-
Notifications
You must be signed in to change notification settings - Fork 38
feat(internal/librarian/golang): generate repo metadata for Go libraries #4055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ import ( | |||||||||||||
|
|
||||||||||||||
| "github.com/googleapis/librarian/internal/command" | ||||||||||||||
| "github.com/googleapis/librarian/internal/config" | ||||||||||||||
| "github.com/googleapis/librarian/internal/repometadata" | ||||||||||||||
| "github.com/googleapis/librarian/internal/semver" | ||||||||||||||
| "github.com/googleapis/librarian/internal/serviceconfig" | ||||||||||||||
| ) | ||||||||||||||
|
|
@@ -98,17 +99,26 @@ func Generate(ctx context.Context, library *config.Library, googleapisDir string | |||||||||||||
| if err := generateInternalVersionFile(moduleRoot, library.Version); err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| for _, api := range library.APIs { | ||||||||||||||
| for i, api := range library.APIs { | ||||||||||||||
| if err := generateClientVersionFile(library, api.Path); err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| api, err := serviceconfig.Find(googleapisDir, library.APIs[0].Path, serviceconfig.LangGo) | ||||||||||||||
| if err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| if err := generateREADME(library, api, moduleRoot); err != nil { | ||||||||||||||
| return err | ||||||||||||||
| svcAPI, err := serviceconfig.Find(googleapisDir, api.Path, serviceconfig.LangGo) | ||||||||||||||
| if err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| info := &repometadata.LibraryInfo{} | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||
| outDir := filepath.Join(outdir, api.Path) | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The You should validate that the constructed References
|
||||||||||||||
| if err := repometadata.FromAPI(svcAPI, info, serviceconfig.LangGo, "", "", outDir); err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| // We only need to generate README.md at module root once. | ||||||||||||||
| if i != 0 { | ||||||||||||||
| continue | ||||||||||||||
| } | ||||||||||||||
| if err := generateREADME(library, svcAPI, moduleRoot); err != nil { | ||||||||||||||
| return err | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| if err := updateSnippetMetadata(library, outdir); err != nil { | ||||||||||||||
| return err | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,14 +61,7 @@ func generateInternalVersionFile(moduleDir, version string) (err error) { | |
| } | ||
|
|
||
| func generateClientVersionFile(library *config.Library, apiPath string) (err error) { | ||
| version := filepath.Base(apiPath) | ||
| goAPI := findGoAPI(library, apiPath) | ||
| var clientDir string | ||
| if goAPI != nil && goAPI.ClientDirectory != "" { | ||
| clientDir = goAPI.ClientDirectory | ||
| } | ||
|
|
||
| dir := filepath.Join(library.Output, library.Name, clientDir, "api"+version) | ||
| dir := apiVersionPath(library, apiPath) | ||
| if err := os.MkdirAll(dir, 0755); err != nil { | ||
| return err | ||
| } | ||
|
|
@@ -87,6 +80,7 @@ func generateClientVersionFile(library *config.Library, apiPath string) (err err | |
| } | ||
| t := template.Must(template.New("version").Parse(clientVersionTmpl)) | ||
| pkg := library.Name | ||
| clientDir := clientDirectory(library, apiPath) | ||
| if clientDir != "" { | ||
| pkg = clientDir | ||
| } | ||
|
|
@@ -96,6 +90,20 @@ func generateClientVersionFile(library *config.Library, apiPath string) (err err | |
| }) | ||
| } | ||
|
|
||
| func apiVersionPath(library *config.Library, apiPath string) string { | ||
| version := filepath.Base(apiPath) | ||
| clientDir := clientDirectory(library, apiPath) | ||
| return filepath.Join(library.Output, library.Name, clientDir, "api"+version) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Validate that the constructed path is within the intended output directory using a prefix check on the absolute paths. References
|
||
| } | ||
|
|
||
| func clientDirectory(library *config.Library, apiPath string) string { | ||
| goAPI := findGoAPI(library, apiPath) | ||
| if goAPI != nil { | ||
| return goAPI.ClientDirectory | ||
| } | ||
| return "" | ||
| } | ||
|
|
||
| // writeLicenseHeader writes the license header as Go comments to the given file. | ||
| func writeLicenseHeader(f *os.File) error { | ||
| year := time.Now().Format("2006") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
api.Pathis passed toserviceconfig.Find, which uses it to construct file paths for reading service configurations. Sinceserviceconfig.validateAPIallows any path starting withgoogle/cloud/, an attacker could use a path likegoogle/cloud/../../../../etc/passwdto cause the tool to attempt to read arbitrary files from the filesystem where the tool is running.Consider sanitizing or validating
api.Pathto ensure it does not contain directory traversal sequences before passing it toserviceconfig.Find.References