Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions internal/boxcli/multi/multi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package multi

import (
"io/fs"
"path/filepath"

"go.jetpack.io/devbox"
"go.jetpack.io/devbox/internal/debug"
"go.jetpack.io/devbox/internal/impl/devopt"
)

func Open(opts *devopt.Opts) ([]devbox.Devbox, error) {
defer debug.FunctionTimer().End()

var boxes []devbox.Devbox
err := filepath.WalkDir(
".",
func(path string, dirEntry fs.DirEntry, err error) error {
if err != nil {
return err
}

if !dirEntry.IsDir() && filepath.Base(path) == "devbox.json" {
optsCopy := *opts
optsCopy.Dir = path
box, err := devbox.Open(&optsCopy)
if err != nil {
return err
}
boxes = append(boxes, box)
}

return nil
},
)

return boxes, err
}
23 changes: 17 additions & 6 deletions internal/lock/sync.go → internal/boxcli/multi/sync.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package lock
package multi

import (
"fmt"
Expand All @@ -8,9 +8,11 @@ import (

"go.jetpack.io/devbox/internal/cuecfg"
"go.jetpack.io/devbox/internal/debug"
"go.jetpack.io/devbox/internal/lock"
"go.jetpack.io/devbox/internal/searcher"
)

func SyncLockfiles() error {
func SyncLockfiles(pkgs []string) error {
lockfilePaths, err := collectLockfiles()
if err != nil {
return err
Expand All @@ -21,15 +23,24 @@ func SyncLockfiles() error {
return err
}

pkgMap := make(map[string]bool)
for _, pkg := range pkgs {
pkgMap[pkg] = true
}

for _, lockfilePath := range lockfilePaths {
var lockFile File
var lockFile lock.File
if err := cuecfg.ParseFile(lockfilePath, &lockFile); err != nil {
return err
}

changed := false
for key, latestPkg := range latestPackages {
if pkg, exists := lockFile.Packages[key]; exists {
name, _, found := searcher.ParseVersionedPackage(key)
if len(pkgMap) > 0 && (!pkgMap[key] && (found && !pkgMap[name])) {
continue
}
if pkg.LastModified != latestPkg.LastModified {
lockFile.Packages[key].AllowInsecure = latestPkg.AllowInsecure
lockFile.Packages[key].LastModified = latestPkg.LastModified
Expand All @@ -54,11 +65,11 @@ func SyncLockfiles() error {
return nil
}

func latestPackages(lockfilePaths []string) (map[string]*Package, error) {
latestPackages := make(map[string]*Package)
func latestPackages(lockfilePaths []string) (map[string]*lock.Package, error) {
latestPackages := make(map[string]*lock.Package)

for _, lockFilePath := range lockfilePaths {
var lockFile File
var lockFile lock.File
if err := cuecfg.ParseFile(lockFilePath, &lockFile); err != nil {
return nil, err
}
Expand Down
47 changes: 40 additions & 7 deletions internal/boxcli/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"github.com/spf13/cobra"

"go.jetpack.io/devbox"
"go.jetpack.io/devbox/internal/boxcli/multi"
"go.jetpack.io/devbox/internal/boxcli/usererr"
"go.jetpack.io/devbox/internal/impl/devopt"
)

type updateCmdFlags struct {
config configFlags
sync bool
config configFlags
sync bool
allProjects bool
}

func updateCmd() *cobra.Command {
Expand All @@ -41,10 +43,28 @@ func updateCmd() *cobra.Command {
"Sync all devbox.lock dependencies in multiple projects. "+
"Dependencies will sync to the latest local version.",
)
command.Flags().BoolVar(
&flags.allProjects,
"all-projects",
false,
"Update all projects in the working directory, recursively.",
)
return command
}

func updateCmdFunc(cmd *cobra.Command, args []string, flags *updateCmdFlags) error {
if len(args) > 0 && flags.sync {
return usererr.New("cannot specify both a package and --sync")
}

if flags.allProjects {
return updateAllProjects(cmd, args)
}

if flags.sync {
return multi.SyncLockfiles(args)
}

box, err := devbox.Open(&devopt.Opts{
Dir: flags.config.path,
Stderr: cmd.ErrOrStderr(),
Expand All @@ -53,12 +73,25 @@ func updateCmdFunc(cmd *cobra.Command, args []string, flags *updateCmdFlags) err
return errors.WithStack(err)
}

if len(args) > 0 && flags.sync {
return usererr.New("cannot specify both a package and --sync")
}

return box.Update(cmd.Context(), devopt.UpdateOpts{
Pkgs: args,
Sync: flags.sync,
})
}

func updateAllProjects(cmd *cobra.Command, args []string) error {
boxes, err := multi.Open(&devopt.Opts{
Stderr: cmd.ErrOrStderr(),
})
if err != nil {
return errors.WithStack(err)
}
for _, box := range boxes {
if err := box.Update(cmd.Context(), devopt.UpdateOpts{
Pkgs: args,
IgnoreMissingPackages: true,
}); err != nil {
return err
}
}
return multi.SyncLockfiles(args)
}
3 changes: 2 additions & 1 deletion internal/impl/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,8 @@ func (d *Devbox) findPackageByName(name string) (*devpkg.Package, error) {
)
}
if len(results) == 0 {
return nil, usererr.New("no package found with name %s", name)
return nil, usererr.WithUserMessage(
searcher.ErrNotFound, "no package found with name %s", name)
}
return lo.Keys(results)[0], nil
}
Expand Down
4 changes: 2 additions & 2 deletions internal/impl/devopt/devboxopts.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ type Credentials struct {
}

type UpdateOpts struct {
Pkgs []string
Sync bool
Pkgs []string
IgnoreMissingPackages bool
}
19 changes: 10 additions & 9 deletions internal/impl/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"

"github.com/pkg/errors"
"go.jetpack.io/devbox/internal/boxcli/featureflag"
"go.jetpack.io/devbox/internal/devpkg"
"go.jetpack.io/devbox/internal/impl/devopt"
Expand All @@ -20,11 +21,7 @@ import (
)

func (d *Devbox) Update(ctx context.Context, opts devopt.UpdateOpts) error {
if opts.Sync {
return lock.SyncLockfiles()
}

inputs, err := d.inputsToUpdate(opts.Pkgs...)
inputs, err := d.inputsToUpdate(opts)
if err != nil {
return err
}
Expand Down Expand Up @@ -77,15 +74,19 @@ func (d *Devbox) Update(ctx context.Context, opts devopt.UpdateOpts) error {
return nix.FlakeUpdate(shellgen.FlakePath(d))
}

func (d *Devbox) inputsToUpdate(pkgs ...string) ([]*devpkg.Package, error) {
if len(pkgs) == 0 {
func (d *Devbox) inputsToUpdate(
opts devopt.UpdateOpts,
) ([]*devpkg.Package, error) {
if len(opts.Pkgs) == 0 {
return d.configPackages(), nil
}

var pkgsToUpdate []*devpkg.Package
for _, pkg := range pkgs {
for _, pkg := range opts.Pkgs {
found, err := d.findPackageByName(pkg)
if err != nil {
if opts.IgnoreMissingPackages && errors.Is(err, searcher.ErrNotFound) {
continue
} else if err != nil {
return nil, err
}
pkgsToUpdate = append(pkgsToUpdate, found)
Expand Down