Source file src/crypto/internal/cryptotest/x509limbo/_schema/schema_gen.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // A stand-alone Go module that generates ../schema.go using the upstream
     6  // x509-limbo JSON schema document.
     7  //
     8  // We maintain this in a separate Go module and vendor the resulting generated
     9  // .go code to avoid the standard library taking a direct dependency on the
    10  // C2SP/x509-limbo or atombender/go-jsonschema modules.
    11  
    12  package main
    13  
    14  import (
    15  	"bytes"
    16  	"encoding/json"
    17  	"fmt"
    18  	"log"
    19  	"os"
    20  	"os/exec"
    21  	"path/filepath"
    22  
    23  	"github.com/atombender/go-jsonschema/pkg/generator"
    24  )
    25  
    26  // x509LimboVersion is the github.com/C2SP/x509-limbo module version used to
    27  // generate ../schema.go. Update this to retarget a different upstream revision.
    28  //
    29  // x509-limbo publishes no Go packages, so we can't pin the version via a
    30  // `require` directive (any `go mod tidy` would drop it) or a `tool` directive
    31  // (no main package). Instead we fetch the module on demand via `go mod
    32  // download` below, and propagate this constant to ../schemaversion.go so the
    33  // runtime test fetches a matching revision.
    34  const x509LimboVersion = "v0.0.0-20260522003327-feb7caccc1af"
    35  
    36  const x509LimboModule = "github.com/C2SP/x509-limbo"
    37  
    38  func main() {
    39  	limboDir, err := downloadModuleDir(x509LimboModule, x509LimboVersion)
    40  	if err != nil {
    41  		log.Fatalf("failed to fetch %s@%s: %v", x509LimboModule, x509LimboVersion, err)
    42  	}
    43  
    44  	outputName := "schema.go"
    45  	gen, err := generator.New(generator.Config{
    46  		DefaultPackageName: "x509limbo",
    47  		DefaultOutputName:  outputName,
    48  		Tags:               []string{"json"},
    49  		Warner: func(message string) {
    50  			log.Printf("go-jsonschema: %s", message)
    51  		},
    52  	})
    53  	if err != nil {
    54  		log.Fatal(err)
    55  	}
    56  
    57  	schemaFile := filepath.Join(limboDir, "limbo-schema.json")
    58  	if err := gen.DoFile(schemaFile); err != nil {
    59  		log.Fatalf("error processing limbo-schema.json: %v\n", err)
    60  	}
    61  
    62  	sources, err := gen.Sources()
    63  	if err != nil {
    64  		log.Fatalf("error generating sources: %v\n", err)
    65  	}
    66  	if sourceCount := len(sources); sourceCount != 1 {
    67  		log.Fatalf("expected to generate 1 source file, got %d\n", sourceCount)
    68  	}
    69  	content, ok := sources[outputName]
    70  	if !ok {
    71  		log.Fatalf("missing generated %q output file source", outputName)
    72  	}
    73  	outFile := filepath.Join("../", outputName)
    74  	if err := os.WriteFile(outFile, content, 0644); err != nil {
    75  		log.Fatalf("error writing file %s: %v\n", outFile, err)
    76  	}
    77  
    78  	// Write a sibling file recording the x509-limbo module version that the
    79  	// generated schema.go was produced against. The x509limbo package uses
    80  	// this constant to fetch matching test vectors at runtime. We avoid reading
    81  	// go.sum at test time because it might not be available (e.g. if the test
    82  	// binary was copied to a remote machine).
    83  	const versionFile = "../schemaversion.go"
    84  	versionSrc := fmt.Sprintf(`// Copyright 2026 The Go Authors. All rights reserved.
    85  // Use of this source code is governed by a BSD-style
    86  // license that can be found in the LICENSE file.
    87  
    88  // Code generated by _schema/schema_gen.go, DO NOT EDIT.
    89  
    90  package x509limbo
    91  
    92  // X509LimboModule is the module path of the upstream x509-limbo project.
    93  const X509LimboModule = %q
    94  
    95  // X509LimboVersion is the X509LimboModule version that schema.go was
    96  // generated against.
    97  const X509LimboVersion = %q
    98  `, x509LimboModule, x509LimboVersion)
    99  	if err := os.WriteFile(versionFile, []byte(versionSrc), 0644); err != nil {
   100  		log.Fatalf("writing %s: %v", versionFile, err)
   101  	}
   102  }
   103  
   104  // downloadModuleDir runs `go mod download` to ensure module@version is present
   105  // in the module cache and returns the directory containing its source tree.
   106  func downloadModuleDir(module, version string) (string, error) {
   107  	cmd := exec.Command("go", "mod", "download", "-json", module+"@"+version)
   108  	var stderr bytes.Buffer
   109  	cmd.Stderr = &stderr
   110  	out, err := cmd.Output()
   111  	if err != nil {
   112  		return "", fmt.Errorf("%w\n%s", err, stderr.String())
   113  	}
   114  	var info struct {
   115  		Dir   string
   116  		Error string
   117  	}
   118  	if err := json.Unmarshal(out, &info); err != nil {
   119  		return "", fmt.Errorf("parsing go mod download output: %w", err)
   120  	}
   121  	if info.Error != "" {
   122  		return "", fmt.Errorf("%s", info.Error)
   123  	}
   124  	return info.Dir, nil
   125  }
   126  

View as plain text