Skip to content

Commit ef288e5

Browse files
committed
Merge remote-tracking branch 'upstream/main' into languagecontainer_generate
2 parents d159ee2 + 452d703 commit ef288e5

10 files changed

Lines changed: 271 additions & 134 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ jobs:
1818
should_run:
1919
- '!internal/librariangen/**'
2020
build:
21-
needs: changes
22-
if: needs.changes.outputs.should_run == 'true'
2321
runs-on: ubuntu-22.04
2422
strategy:
2523
matrix:
@@ -332,8 +330,6 @@ jobs:
332330
--batch-mode \
333331
--no-transfer-progress
334332
showcase:
335-
needs: changes
336-
if: needs.changes.outputs.should_run == 'true'
337333
runs-on: ubuntu-22.04
338334
strategy:
339335
matrix:

internal/librariangen/bazel/parser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func (c *Config) Validate() error {
6565
}
6666

6767
var javaGapicLibraryRE = regexp.MustCompile(`java_gapic_library\((?s:.)*?\)`)
68+
6869
// Parse reads a BUILD.bazel file from the given directory and extracts the
6970
// relevant configuration from the java_gapic_library rule.
7071
func Parse(dir string) (*Config, error) {

internal/librariangen/bazel/parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,4 @@ func TestParse_noBuildFile(t *testing.T) {
256256
if err == nil {
257257
t.Error("Parse() succeeded; want error")
258258
}
259-
}
259+
}

internal/librariangen/execv/execv.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ func Run(ctx context.Context, args []string, workingDir string) error {
4848
return fmt.Errorf("librariangen: command failed: %w", err)
4949
}
5050
return nil
51-
}
51+
}

internal/librariangen/execv/execv_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ func TestRun(t *testing.T) {
7676
}
7777
})
7878
}
79-
}
79+
}

internal/librariangen/generate/generator.go

