@@ -45,8 +45,9 @@ var upgradeDepCmd = command{
4545
4646upgrade-dep upgrades one or more rules_go dependencies in WORKSPACE or
4747go/private/repositories.bzl. Dependency names (matching the name attributes)
48- can be specified with positional arguments. "all" may be specified to upgrade
49- all upgradeable dependencies.
48+ can be specified with positional arguments. They may have a suffix of the form
49+ '@version' to request update to a specific version.
50+ "all" may be specified to upgrade all upgradeable dependencies.
5051
5152For each dependency, upgrade-dep finds the highest version available in the
5253upstream repository. If no version is available, upgrade-dep uses the commit
@@ -80,6 +81,18 @@ func init() {
8081 upgradeDepCmd .run = runUpgradeDep
8182}
8283
84+ // parseDepArg parses a dependency argument like [email protected] 85+ // into the dependency name and version.
86+ // If there is no @, the arg will be returned unchanged and the version
87+ // will be an empty string.
88+ func parseDepArg (arg string ) (string , string ) {
89+ i := strings .Index (arg , "@" )
90+ if i < 0 {
91+ return arg , ""
92+ }
93+ return arg [:i ], arg [i + 1 :]
94+ }
95+
8396func runUpgradeDep (ctx context.Context , stderr io.Writer , args []string ) error {
8497 // Parse arguments.
8598 flags := flag .NewFlagSet ("releaser upgrade-dep" , flag .ContinueOnError )
@@ -210,19 +223,20 @@ func runUpgradeDep(ctx context.Context, stderr io.Writer, args []string) error {
210223 continue
211224 }
212225 eg .Go (func () error {
213- return upgradeDepDecl (egctx , gh , workDir , name , depIndex [name ], uploadToMirror )
226+ return upgradeDepDecl (egctx , gh , workDir , name , "" , depIndex [name ], uploadToMirror )
214227 })
215228 }
216229 } else {
217230 for _ , arg := range flags .Args () {
218- if depIndex [arg ] == nil {
231+ dep , _ := parseDepArg (arg )
232+ if depIndex [dep ] == nil {
219233 return fmt .Errorf ("could not find dependency %s" , arg )
220234 }
221235 }
222236 for _ , arg := range flags .Args () {
223- arg := arg
237+ arg , ver := parseDepArg ( arg )
224238 eg .Go (func () error {
225- return upgradeDepDecl (egctx , gh , workDir , arg , depIndex [arg ], uploadToMirror )
239+ return upgradeDepDecl (egctx , gh , workDir , arg , ver , depIndex [arg ], uploadToMirror )
226240 })
227241 }
228242 }
@@ -240,7 +254,7 @@ func runUpgradeDep(ctx context.Context, stderr io.Writer, args []string) error {
240254}
241255
242256// upgradeDepDecl upgrades a specific dependency.
243- func upgradeDepDecl (ctx context.Context , gh * githubClient , workDir , name string , call * bzl.CallExpr , uploadToMirror bool ) (err error ) {
257+ func upgradeDepDecl (ctx context.Context , gh * githubClient , workDir , name , version string , call * bzl.CallExpr , uploadToMirror bool ) (err error ) {
244258 defer func () {
245259 if err != nil {
246260 err = fmt .Errorf ("upgrading %s: %w" , name , err )
@@ -321,7 +335,8 @@ func upgradeDepDecl(ctx context.Context, gh *githubClient, workDir, name string,
321335 if name != semver .Canonical (name ) {
322336 continue
323337 }
324- if semver .Prerelease (name ) != "" {
338+ // Only use pre-release tags if specifically requested.
339+ if semver .Prerelease (name ) != "" && (version == "" || semver .Prerelease (version ) == "" ) {
325340 continue
326341 }
327342 tags [w ] = tags [r ]
@@ -333,6 +348,11 @@ func upgradeDepDecl(ctx context.Context, gh *githubClient, workDir, name string,
333348 var highestVname string
334349 for _ , tag := range tags {
335350 name := vname (* tag .Name )
351+ if version != "" && name == version {
352+ highestTag = tag
353+ highestVname = name
354+ break
355+ }
336356 if highestTag == nil || semver .Compare (name , highestVname ) > 0 {
337357 highestTag = tag
338358 highestVname = name
@@ -342,6 +362,11 @@ func upgradeDepDecl(ctx context.Context, gh *githubClient, workDir, name string,
342362 var ghURL , stripPrefix , urlComment string
343363 date := time .Now ().Format ("2006-01-02" )
344364 if highestTag != nil {
365+ // Check that this is the tag that was requested.
366+ if version != "" && highestVname != version {
367+ err = fmt .Errorf ("version %s not found, latest is %s" , version , * highestTag .Name )
368+ return err
369+ }
345370 // If the tag is part of a release, check whether there is a release
346371 // artifact we should use.
347372 release , _ , err := gh .Repositories .GetReleaseByTag (ctx , orgName , repoName , * highestTag .Name )
@@ -369,23 +394,49 @@ func upgradeDepDecl(ctx context.Context, gh *githubClient, workDir, name string,
369394 stripPrefix += "/" + relPath
370395 }
371396 }
372- urlComment = fmt .Sprintf ("%s, latest as of %s" , * highestTag .Name , date )
373- } else {
374- repo , _ , err := gh .Repositories .Get (ctx , orgName , repoName )
375- if err != nil {
376- return err
377- }
378- defaultBranchName := "main"
379- if repo .DefaultBranch != nil {
380- defaultBranchName = * repo .DefaultBranch
397+
398+ if version != "" {
399+ // This tag is not necessarily latest as of today, so get the commit
400+ // so we can report the actual date.
401+ commit , _ , _ := gh .Repositories .GetCommit (ctx , orgName , repoName , * highestTag .Commit .SHA )
402+ if commit := commit .GetCommit (); commit != nil {
403+ if d := commit .Committer .GetDate (); ! d .IsZero () {
404+ date = d .Format ("2006-01-02" )
405+ } else if d := commit .Author .GetDate (); ! d .IsZero () {
406+ date = d .Format ("2006-01-02" )
407+ }
408+ }
409+ urlComment = fmt .Sprintf ("%s, from %s" , * highestTag .Name , date )
410+ } else {
411+ urlComment = fmt .Sprintf ("%s, latest as of %s" , * highestTag .Name , date )
381412 }
382- branch , _ , err := gh .Repositories .GetBranch (ctx , orgName , repoName , defaultBranchName )
383- if err != nil {
384- return err
413+ } else {
414+ var commit * github.RepositoryCommit
415+ if version != "" {
416+ commit , _ , err = gh .Repositories .GetCommit (ctx , orgName , repoName , version )
417+ if err != nil {
418+ return err
419+ }
420+ date = commit .GetCommit ().Committer .GetDate ().Format ("2006-01-02" )
421+ urlComment = fmt .Sprintf ("from %s" , date )
422+ } else {
423+ repo , _ , err := gh .Repositories .Get (ctx , orgName , repoName )
424+ if err != nil {
425+ return err
426+ }
427+ defaultBranchName := "main"
428+ if repo .DefaultBranch != nil {
429+ defaultBranchName = * repo .DefaultBranch
430+ }
431+ branch , _ , err := gh .Repositories .GetBranch (ctx , orgName , repoName , defaultBranchName )
432+ if err != nil {
433+ return err
434+ }
435+ commit = branch .Commit
436+ urlComment = fmt .Sprintf ("%s, as of %s" , defaultBranchName , date )
385437 }
386- ghURL = fmt .Sprintf ("https://github.com/%s/%s/archive/%s.zip" , orgName , repoName , * branch .Commit .SHA )
387- stripPrefix = repoName + "-" + * branch .Commit .SHA
388- urlComment = fmt .Sprintf ("%s, as of %s" , defaultBranchName , date )
438+ ghURL = fmt .Sprintf ("https://github.com/%s/%s/archive/%s.zip" , orgName , repoName , * commit .SHA )
439+ stripPrefix = repoName + "-" + * commit .SHA
389440 }
390441 ghURLWithoutScheme := ghURL [len ("https://" ):]
391442 mirrorURL := "https://mirror.bazel.build/" + ghURLWithoutScheme
0 commit comments