diff --git a/internal/boxcli/list.go b/internal/boxcli/list.go index 0ed713d8606..48c33707b79 100644 --- a/internal/boxcli/list.go +++ b/internal/boxcli/list.go @@ -5,6 +5,7 @@ package boxcli import ( "fmt" + "strings" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -32,8 +33,26 @@ func listCmd() *cobra.Command { if err != nil { return errors.WithStack(err) } - for _, p := range box.AllPackageNamesIncludingRemovedTriggerPackages() { - fmt.Fprintf(cmd.OutOrStdout(), "* %s\n", p) + + for _, pkg := range box.AllPackagesIncludingRemovedTriggerPackages() { + resolvedVersion, err := pkg.ResolvedVersion() + if err != nil { + // Continue to print the package even if we can't resolve the version + // so that the user can see the error for this package, as well as get the + // results for the other packages + resolvedVersion = "" + } + msg := "" + + // Print the resolved version, unless the user has specified a version already + if strings.HasSuffix(pkg.Versioned(), "latest") && resolvedVersion != "" { + // Runx packages have a "v" prefix (why?). Trim for consistency. + resolvedVersion = strings.TrimPrefix(resolvedVersion, "v") + msg = fmt.Sprintf("* %s - %s\n", pkg.Versioned(), resolvedVersion) + } else { + msg = fmt.Sprintf("* %s\n", pkg.Versioned()) + } + fmt.Fprint(cmd.OutOrStdout(), msg) } return nil }, diff --git a/internal/devbox/devbox.go b/internal/devbox/devbox.go index f9584173203..f9ee29d96fc 100644 --- a/internal/devbox/devbox.go +++ b/internal/devbox/devbox.go @@ -842,12 +842,17 @@ func (d *Devbox) flakeDir() string { // flakes (lockfile vs devbox list) func (d *Devbox) AllPackageNamesIncludingRemovedTriggerPackages() []string { result := []string{} - for _, p := range d.cfg.Packages(true /*includeRemovedTriggerPackages*/) { - result = append(result, p.VersionedName()) + for _, p := range d.AllPackagesIncludingRemovedTriggerPackages() { + result = append(result, p.Versioned()) } return result } +func (d *Devbox) AllPackagesIncludingRemovedTriggerPackages() []*devpkg.Package { + packages := d.cfg.Packages(true /*includeRemovedTriggerPackages*/) + return devpkg.PackagesFromConfig(packages, d.lockfile) +} + // AllPackages returns the packages that are defined in devbox.json and // recursively added by plugins. // NOTE: This will not return packages removed by their plugin with the diff --git a/internal/devpkg/package.go b/internal/devpkg/package.go index c4341dbff33..da6d4332651 100644 --- a/internal/devpkg/package.go +++ b/internal/devpkg/package.go @@ -832,3 +832,15 @@ func packageInstallErrorHandler(err error, pkg *Package, installableOrEmpty stri return usererr.WithUserMessage(err, "error installing package %s", pkg.Raw) } + +func (p *Package) ResolvedVersion() (string, error) { + if err := p.resolve(); err != nil { + return "", err + } + lockPackage := p.lockfile.Get(p.Raw) + // Flake packages don't have any values in the lockfile + if lockPackage == nil { + return "", nil + } + return p.lockfile.Get(p.Raw).Version, nil +}