@@ -17,7 +17,6 @@ package generate
1717import (
1818 "archive/zip"
1919 "context"
20- "errors"
2120 "fmt"
2221 "io"
2322 "log/slog"
@@ -27,85 +26,46 @@ import (
2726
2827 "cloud.google.com/java/internal/librariangen/bazel"
2928 "cloud.google.com/java/internal/librariangen/execv"
29+ "cloud.google.com/java/internal/librariangen/languagecontainer/generate"
3030 "cloud.google.com/java/internal/librariangen/message"
3131 "cloud.google.com/java/internal/librariangen/protoc"
3232)
3333
3434// Test substitution vars.
3535var (
36- bazelParse = bazel .Parse
37- execvRun = execv .Run
38- requestParse = message .ParseLibrary
39- protocBuild = protoc .Build
36+ bazelParse = bazel .Parse
37+ execvRun = execv .Run
38+ protocBuild = protoc .Build
4039)
4140
42- // Config holds the internal librariangen configuration for the generate command.
43- type Config struct {
44- // LibrarianDir is the path to the librarian-tool input directory.
45- // It is expected to contain the generate-request.json file.
46- LibrarianDir string
47- // InputDir is the path to the .librarian/generator-input directory from the
48- // language repository.
49- InputDir string
50- // OutputDir is the path to the empty directory where librariangen writes
51- // its output.
52- OutputDir string
53- // SourceDir is the path to a complete checkout of the googleapis repository.
54- SourceDir string
55- }
56-
57- // Validate ensures that the configuration is valid.
58- func (c * Config ) Validate () error {
59- if c .LibrarianDir == "" {
60- return errors .New ("librariangen: librarian directory must be set" )
61- }
62- if c .InputDir == "" {
63- return errors .New ("librariangen: input directory must be set" )
64- }
65- if c .OutputDir == "" {
66- return errors .New ("librariangen: output directory must be set" )
67- }
68- if c .SourceDir == "" {
69- return errors .New ("librariangen: source directory must be set" )
70- }
71- return nil
72- }
73-
7441// Generate is the main entrypoint for the `generate` command. It orchestrates
7542// the entire generation process.
76- func Generate (ctx context.Context , cfg * Config ) error {
77- if err := cfg .Validate (); err != nil {
78- return fmt .Errorf ("librariangen: invalid configuration: %w" , err )
79- }
43+ func Generate (ctx context.Context , cfg * generate.Config ) error {
8044 slog .Debug ("librariangen: generate command started" )
8145 outputConfig := & protoc.OutputConfig {
82- GAPICDir : filepath .Join (cfg .OutputDir , "gapic" ),
83- GRPCDir : filepath .Join (cfg .OutputDir , "grpc" ),
84- ProtoDir : filepath .Join (cfg .OutputDir , "proto" ),
46+ GAPICDir : filepath .Join (cfg .Context . OutputDir , "gapic" ),
47+ GRPCDir : filepath .Join (cfg .Context . OutputDir , "grpc" ),
48+ ProtoDir : filepath .Join (cfg .Context . OutputDir , "proto" ),
8549 }
8650 defer func () {
8751 if err := cleanupIntermediateFiles (outputConfig ); err != nil {
8852 slog .Error ("librariangen: failed to clean up intermediate files" , "error" , err )
8953 }
9054 }()
9155
92- generateReq , err := readGenerateReq (cfg .LibrarianDir )
93- if err != nil {
94- return fmt .Errorf ("librariangen: failed to read request: %w" , err )
95- }
56+ generateReq := cfg .Request
9657
97- if err := invokeProtoc (ctx , cfg , generateReq , outputConfig ); err != nil {
58+ if err := invokeProtoc (ctx , cfg . Context , generateReq , outputConfig ); err != nil {
9859 return fmt .Errorf ("librariangen: gapic generation failed: %w" , err )
9960 }
100-
10161 // Unzip the temp-codegen.srcjar.
10262 srcjarPath := filepath .Join (outputConfig .GAPICDir , "temp-codegen.srcjar" )
10363 srcjarDest := outputConfig .GAPICDir
10464 if err := unzip (srcjarPath , srcjarDest ); err != nil {
10565 return fmt .Errorf ("librariangen: failed to unzip %s: %w" , srcjarPath , err )
10666 }
10767
108- if err := restructureOutput (cfg .OutputDir , generateReq .ID ); err != nil {
68+ if err := restructureOutput (cfg .Context . OutputDir , generateReq .ID ); err != nil {
10969 return fmt .Errorf ("librariangen: failed to restructure output: %w" , err )
11070 }
11171
@@ -116,15 +76,15 @@ func Generate(ctx context.Context, cfg *Config) error {
11676// invokeProtoc handles the protoc GAPIC generation logic for the 'generate' CLI command.
11777// It reads a request file, and for each API specified, it invokes protoc
11878// to generate the client library. It returns the module path and the path to the service YAML.
119- func invokeProtoc (ctx context.Context , cfg * Config , generateReq * message.Library , outputConfig * protoc.OutputConfig ) error {
79+ func invokeProtoc (ctx context.Context , genCtx * generate. Context , generateReq * message.Library , outputConfig * protoc.OutputConfig ) error {
12080 for _ , api := range generateReq .APIs {
121- apiServiceDir := filepath .Join (cfg .SourceDir , api .Path )
81+ apiServiceDir := filepath .Join (genCtx .SourceDir , api .Path )
12282 slog .Info ("processing api" , "service_dir" , apiServiceDir )
12383 bazelConfig , err := bazelParse (apiServiceDir )
12484 if err != nil {
12585 return fmt .Errorf ("librariangen: failed to parse BUILD.bazel for %s: %w" , apiServiceDir , err )
12686 }
127- args , err := protocBuild (apiServiceDir , bazelConfig , cfg .SourceDir , outputConfig )
87+ args , err := protocBuild (apiServiceDir , bazelConfig , genCtx .SourceDir , outputConfig )
12888 if err != nil {
12989 return fmt .Errorf ("librariangen: failed to build protoc command for api %q in library %q: %w" , api .Path , generateReq .ID , err )
13090 }
@@ -136,28 +96,13 @@ func invokeProtoc(ctx context.Context, cfg *Config, generateReq *message.Library
13696 }
13797 }
13898
139- if err := execvRun (ctx , args , cfg .OutputDir ); err != nil {
99+ if err := execvRun (ctx , args , genCtx .OutputDir ); err != nil {
140100 return fmt .Errorf ("librariangen: protoc failed for api %q in library %q: %w, execvRun error: %v" , api .Path , generateReq .ID , err , err )
141101 }
142102 }
143103 return nil
144104}
145105
146- // readGenerateReq reads generate-request.json from the librarian-tool input directory.
147- // The request file tells librariangen which library and APIs to generate.
148- // It is prepared by the Librarian tool and mounted at /librarian.
149- func readGenerateReq (librarianDir string ) (* message.Library , error ) {
150- reqPath := filepath .Join (librarianDir , "generate-request.json" )
151- slog .Debug ("librariangen: reading generate request" , "path" , reqPath )
152-
153- generateReq , err := requestParse (reqPath )
154- if err != nil {
155- return nil , err
156- }
157- slog .Debug ("librariangen: successfully unmarshalled request" , "library_id" , generateReq .ID )
158- return generateReq , nil
159- }
160-
161106// moveFiles moves all files (and directories) from sourceDir to targetDir.
162107func moveFiles (sourceDir , targetDir string ) error {
163108 files , err := os .ReadDir (sourceDir )
0 commit comments