diff --git a/README.md b/README.md index 7b61982..ba60d75 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,28 @@ ## Install +Homebrew: + +```sh +brew install thames-technology/tap/apigen +``` + +Go: + ```sh -# TODO +go install github.com/thames-technology/apigen ``` ## Getting started +Create standard `BookService` definition with `author` parent resource in `proto/bookservice/v1alpha1/service.proto`: + +```sh +apigen proto -r book -p author -pkg bookservice.v1alpha1 -w +``` + +Create standard `AuthorService` definition without a parent resource in `proto/authorservice/v1alpha1/service.proto`: + ```sh -apigen proto -r book -pkg bookservice.v1alpha1 +apigen proto -r author -pkg authorservice.v1alpha1 -w ``` diff --git a/internal/template/template.go b/internal/template/template.go index 5d39cc3..b8c7c8b 100644 --- a/internal/template/template.go +++ b/internal/template/template.go @@ -2,6 +2,7 @@ package template import ( "embed" + "io" "os" "path/filepath" "strings" @@ -28,14 +29,18 @@ type ProtoData struct { Package string } -func Write(data *ProtoData, outDir string) error { - tmpl, err := template.New("proto").Funcs(funcs).ParseFS(tmplFS, "service.tmpl") - if err != nil { - return err +type WriteOpts struct { + OutDir string + Write bool +} + +func Write(data *ProtoData, opts *WriteOpts) error { + if !opts.Write { + return writeTo(os.Stdout, data) } // Construct the output file path - outFilePath := filepath.Join(outDir, strings.ReplaceAll(data.Package, ".", "/"), "service.proto") + outFilePath := filepath.Join(opts.OutDir, strings.ReplaceAll(data.Package, ".", "/"), "service.proto") // Create the directory structure if it doesn't exist if err := os.MkdirAll(filepath.Dir(outFilePath), 0755); err != nil { @@ -49,5 +54,14 @@ func Write(data *ProtoData, outDir string) error { } defer outFile.Close() - return tmpl.ExecuteTemplate(outFile, "service.tmpl", data) + return writeTo(outFile, data) +} + +func writeTo(w io.Writer, data *ProtoData) error { + tmpl, err := template.New("proto").Funcs(funcs).ParseFS(tmplFS, "service.tmpl") + if err != nil { + return err + } + + return tmpl.ExecuteTemplate(w, "service.tmpl", data) } diff --git a/internal/template/template_test.go b/internal/template/template_test.go index 46dd22e..9dd0f26 100644 --- a/internal/template/template_test.go +++ b/internal/template/template_test.go @@ -10,11 +10,12 @@ import ( ) func TestWrite(t *testing.T) { + expectedDir := "../../proto" + tests := []struct { - name string - data *ProtoData - outDir string - expectedDir string + name string + data *ProtoData + opts *WriteOpts }{ { name: "Test Book Service", @@ -25,8 +26,7 @@ func TestWrite(t *testing.T) { Parents: "authors", Package: "bookservice.v1alpha1", }, - outDir: "testdata", - expectedDir: "../../proto", + opts: &WriteOpts{Write: true, OutDir: "testdata"}, }, { name: "Test Author Service", @@ -35,26 +35,25 @@ func TestWrite(t *testing.T) { Resources: "authors", Package: "authorservice.v1alpha1", }, - outDir: "testdata", - expectedDir: "../../proto", + opts: &WriteOpts{Write: true, OutDir: "testdata"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Ensure the output directory exists - if err := os.MkdirAll(tt.outDir, 0755); err != nil { + if err := os.MkdirAll(tt.opts.OutDir, 0755); err != nil { t.Fatalf("Failed to create output directory: %v", err) } // Run the Write function - if err := Write(tt.data, tt.outDir); err != nil { + if err := Write(tt.data, tt.opts); err != nil { t.Fatalf("Write() error: %v", err) } // Compare the output file with the expected file - outputFile := filepath.Join(tt.outDir, strings.ReplaceAll(tt.data.Package, ".", "/"), "service.proto") - expectedFile := filepath.Join(tt.expectedDir, strings.ReplaceAll(tt.data.Package, ".", "/"), "service.proto") + outputFile := filepath.Join(tt.opts.OutDir, strings.ReplaceAll(tt.data.Package, ".", "/"), "service.proto") + expectedFile := filepath.Join(expectedDir, strings.ReplaceAll(tt.data.Package, ".", "/"), "service.proto") output, err := os.ReadFile(outputFile) if err != nil { @@ -71,7 +70,7 @@ func TestWrite(t *testing.T) { } // Clean up the output directory - os.RemoveAll(tt.outDir) + os.RemoveAll(tt.opts.OutDir) }) } } diff --git a/main.go b/main.go index 2c1a0a7..5776f2e 100644 --- a/main.go +++ b/main.go @@ -53,6 +53,11 @@ func main() { Usage: "The directory to write the proto files to", Value: "proto", }, + &cli.BoolFlag{ + Name: "write", + Aliases: []string{"w"}, + Usage: "Write the output to a file", + }, }, Action: func(c *cli.Context) error { resource := c.String("resource") @@ -75,7 +80,12 @@ func main() { Package: c.String("package"), } - return template.Write(data, c.String("out-dir")) + opts := &template.WriteOpts{ + OutDir: c.String("out-dir"), + Write: c.Bool("write"), + } + + return template.Write(data, opts) }, }, },