@@ -72,14 +72,12 @@ func main() {
7272log .Println ("googleapis-dir set to" ,* googleapisDir )
7373log .Println ("branch set to" ,* branchOverride )
7474log .Println ("prFilepath is" ,* prFilepath )
75+ log .Println ("directories are" ,* directories )
7576
76- var modules []string
77+ dirSlice := []string {}
7778if * directories != "" {
7879dirSlice := strings .Split (* directories ,"," )
79- for _ ,dir := range dirSlice {
80- modules = append (modules ,filepath .Join (* clientRoot ,dir ))
81- }
82- log .Println ("Postprocessor running on" ,modules )
80+ log .Println ("Postprocessor running on" ,dirSlice )
8381}else {
8482log .Println ("Postprocessor running on all modules." )
8583}
@@ -103,11 +101,13 @@ func main() {
103101c := & config {
104102googleapisDir :* googleapisDir ,
105103googleCloudDir :* clientRoot ,
106- modules :modules ,
104+ modules :dirSlice ,
107105branchOverride :* branchOverride ,
108106githubUsername :* githubUsername ,
109107prFilepath :* prFilepath ,
110108runAll :runAll ,
109+ prTitle :"" ,
110+ prBody :"" ,
111111}
112112
113113if err := c .run (ctx );err != nil {
@@ -120,11 +120,19 @@ func main() {
120120type config struct {
121121googleapisDir string
122122googleCloudDir string
123- modules []string
123+
124+ // At this time modules are either provided at the time of invocation locally
125+ // and extracted from the open OwlBot PR description. If we would like
126+ // the postprocessor to be able to be run on non-OwlBot PRs, we would
127+ // need to change the method of populating this field.
128+ modules []string
129+
124130branchOverride string
125131githubUsername string
126132prFilepath string
127133runAll bool
134+ prTitle string
135+ prBody string
128136}
129137
130138// runAll uses git to tell if the PR being updated should run all post
@@ -150,7 +158,16 @@ func (c *config) run(ctx context.Context) error {
150158log .Println ("exiting post processing early" )
151159return nil
152160}
153- if err := gocmd .ModTidyAll (c .googleCloudDir );err != nil {
161+ // TODO(guadriana): Once the PR for initializing new modules is merged, we
162+ // will need to add logic here that sets c.modules to modConfigs (a slice of
163+ // all modules) if branchOverride != ""
164+
165+ // TODO(codyoss): In the future we may want to make it possible to be able
166+ // to run this locally with a user defined remote branch.
167+ if err := c .SetScopesAndPRInfo (ctx );err != nil {
168+ return err
169+ }
170+ if err := c .TidyAffectedMods ();err != nil {
154171return err
155172}
156173if err := gocmd .Vet (c .googleCloudDir );err != nil {
@@ -162,28 +179,44 @@ func (c *config) run(ctx context.Context) error {
162179if _ ,err := c .Manifest (generator .MicrogenGapicConfigs );err != nil {
163180return err
164181}
165- // TODO(codyoss): In the future we may want to make it possible to be able
166- // to run this locally with a user defined remote branch.
167- if err := c .AmendPRDescription (ctx );err != nil {
182+ if err := c .WritePRInfoToFile ();err != nil {
168183return err
169184}
170185return nil
171186}
172187
188+ func (c * config )getDirs () []string {
189+ dirs := []string {}
190+ for _ ,module := range c .modules {
191+ dirs = append (dirs ,filepath .Join (c .googleCloudDir ,module ))
192+ }
193+ return dirs
194+ }
195+
196+ func (c * config )TidyAffectedMods ()error {
197+ dirs := c .getDirs ()
198+ for _ ,dir := range dirs {
199+ if err := gocmd .ModTidy (dir );err != nil {
200+ return err
201+ }
202+ }
203+ return nil
204+ }
205+
173206// RegenSnippets regenerates the snippets for all GAPICs configured to be generated.
174207func (c * config )RegenSnippets ()error {
175208log .Println ("regenerating snippets" )
176-
177209snippetDir := filepath .Join (c .googleCloudDir ,"internal" ,"generated" ,"snippets" )
178- apiShortnames , err := generator . ParseAPIShortnames ( c . googleapisDir , generator . MicrogenGapicConfigs , generator . ManualEntries )
179-
210+ confs := c . getChangedClientConfs ( )
211+ apiShortnames , err := generator . ParseAPIShortnames ( c . googleapisDir , confs , generator . ManualEntries )
180212if err != nil {
181213return err
182214}
183- if err := gensnippets .GenerateSnippetsDirs (c .googleCloudDir ,snippetDir ,apiShortnames ,c .modules );err != nil {
215+ dirs := c .getDirs ()
216+ if err := gensnippets .GenerateSnippetsDirs (c .googleCloudDir ,snippetDir ,apiShortnames ,dirs );err != nil {
184217log .Printf ("warning: got the following non-fatal errors generating snippets: %v" ,err )
185218}
186- if err := c .replaceAllForSnippets (c . googleCloudDir , snippetDir );err != nil {
219+ if err := c .replaceAllForSnippets (snippetDir );err != nil {
187220return err
188221}
189222if err := gocmd .ModTidy (snippetDir );err != nil {
@@ -193,15 +226,44 @@ func (c *config) RegenSnippets() error {
193226return nil
194227}
195228
196- func (c * config )replaceAllForSnippets (googleCloudDir ,snippetDir string )error {
197- return execv .ForEachMod (googleCloudDir ,func (dir string )error {
229+ // getChangedClientConfs iterates through the MicrogenGapicConfigs and returns
230+ // a slice of the entries corresponding to modified modules and clients
231+ func (c * config )getChangedClientConfs () []* generator.MicrogenConfig {
232+ if len (c .modules )!= 0 {
233+ runConfs := []* generator.MicrogenConfig {}
234+ for _ ,conf := range generator .MicrogenGapicConfigs {
235+ for _ ,scope := range c .modules {
236+ scopePathElement := "/" + scope + "/"
237+ if strings .Contains (conf .InputDirectoryPath ,scopePathElement ) {
238+ runConfs = append (runConfs ,conf )
239+ }
240+ }
241+ }
242+ return runConfs
243+ }
244+ return generator .MicrogenGapicConfigs
245+ }
246+
247+ func (c * config )replaceAllForSnippets (snippetDir string )error {
248+ return execv .ForEachMod (c .googleCloudDir ,func (dir string )error {
249+ processMod := false
198250if c .modules != nil {
251+ // Checking each path component in its entirety prevents mistaken addition of modules whose names
252+ // contain the scope as a substring. For example if the scope is "video" we do not want to regenerate
253+ // snippets for "videointelligence"
254+ dirSlice := strings .Split (dir ,"/" )
199255for _ ,mod := range c .modules {
200- if ! strings .Contains (dir ,mod ) {
201- return nil
256+ for _ ,dirElem := range dirSlice {
257+ if mod == dirElem {
258+ processMod = true
259+ break
260+ }
202261}
203262}
204263}
264+ if ! processMod {
265+ return nil
266+ }
205267if dir == snippetDir {
206268return nil
207269}
@@ -280,7 +342,7 @@ func docURL(cloudDir, importPath string) (string, error) {
280342return "https://cloud.google.com/go/docs/reference/" + mod + "/latest/" + pkgPath ,nil
281343}
282344
283- func (c * config )AmendPRDescription (ctx context.Context )error {
345+ func (c * config )SetScopesAndPRInfo (ctx context.Context )error {
284346log .Println ("Amending PR title and body" )
285347pr ,err := c .getPR (ctx )
286348if err != nil {
@@ -290,13 +352,16 @@ func (c *config) AmendPRDescription(ctx context.Context) error {
290352if err != nil {
291353return err
292354}
293- return c .writePRCommitToFile (newPRTitle ,newPRBody )
355+ c .prTitle = newPRTitle
356+ c .prBody = newPRBody
357+ return nil
294358}
295359
296360func (c * config )processCommit (title ,body string ) (string ,string ,error ) {
297361var newPRTitle string
298362var commitTitle string
299363var commitTitleIndex int
364+ var modules []string
300365
301366bodySlice := strings .Split (body ,"\n " )
302367for index ,line := range bodySlice {
@@ -312,7 +377,12 @@ func (c *config) processCommit(title, body string) (string, string, error) {
312377continue
313378}
314379hash := extractHashFromLine (line )
315- scope ,err := c .getScopeFromGoogleapisCommitHash (hash )
380+ scopes ,err := c .getScopesFromGoogleapisCommitHash (hash )
381+ modules = append (modules ,scopes ... )
382+ var scope string
383+ if len (scopes )== 1 {
384+ scope = scopes [0 ]
385+ }
316386if err != nil {
317387return "" ,"" ,err
318388}
@@ -324,6 +394,7 @@ func (c *config) processCommit(title, body string) (string, string, error) {
324394bodySlice [commitTitleIndex ]= newCommitTitle
325395}
326396body = strings .Join (bodySlice ,"\n " )
397+ c .modules = append (c .modules ,modules ... )
327398return newPRTitle ,body ,nil
328399}
329400
@@ -349,14 +420,14 @@ func (c *config) getPR(ctx context.Context) (*github.PullRequest, error) {
349420return owlbotPR ,nil
350421}
351422
352- func (c * config )getScopeFromGoogleapisCommitHash (commitHash string ) (string ,error ) {
423+ func (c * config )getScopesFromGoogleapisCommitHash (commitHash string ) ([] string ,error ) {
353424files ,err := c .filesChanged (commitHash )
354425if err != nil {
355- return "" ,err
426+ return nil ,err
356427}
357428// if no files changed, return empty string
358429if len (files )== 0 {
359- return "" ,nil
430+ return nil ,nil
360431}
361432scopesMap := make (map [string ]bool )
362433scopes := []string {}
@@ -375,12 +446,7 @@ func (c *config) getScopeFromGoogleapisCommitHash(commitHash string) (string, er
375446}
376447}
377448}
378- // if no in-scope packages are found or if many packages found, return empty string
379- if len (scopes )!= 1 {
380- return "" ,nil
381- }
382- // if single scope found, return
383- return scopes [0 ],nil
449+ return scopes ,nil
384450}
385451
386452// filesChanged returns a list of files changed in a commit for the provdied
@@ -421,8 +487,9 @@ func updateCommitTitle(title, titlePkg string) string {
421487return newTitle
422488}
423489
424- // writePRCommitToFile uses OwlBot env variable specified path to write updated PR title and body at that location
425- func (c * config )writePRCommitToFile (title ,body string )error {
490+ // WritePRInfoToFile uses OwlBot env variable specified path to write updated
491+ // PR title and body at that location
492+ func (c * config )WritePRInfoToFile ()error {
426493// if file exists at location, delete
427494if err := os .Remove (c .prFilepath );err != nil {
428495if errors .Is (err ,fs .ErrNotExist ) {
@@ -436,7 +503,12 @@ func (c *config) writePRCommitToFile(title, body string) error {
436503return err
437504}
438505defer f .Close ()
439- if _ ,err := f .WriteString (fmt .Sprintf ("%s\n \n %s" ,title ,body ));err != nil {
506+ if c .prTitle == "" && c .prBody == "" {
507+ log .Println ("No updated PR info found, will not write PR title and description to file." )
508+ return nil
509+ }
510+ log .Println ("Writing PR title and description to file." )
511+ if _ ,err := f .WriteString (fmt .Sprintf ("%s\n \n %s" ,c .prTitle ,c .prBody ));err != nil {
440512return err
441513}
442514return nil