Skip to content

Commit ff381aa

Browse files
guerinoniLagoja
andauthored
feat: implement outdated command (#2497)
## Summary This allow to present all new versions available for the pkg installed. It is a lot useful because otherwise you need to check this manually. ## How was it tested? In a different repository, this is the output. <img width="383" alt="Screenshot 2025-01-31 at 17 54 25" src="https://github.com/user-attachments/assets/6041e24a-8c1c-4d74-8213-99738959cc17" /> --------- Co-authored-by: John Lago <[email protected]>
1 parent 3f7706d commit ff381aa

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

internal/boxcli/list.go

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 Jetify Inc. and contributors. All rights reserved.
1+
// Copyright 2025 Jetify Inc. and contributors. All rights reserved.
22
// Use of this source code is governed by the license in the LICENSE file.
33

44
package boxcli
@@ -15,7 +15,8 @@ import (
1515
)
1616

1717
type listCmdFlags struct {
18-
config configFlags
18+
config configFlags
19+
outdated bool
1920
}
2021

2122
func listCmd() *cobra.Command {
@@ -34,6 +35,10 @@ func listCmd() *cobra.Command {
3435
return errors.WithStack(err)
3536
}
3637

38+
if flags.outdated {
39+
return printOutdatedPackages(cmd, box)
40+
}
41+
3742
for _, pkg := range box.AllPackagesIncludingRemovedTriggerPackages() {
3843
resolvedVersion, err := pkg.ResolvedVersion()
3944
if err != nil {
@@ -57,6 +62,28 @@ func listCmd() *cobra.Command {
5762
return nil
5863
},
5964
}
65+
66+
cmd.Flags().BoolVar(&flags.outdated, "outdated", false, "List outdated packages")
6067
flags.config.register(cmd)
6168
return cmd
6269
}
70+
71+
// printOutdatedPackages prints a list of outdated packages.
72+
func printOutdatedPackages(cmd *cobra.Command, box *devbox.Devbox) error {
73+
results, err := box.Outdated(cmd.Context())
74+
if err != nil {
75+
return errors.WithStack(err)
76+
}
77+
78+
if len(results) == 0 {
79+
cmd.Println("Your packages are up to date!")
80+
return nil
81+
}
82+
83+
cmd.Println("The following packages can be updated:")
84+
for pkg, version := range results {
85+
cmd.Printf(" * %-30s %s -> %s\n", pkg, version.Current, version.Latest)
86+
}
87+
88+
return nil
89+
}

internal/devbox/packages.go

+31
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,37 @@ const StateOutOfDateMessage = "Your devbox environment may be out of date. Run %
4343
// packages.go has functions for adding, removing and getting info about nix
4444
// packages
4545

46+
type UpdateVersion struct {
47+
Current string
48+
Latest string
49+
}
50+
51+
// Outdated returns a map of package names to their available latest version.
52+
func (d *Devbox) Outdated(ctx context.Context) (map[string]UpdateVersion, error) {
53+
lockfile := d.Lockfile()
54+
outdatedPackages := map[string]UpdateVersion{}
55+
56+
for _, pkg := range d.AllPackages() {
57+
// For non-devbox packages, like flakes or runx, we can skip for now
58+
if !pkg.IsDevboxPackage {
59+
continue
60+
}
61+
62+
lockPackage, err := lockfile.FetchResolvedPackage(pkg.Versioned())
63+
if err != nil {
64+
return nil, errors.Wrap(err, "failed to fetch resolved package")
65+
}
66+
existingLockPackage := lockfile.Packages[pkg.Raw]
67+
if lockPackage.Version == existingLockPackage.Version {
68+
continue
69+
}
70+
71+
outdatedPackages[pkg.Versioned()] = UpdateVersion{Current: existingLockPackage.Version, Latest: lockPackage.Version}
72+
}
73+
74+
return outdatedPackages, nil
75+
}
76+
4677
// Add adds the `pkgs` to the config (i.e. devbox.json) and nix profile for this
4778
// devbox project
4879
func (d *Devbox) Add(ctx context.Context, pkgsNames []string, opts devopt.AddOpts) error {

0 commit comments

Comments
 (0)