@@ -50,6 +50,15 @@ type generateRunner struct {
5050 workRoot string
5151}
5252
53+ // generationStatus represents the result of a single library generation.
54+ type generationStatus struct {
55+ // oldCommit is the SHA of the previously generated version of the library.
56+ oldCommit string
57+ // apiOnboarding is true if an API is being configured and generated for the
58+ // first time.
59+ apiOnboarding bool
60+ }
61+
5362func newGenerateRunner (cfg * config.Config ) (* generateRunner , error ) {
5463 runner , err := newCommandRunner (cfg )
5564 if err != nil {
@@ -88,18 +97,20 @@ func (r *generateRunner) run(ctx context.Context) error {
8897 // use this map to keep the mapping from library id to commit sha before the
8998 // generation since we need these commits to create pull request body.
9099 idToCommits := make (map [string ]string )
100+ apiOnboarding := false
91101 var failedLibraries []string
92102 failedGenerations := 0
93103 if r .api != "" || r .library != "" {
94104 libraryID := r .library
95105 if libraryID == "" {
96106 libraryID = findLibraryIDByAPIPath (r .state , r .api )
97107 }
98- oldCommit , err := r .generateSingleLibrary (ctx , libraryID , outputDir )
108+ status , err := r .generateSingleLibrary (ctx , libraryID , outputDir )
99109 if err != nil {
100110 return err
101111 }
102- idToCommits [libraryID ] = oldCommit
112+ idToCommits [libraryID ] = status .oldCommit
113+ apiOnboarding = status .apiOnboarding
103114 } else {
104115 succeededGenerations := 0
105116 blockedGenerations := 0
@@ -112,15 +123,15 @@ func (r *generateRunner) run(ctx context.Context) error {
112123 continue
113124 }
114125 }
115- oldCommit , err := r .generateSingleLibrary (ctx , library .ID , outputDir )
126+ status , err := r .generateSingleLibrary (ctx , library .ID , outputDir )
116127 if err != nil {
117128 slog .Error ("failed to generate library" , "id" , library .ID , "err" , err )
118129 failedLibraries = append (failedLibraries , library .ID )
119130 failedGenerations ++
120131 } else {
121132 // Only add the mapping if library generation is successful so that
122133 // failed library will not appear in generation PR body.
123- idToCommits [library .ID ] = oldCommit
134+ idToCommits [library .ID ] = status . oldCommit
124135 succeededGenerations ++
125136 }
126137 }
@@ -154,6 +165,7 @@ func (r *generateRunner) run(ctx context.Context) error {
154165 sourceRepo : r .sourceRepo ,
155166 state : r .state ,
156167 workRoot : r .workRoot ,
168+ apiOnboarding : apiOnboarding ,
157169 failedGenerations : failedGenerations ,
158170 }
159171
@@ -170,58 +182,65 @@ func (r *generateRunner) run(ctx context.Context) error {
170182//
171183// 3. Build the library.
172184//
173- // 4. Update the last generated commit.
174- //
175- // Returns the last generated commit before the generation and error, if any.
176- func (r * generateRunner ) generateSingleLibrary (ctx context.Context , libraryID , outputDir string ) (string , error ) {
185+ // 4. Update the last generated commit or initial piper id if the library needs configure.
186+ func (r * generateRunner ) generateSingleLibrary (ctx context.Context , libraryID , outputDir string ) (* generationStatus , error ) {
177187 safeLibraryDirectory := getSafeDirectoryName (libraryID )
188+ apiOnboarding := false
178189 if r .needsConfigure () {
179190 slog .Info ("library not configured, start initial configuration" , "library" , r .library )
180191 configureOutputDir := filepath .Join (outputDir , safeLibraryDirectory , "configure" )
181192 if err := os .MkdirAll (configureOutputDir , 0755 ); err != nil {
182- return "" , err
193+ return nil , err
183194 }
184195 configuredLibraryID , err := r .runConfigureCommand (ctx , configureOutputDir )
185196 if err != nil {
186- return "" , err
197+ return nil , err
187198 }
199+
200+ apiOnboarding = true
188201 libraryID = configuredLibraryID
189202 }
190203
191204 // At this point, we should have a library in the state.
192205 libraryState := findLibraryByID (r .state , libraryID )
193206 if libraryState == nil {
194- return "" , fmt .Errorf ("library %q not configured yet, generation stopped" , libraryID )
207+ return nil , fmt .Errorf ("library %q not configured yet, generation stopped" , libraryID )
195208 }
196209 lastGenCommit := libraryState .LastGeneratedCommit
197210
198211 if len (libraryState .APIs ) == 0 {
199212 slog .Info ("library has no APIs; skipping generation" , "library" , libraryID )
200- return "" , nil
213+ return & generationStatus {
214+ oldCommit : "" ,
215+ apiOnboarding : apiOnboarding ,
216+ }, nil
201217 }
202218
203219 // For each library, create a separate output directory. This avoids
204220 // libraries interfering with each other, and makes it easier to see what
205221 // was generated for each library when debugging.
206222 libraryOutputDir := filepath .Join (outputDir , safeLibraryDirectory )
207223 if err := os .MkdirAll (libraryOutputDir , 0755 ); err != nil {
208- return "" , err
224+ return nil , err
209225 }
210226
211227 generatedLibraryID , err := r .runGenerateCommand (ctx , libraryID , libraryOutputDir )
212228 if err != nil {
213- return "" , err
229+ return nil , err
214230 }
215231
216232 if err := r .runBuildCommand (ctx , generatedLibraryID ); err != nil {
217- return "" , err
233+ return nil , err
218234 }
219235
220236 if err := r .updateLastGeneratedCommitState (generatedLibraryID ); err != nil {
221- return "" , err
237+ return nil , err
222238 }
223239
224- return lastGenCommit , nil
240+ return & generationStatus {
241+ oldCommit : lastGenCommit ,
242+ apiOnboarding : apiOnboarding ,
243+ }, nil
225244}
226245
227246func (r * generateRunner ) needsConfigure () bool {
@@ -451,7 +470,7 @@ func setAllAPIStatus(state *config.LibrarianState, status string) {
451470
452471// getSafeDirectoryName returns a directory name which doesn't contain slashes
453472// based on a library ID. This avoids cases where a library ID contains
454- // slashes but we want generateSingleLibrary to create a directory which
473+ // slashes, but we want generateSingleLibrary to create a directory which
455474// is not a subdirectory of some other directory. For example, if there
456475// are library IDs of "pubsub" and "pubsub/v2" we don't want to create
457476// "output/pubsub/v2" and then "output/pubsub" later. This function does
0 commit comments