this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

add codegen support to glot

+142
+141
cmd/glot/codegen.go
··· 1 + package main 2 + 3 + import ( 4 + "bytes" 5 + "context" 6 + "encoding/json" 7 + "fmt" 8 + "go/format" 9 + "os" 10 + "path" 11 + 12 + "github.com/bluesky-social/indigo/atproto/lexicon" 13 + "github.com/bluesky-social/indigo/lex/lexgen" 14 + 15 + "github.com/urfave/cli/v3" 16 + "golang.org/x/tools/imports" 17 + ) 18 + 19 + var cmdCodegen = &cli.Command{ 20 + Name: "codegen", 21 + Usage: "output Go code (types) for indicated lexicon schemas", 22 + Description: "Enumerates all local lexicons (JSON files), and outputs Go source file for each.\nOperates on entire ./lexicons/ directory unless specific files or directories are provided.", 23 + ArgsUsage: `<file-or-dir>*`, 24 + Flags: []cli.Flag{ 25 + &cli.StringFlag{ 26 + Name: "lexicons-dir", 27 + Value: "lexicons/", 28 + Usage: "base directory for project Lexicon files", 29 + Sources: cli.EnvVars("LEXICONS_DIR"), 30 + }, 31 + &cli.StringFlag{ 32 + Name: "output-dir", 33 + Value: "./codegen-output/", 34 + Usage: "base directory for output packages", 35 + Sources: cli.EnvVars("OUTPUT_DIR"), 36 + }, 37 + &cli.BoolFlag{ 38 + Name: "no-imports-tidy", 39 + Usage: "skip cleanup of go imports in writen output", 40 + }, 41 + }, 42 + Action: runCodegen, 43 + } 44 + 45 + func runCodegen(ctx context.Context, cmd *cli.Command) error { 46 + 47 + // enumerate lexicon JSON file paths 48 + filePaths, err := collectPaths(cmd) 49 + if err != nil { 50 + return err 51 + } 52 + 53 + // construct full catalog of local schemas 54 + cat, err := collectCatalog(cmd) 55 + if err != nil { 56 + return err 57 + } 58 + 59 + anyFailures := false 60 + for _, p := range filePaths { 61 + if err := genFile(ctx, cmd, cat, p); err != nil { 62 + fmt.Printf(" 🟠 %s\n", p) 63 + fmt.Printf(" [failed]: %s\n", err) 64 + anyFailures = true 65 + continue 66 + } 67 + fmt.Printf(" 🟢 %s\n", p) 68 + } 69 + if anyFailures { 70 + return fmt.Errorf("some codegen failed") 71 + } 72 + return nil 73 + } 74 + 75 + func genFile(ctx context.Context, cmd *cli.Command, cat lexicon.Catalog, p string) error { 76 + b, err := os.ReadFile(p) 77 + if err != nil { 78 + return fmt.Errorf("failed to read lexicon schema from disk (%s): %w", p, err) 79 + } 80 + 81 + // parse file regularly 82 + // NOTE: use json/v2 when it stabilizes for case-sensitivity 83 + var sf lexicon.SchemaFile 84 + 85 + err = json.Unmarshal(b, &sf) 86 + if err == nil { 87 + err = sf.FinishParse() 88 + } 89 + if err == nil { 90 + err = sf.CheckSchema() 91 + } 92 + if err != nil { 93 + return fmt.Errorf("failed to parse lexicon schema from disk (%s): %w", p, err) 94 + } 95 + 96 + flat, err := lexgen.FlattenSchemaFile(&sf) 97 + if err != nil { 98 + return fmt.Errorf("internal codegen flattening error (%s): %w", p, err) 99 + } 100 + 101 + cfg := lexgen.NewGenConfig() 102 + if cmd.Bool("legacy-mode") { 103 + cfg = lexgen.LegacyConfig() 104 + } 105 + 106 + buf := new(bytes.Buffer) 107 + gen := lexgen.CodeGenerator{ 108 + Config: cfg, 109 + Lex: flat, 110 + Cat: cat, 111 + Out: buf, 112 + } 113 + if err := gen.WriteLexicon(); err != nil { 114 + return fmt.Errorf("failed to format codegen output (%s): %w", p, err) 115 + } 116 + 117 + outPath := path.Join(cmd.String("output-dir"), gen.PkgName(), gen.FileName()) 118 + if err := os.MkdirAll(path.Dir(outPath), 0755); err != nil { 119 + return err 120 + } 121 + 122 + if !cmd.Bool("no-imports-tidy") { 123 + // NOTE: processing imports per file gets slow if imports are missing 124 + fmtOpts := imports.Options{ 125 + Comments: true, 126 + TabIndent: false, 127 + TabWidth: 4, 128 + } 129 + formatted, err := imports.Process(outPath, buf.Bytes(), &fmtOpts) 130 + if err != nil { 131 + return fmt.Errorf("failed to format codegen output (%s): %w", p, err) 132 + } 133 + return os.WriteFile(outPath, formatted, 0644) 134 + } else { 135 + formatted, err := format.Source(buf.Bytes()) 136 + if err != nil { 137 + return fmt.Errorf("failed to format codegen output (%s): %w", p, err) 138 + } 139 + return os.WriteFile(outPath, formatted, 0644) 140 + } 141 + }
+1
cmd/glot/main.go
··· 39 39 cmdPublish, 40 40 cmdUnpublish, 41 41 cmdCheckDNS, 42 + cmdCodegen, 42 43 } 43 44 return app.Run(context.Background(), args) 44 45 }