@@ -29,7 +29,6 @@ import (
2929 "github.com/googleapis/librarian/internal/sidekick/source"
3030 "github.com/googleapis/librarian/internal/yaml"
3131 "github.com/urfave/cli/v3"
32- "golang.org/x/sync/errgroup"
3332)
3433
3534const (
@@ -76,23 +75,20 @@ func runGenerate(ctx context.Context, cfg *config.Config, all bool, libraryName
7675 if cfg .Sources == nil {
7776 return errEmptySources
7877 }
79- return generateLibraries (ctx , all , cfg , libraryName )
80- }
8178
82- func generateLibraries (ctx context.Context , all bool , cfg * config.Config , libraryName string ) error {
8379 googleapisDir , rustDartSources , err := LoadSources (ctx , cfg )
8480 if err != nil {
8581 return err
8682 }
8783
88- // Prepare and clean libraries sequentially.
89- // This avoids race conditions when output directories are nested .
84+ // Prepare the libraries to generate by skipping as specified and applying
85+ // defaults .
9086 var libraries []* config.Library
9187 for _ , lib := range cfg .Libraries {
9288 if ! shouldGenerate (lib , all , libraryName ) {
9389 continue
9490 }
95- prepared , err := prepareLibrary (cfg .Language , lib , cfg .Default )
91+ prepared , err := applyDefaults (cfg .Language , lib , cfg .Default )
9692 if err != nil {
9793 return err
9894 }
@@ -110,22 +106,17 @@ func generateLibraries(ctx context.Context, all bool, cfg *config.Config, librar
110106 return fmt .Errorf ("%w: %q" , ErrLibraryNotFound , libraryName )
111107 }
112108
113- // Generate all libraries in parallel.
114- g , gctx := errgroup .WithContext (ctx )
115- for _ , lib := range libraries {
116- g .Go (func () error {
117- return generate (gctx , cfg .Language , lib , googleapisDir , rustDartSources )
118- })
109+ // Clean, generate and format libraries. Each of these steps is completed
110+ // before the next one starts, but each language can choose whether to
111+ // implement the step in parallel across all libraries or in sequence.
112+ if err := cleanLibraries (cfg .Language , libraries ); err != nil {
113+ return err
119114 }
120- if err := g . Wait ( ); err != nil {
115+ if err := generateLibraries ( ctx , cfg . Language , libraries , googleapisDir , rustDartSources ); err != nil {
121116 return err
122117 }
123-
124- // Format all libraries sequentially.
125- for _ , lib := range libraries {
126- if err := formatLibrary (ctx , cfg .Language , lib ); err != nil {
127- return err
128- }
118+ if err := formatLibraries (ctx , cfg .Language , libraries ); err != nil {
119+ return err
129120 }
130121 return postGenerate (ctx , cfg .Language )
131122}
@@ -158,6 +149,85 @@ func LoadSources(ctx context.Context, cfg *config.Config) (string, *source.Sourc
158149 return googleapisDir , rustDartSources , nil
159150}
160151
152+ // cleanLibraries iterates over all the given libraries sequentially,
153+ // delegating to language-specific code to clean each library.
154+ func cleanLibraries (language string , libraries []* config.Library ) error {
155+ for _ , library := range libraries {
156+ switch language {
157+ case languageFake :
158+ // No cleaning needed.
159+ case languageDart , languagePython :
160+ if err := checkAndClean (library .Output , library .Keep ); err != nil {
161+ return err
162+ }
163+ case languageGo :
164+ if err := golang .Clean (library ); err != nil {
165+ return err
166+ }
167+ case languageRust :
168+ keep , err := rust .Keep (library )
169+ if err != nil {
170+ return fmt .Errorf ("library %q: %w" , library .Name , err )
171+ }
172+ if err := checkAndClean (library .Output , keep ); err != nil {
173+ return err
174+ }
175+ }
176+ }
177+ return nil
178+ }
179+
180+ // generateLibraries delegates to language-specific code to generate all the
181+ // given libraries.
182+ func generateLibraries (ctx context.Context , language string , libraries []* config.Library , googleapisDir string , src * source.Sources ) error {
183+ switch language {
184+ case languageFake :
185+ return fakeGenerateLibraries (libraries )
186+ case languageDart :
187+ return dart .GenerateLibraries (ctx , libraries , src )
188+ case languagePython :
189+ return python .GenerateLibraries (ctx , libraries , googleapisDir )
190+ case languageGo :
191+ return golang .GenerateLibraries (ctx , libraries , googleapisDir )
192+ case languageRust :
193+ return rust .GenerateLibraries (ctx , libraries , src )
194+ default :
195+ return fmt .Errorf ("language %q does not support generation" , language )
196+ }
197+ }
198+
199+ // formatLibraries iterates over all the given libraries sequentially,
200+ // delegating to language-specific code to format each library.
201+ func formatLibraries (ctx context.Context , language string , libraries []* config.Library ) error {
202+ for _ , library := range libraries {
203+ switch language {
204+ case languageFake :
205+ if err := fakeFormat (library ); err != nil {
206+ return err
207+ }
208+ case languageDart :
209+ if err := dart .Format (ctx , library ); err != nil {
210+ return err
211+ }
212+ case languageGo :
213+ if err := golang .Format (ctx , library ); err != nil {
214+ return err
215+ }
216+ case languageRust :
217+ if err := rust .Format (ctx , library ); err != nil {
218+ return err
219+ }
220+ case languagePython :
221+ // TODO(https://github.com/googleapis/librarian/issues/3730): separate
222+ // generation and formatting for Python.
223+ return nil
224+ default :
225+ return fmt .Errorf ("language %q does not support formatting" , language )
226+ }
227+ }
228+ return nil
229+ }
230+
161231// postGenerate performs repository-level actions after all individual
162232// libraries have been generated.
163233func postGenerate (ctx context.Context , language string ) error {
@@ -201,76 +271,3 @@ func shouldGenerate(lib *config.Library, all bool, libraryName string) bool {
201271 }
202272 return all || lib .Name == libraryName
203273}
204-
205- // prepareLibrary applies defaults and cleans the output directory.
206- func prepareLibrary (language string , lib * config.Library , defaults * config.Default ) (* config.Library , error ) {
207- library , err := applyDefaults (language , lib , defaults )
208- if err != nil {
209- return nil , err
210- }
211- switch language {
212- case languageFake :
213- // No cleaning needed.
214- case languageDart , languagePython :
215- if err := checkAndClean (library .Output , library .Keep ); err != nil {
216- return nil , err
217- }
218- case languageGo :
219- return golang .Clean (library )
220- case languageRust :
221- keep , err := rust .Keep (library )
222- if err != nil {
223- return nil , fmt .Errorf ("library %q: %w" , library .Name , err )
224- }
225- if err := checkAndClean (library .Output , keep ); err != nil {
226- return nil , err
227- }
228- }
229- return library , nil
230- }
231-
232- func generate (ctx context.Context , language string , library * config.Library , googleapisDir string , src * source.Sources ) error {
233- switch language {
234- case languageFake :
235- if err := fakeGenerate (library ); err != nil {
236- return err
237- }
238- case languageDart :
239- if err := dart .Generate (ctx , library , src ); err != nil {
240- return err
241- }
242- case languagePython :
243- if err := python .Generate (ctx , library , googleapisDir ); err != nil {
244- return err
245- }
246- case languageGo :
247- if err := golang .Generate (ctx , library , googleapisDir ); err != nil {
248- return err
249- }
250- case languageRust :
251- if err := rust .Generate (ctx , library , src ); err != nil {
252- return err
253- }
254- default :
255- return fmt .Errorf ("language %q does not support generation" , language )
256- }
257- return nil
258- }
259-
260- func formatLibrary (ctx context.Context , language string , library * config.Library ) error {
261- switch language {
262- case languageFake :
263- return fakeFormat (library )
264- case languageDart :
265- return dart .Format (ctx , library )
266- case languageGo :
267- return golang .Format (ctx , library )
268- case languageRust :
269- return rust .Format (ctx , library )
270- case languagePython :
271- // TODO(https://github.com/googleapis/librarian/issues/3730): separate
272- // generation and formatting for Python.
273- return nil
274- }
275- return fmt .Errorf ("language %q does not support formatting" , language )
276- }
0 commit comments