Lines changed: 84 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,25 @@ var (
4242
// the entire generation process.
4343
func Generate(ctx context.Context, cfg *generate.Config) error {
4444
slog.Debug("librariangen: generate command started")
45-
defer cleanupIntermediateFiles(cfg.Context.OutputDir)
45+
outputConfig := &protoc.OutputConfig{
46+
GAPICDir: filepath.Join(cfg.Context.OutputDir, "gapic"),
47+
GRPCDir: filepath.Join(cfg.Context.OutputDir, "grpc"),
48+
ProtoDir: filepath.Join(cfg.Context.OutputDir, "proto"),
49+
}
50+
defer func() {
51+
if err := cleanupIntermediateFiles(outputConfig); err != nil {
52+
slog.Error("librariangen: failed to clean up intermediate files", "error", err)
53+
}
54+
}()
4655

4756
generateReq := cfg.Request
4857

49-
if err := invokeProtoc(ctx, cfg.Context, generateReq); err != nil {
58+
if err := invokeProtoc(ctx, cfg.Context, generateReq, outputConfig); err != nil {
5059
return fmt.Errorf("librariangen: gapic generation failed: %w", err)
5160
}
52-
53-
// Unzip the generated zip file.
54-
zipPath := filepath.Join(cfg.Context.OutputDir, "java_gapic.zip")
55-
if err := unzip(zipPath, cfg.Context.OutputDir); err != nil {
56-
return fmt.Errorf("librariangen: failed to unzip %s: %w", zipPath, err)
57-
}
58-
59-
// Unzip the inner temp-codegen.srcjar.
60-
srcjarPath := filepath.Join(cfg.Context.OutputDir, "temp-codegen.srcjar")
61-
srcjarDest := filepath.Join(cfg.Context.OutputDir, "java_gapic_srcjar")
61+
// Unzip the temp-codegen.srcjar.
62+
srcjarPath := filepath.Join(outputConfig.GAPICDir, "temp-codegen.srcjar")
63+
srcjarDest := outputConfig.GAPICDir
6264
if err := unzip(srcjarPath, srcjarDest); err != nil {
6365
return fmt.Errorf("librariangen: failed to unzip %s: %w", srcjarPath, err)
6466
}
@@ -74,20 +76,28 @@ func Generate(ctx context.Context, cfg *generate.Config) error {
7476
// invokeProtoc handles the protoc GAPIC generation logic for the 'generate' CLI command.
7577
// It reads a request file, and for each API specified, it invokes protoc
7678
// to generate the client library. It returns the module path and the path to the service YAML.
77-
func invokeProtoc(ctx context.Context, genCtx *generate.Context, generateReq *message.Library) error {
79+
func invokeProtoc(ctx context.Context, genCtx *generate.Context, generateReq *message.Library, outputConfig *protoc.OutputConfig) error {
7880
for _, api := range generateReq.APIs {
7981
apiServiceDir := filepath.Join(genCtx.SourceDir, api.Path)
8082
slog.Info("processing api", "service_dir", apiServiceDir)
8183
bazelConfig, err := bazelParse(apiServiceDir)
8284
if err != nil {
8385
return fmt.Errorf("librariangen: failed to parse BUILD.bazel for %s: %w", apiServiceDir, err)
8486
}
85-
args, err := protocBuild(apiServiceDir, bazelConfig, genCtx.SourceDir, genCtx.OutputDir)
87+
args, err := protocBuild(apiServiceDir, bazelConfig, genCtx.SourceDir, outputConfig)
8688
if err != nil {
8789
return fmt.Errorf("librariangen: failed to build protoc command for api %q in library %q: %w", api.Path, generateReq.ID, err)
8890
}
91+
92+
// Create protoc output directories.
93+
for _, dir := range []string{outputConfig.ProtoDir, outputConfig.GRPCDir, outputConfig.GAPICDir} {
94+
if err := os.MkdirAll(dir, 0755); err != nil {
95+
return err
96+
}
97+
}
98+
8999
if err := execvRun(ctx, args, genCtx.OutputDir); err != nil {
90-
return fmt.Errorf("librariangen: protoc failed for api %q in library %q: %w", api.Path, generateReq.ID, err)
100+
return fmt.Errorf("librariangen: protoc failed for api %q in library %q: %w, execvRun error: %v", api.Path, generateReq.ID, err, err)
91101
}
92102
}
93103
return nil
@@ -104,7 +114,7 @@ func moveFiles(sourceDir, targetDir string) error {
104114
newPath := filepath.Join(targetDir, f.Name())
105115
slog.Debug("librariangen: moving file", "from", oldPath, "to", newPath)
106116
if err := os.Rename(oldPath, newPath); err != nil {
107-
return fmt.Errorf("librariangen: failed to move %s to %s: %w", oldPath, newPath, err)
117+
return fmt.Errorf("librariangen: failed to move %s to %s: %w, os.Rename error: %v", oldPath, newPath, err, err)
108118
}
109119
}
110120
return nil
@@ -114,29 +124,43 @@ func restructureOutput(outputDir, libraryID string) error {
114124
slog.Debug("librariangen: restructuring output directory", "dir", outputDir)
115125

116126
// Define source and destination directories.
117-
gapicSrcDir := filepath.Join(outputDir, "java_gapic_srcjar", "src", "main", "java")
118-
gapicTestDir := filepath.Join(outputDir, "java_gapic_srcjar", "src", "test", "java")
119-
protoSrcDir := filepath.Join(outputDir, "com")
120-
samplesDir := filepath.Join(outputDir, "java_gapic_srcjar", "samples", "snippets")
127+
gapicSrcDir := filepath.Join(outputDir, "gapic", "src", "main", "java")
128+
gapicTestDir := filepath.Join(outputDir, "gapic", "src", "test", "java")
129+
protoSrcDir := filepath.Join(outputDir, "proto")
130+
resourceNameSrcDir := filepath.Join(outputDir, "gapic", "proto", "src", "main", "java")
131+
grpcSrcDir := filepath.Join(outputDir, "grpc")
132+
samplesDir := filepath.Join(outputDir, "gapic", "samples", "snippets")
121133

134+
// TODO(meltsufin): currently we assume we have a single API variant v1
122135
gapicDestDir := filepath.Join(outputDir, fmt.Sprintf("google-cloud-%s", libraryID), "src", "main", "java")
123136
gapicTestDestDir := filepath.Join(outputDir, fmt.Sprintf("google-cloud-%s", libraryID), "src", "test", "java")
124137
protoDestDir := filepath.Join(outputDir, fmt.Sprintf("proto-google-cloud-%s-v1", libraryID), "src", "main", "java")
138+
resourceNameDestDir := filepath.Join(outputDir, fmt.Sprintf("proto-google-cloud-%s-v1", libraryID), "src", "main", "java")
139+
grpcDestDir := filepath.Join(outputDir, fmt.Sprintf("grpc-google-cloud-%s-v1", libraryID), "src", "main", "java")
125140
samplesDestDir := filepath.Join(outputDir, "samples", "snippets")
126141

127142
// Create destination directories.
128-
destDirs := []string{gapicDestDir, gapicTestDestDir, protoDestDir, samplesDestDir}
143+
destDirs := []string{gapicDestDir, gapicTestDestDir, protoDestDir, samplesDestDir, grpcDestDir}
129144
for _, dir := range destDirs {
130145
if err := os.MkdirAll(dir, 0755); err != nil {
131146
return err
132147
}
133148
}
134149

135-
// Move files.
150+
// The resource name directory is not created if there are no resource names
151+
// to generate. We create it here to avoid errors later.
152+
if _, err := os.Stat(resourceNameSrcDir); os.IsNotExist(err) {
153+
if err := os.MkdirAll(resourceNameSrcDir, 0755); err != nil {
154+
return err
155+
}
156+
}
157+
158+
// Move files that won't have conflicts.
136159
moves := map[string]string{
137160
gapicSrcDir: gapicDestDir,
138161
gapicTestDir: gapicTestDestDir,
139162
protoSrcDir: protoDestDir,
163+
grpcSrcDir: grpcDestDir,
140164
samplesDir: samplesDestDir,
141165
}
142166
for src, dest := range moves {
@@ -145,23 +169,51 @@ func restructureOutput(outputDir, libraryID string) error {
145169
}
146170
}
147171

172+
// Merge the resource name files into the proto destination.
173+
if err := copyAndMerge(resourceNameSrcDir, resourceNameDestDir); err != nil {
174+
return err
175+
}
176+
148177
return nil
149178
}
150179

151-
func cleanupIntermediateFiles(outputDir string) {
152-
slog.Debug("librariangen: cleaning up intermediate files", "dir", outputDir)
153-
filesToRemove := []string{
154-
"java_gapic_srcjar",
155-
"com",
156-
"java_gapic.zip",
157-
"temp-codegen.srcjar",
180+
// copyAndMerge recursively copies the contents of src to dest, merging directories.
181+
func copyAndMerge(src, dest string) error {
182+
entries, err := os.ReadDir(src)
183+
if os.IsNotExist(err) {
184+
return nil
185+
}
186+
if err != nil {
187+
return err
188+
}
189+
190+
for _, entry := range entries {
191+
srcPath := filepath.Join(src, entry.Name())
192+
destPath := filepath.Join(dest, entry.Name())
193+
if entry.IsDir() {
194+
if err := os.MkdirAll(destPath, 0755); err != nil {
195+
return err
196+
}
197+
if err := copyAndMerge(srcPath, destPath); err != nil {
198+
return err
199+
}
200+
} else {
201+
if err := os.Rename(srcPath, destPath); err != nil {
202+
return fmt.Errorf("librariangen: failed to move %s to %s: %w, os.Rename error: %v", srcPath, destPath, err, err)
203+
}
204+
}
158205
}
159-
for _, file := range filesToRemove {
160-
path := filepath.Join(outputDir, file)
206+
return nil
207+
}
208+
209+
func cleanupIntermediateFiles(outputConfig *protoc.OutputConfig) error {
210+
slog.Debug("librariangen: cleaning up intermediate files")
211+
for _, path := range []string{outputConfig.GAPICDir, outputConfig.GRPCDir, outputConfig.ProtoDir} {
161212
if err := os.RemoveAll(path); err != nil {
162-
slog.Error("librariangen: failed to clean up intermediate file", "path", path, "error", err)
213+
return fmt.Errorf("failed to clean up intermediate file at %s: %w", path, err)
163214
}
164215
}
216+
return nil
165217
}
166218

167219
func unzip(src, dest string) error {

0 commit comments

Comments
 (0)