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
25 changes: 13 additions & 12 deletions internal/boxcli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package boxcli

import (
"fmt"

"github.com/pkg/errors"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -31,7 +33,7 @@ func initCmd() *cobra.Command {
}

command.Flags().BoolVar(&flags.auto, "auto", false, "Automatically detect packages to add")
command.Flags().BoolVar(&flags.dryRun, "dry-run", false, "Dry run")
command.Flags().BoolVar(&flags.dryRun, "dry-run", false, "Dry run for auto mode. Prints the config that would be used")
_ = command.Flags().MarkHidden("auto")
_ = command.Flags().MarkHidden("dry-run")

Expand All @@ -41,18 +43,17 @@ func initCmd() *cobra.Command {
func runInitCmd(cmd *cobra.Command, args []string, flags *initFlags) error {
path := pathArg(args)

if flags.auto && flags.dryRun {
return autodetect.DryRun(cmd.Context(), path, cmd.ErrOrStderr())
}

err := devbox.InitConfig(path)
if err != nil {
return errors.WithStack(err)
}

if flags.auto {
err = autodetect.PopulateConfig(cmd.Context(), path, cmd.ErrOrStderr())
if flags.dryRun {
config, err := autodetect.DryRun(cmd.Context(), path)
if err != nil {
return errors.WithStack(err)
}
fmt.Fprintln(cmd.OutOrStdout(), string(config))
return nil
}
return autodetect.InitConfig(cmd.Context(), path)
}

return errors.WithStack(err)
return devbox.InitConfig(path)
}
3 changes: 2 additions & 1 deletion internal/devbox/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ type Devbox struct {
var legacyPackagesWarningHasBeenShown = false

func InitConfig(dir string) error {
return devconfig.Init(dir)
_, err := devconfig.Init(dir)
return err
}

func Open(opts *devopt.Opts) (*Devbox, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/devbox/devbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func TestComputeDevboxPathWhenRemoving(t *testing.T) {

func devboxForTesting(t *testing.T) *Devbox {
path := t.TempDir()
err := devconfig.Init(path)
_, err := devconfig.Init(path)
require.NoError(t, err, "InitConfig should not fail")
d, err := Open(&devopt.Opts{
Dir: path,
Expand Down
32 changes: 16 additions & 16 deletions internal/devconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func TestOpen(t *testing.T) {
t.Run("Dir", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -31,7 +31,7 @@ func TestOpen(t *testing.T) {
})
t.Run("File", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}
path := filepath.Join(root, "devbox.json")
Expand All @@ -50,7 +50,7 @@ func TestOpen(t *testing.T) {
func TestOpenError(t *testing.T) {
t.Run("NotExist", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand Down Expand Up @@ -79,7 +79,7 @@ func TestOpenError(t *testing.T) {
})
t.Run("ParentNotFound", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -96,10 +96,10 @@ func TestOpenError(t *testing.T) {
func TestFind(t *testing.T) {
t.Run("StartInSameDir", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}
if err := Init(child); err != nil {
if _, err := Init(child); err != nil {
t.Fatalf("Init(%q) error: %v", child, err)
}

Expand All @@ -114,7 +114,7 @@ func TestFind(t *testing.T) {
})
t.Run("StartInChildDir", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -129,10 +129,10 @@ func TestFind(t *testing.T) {
})
t.Run("StartInNestedChildDir", func(t *testing.T) {
root, child, nested := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}
if err := Init(child); err != nil {
if _, err := Init(child); err != nil {
t.Fatalf("Init(%q) error: %v", child, err)
}

Expand All @@ -147,7 +147,7 @@ func TestFind(t *testing.T) {
})
t.Run("IgnoreDirsWithMatchingName", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -171,7 +171,7 @@ func TestFind(t *testing.T) {
})
t.Run("ExactFile", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -189,7 +189,7 @@ func TestFind(t *testing.T) {
func TestFindError(t *testing.T) {
t.Run("NotExist", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -207,7 +207,7 @@ func TestFindError(t *testing.T) {
})
t.Run("NotFound", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(child); err != nil {
if _, err := Init(child); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}

Expand All @@ -221,10 +221,10 @@ func TestFindError(t *testing.T) {
})
t.Run("Permissions", func(t *testing.T) {
root, child, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}
if err := Init(child); err != nil {
if _, err := Init(child); err != nil {
t.Fatalf("Init(%q) error: %v", child, err)
}
path := filepath.Join(child, "devbox.json")
Expand Down Expand Up @@ -260,7 +260,7 @@ func TestFindError(t *testing.T) {
})
t.Run("ExactFilePermissions", func(t *testing.T) {
root, _, _ := mkNestedDirs(t)
if err := Init(root); err != nil {
if _, err := Init(root); err != nil {
t.Fatalf("Init(%q) error: %v", root, err)
}
path := filepath.Join(root, "devbox.json")
Expand Down
17 changes: 10 additions & 7 deletions internal/devconfig/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@ import (
"go.jetpack.io/devbox/internal/devconfig/configfile"
)

func Init(dir string) error {
func Init(dir string) (*Config, error) {
file, err := os.OpenFile(
filepath.Join(dir, configfile.DefaultName),
os.O_RDWR|os.O_CREATE|os.O_EXCL,
0o644,
)
if errors.Is(err, os.ErrExist) {
return nil
// TODO: Should we return an error here?
// If we do, it breaks a bunch of tests, but it's likely the correct behavior
return nil, nil
}
if err != nil {
return err
return nil, err
}
defer func() {
if err != nil {
os.Remove(file.Name())
}
}()

_, err = file.Write(DefaultConfig().Root.Bytes())
newConfig := DefaultConfig()
_, err = file.Write(newConfig.Root.Bytes())
defer file.Close()
if err != nil {
file.Close()
return err
return nil, err
}
return file.Close()
return newConfig, nil
}
33 changes: 14 additions & 19 deletions pkg/autodetect/autodetect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,35 @@ package autodetect

import (
"context"
"fmt"
"io"

"go.jetpack.io/devbox/internal/devbox"
"go.jetpack.io/devbox/internal/devbox/devopt"
"go.jetpack.io/devbox/internal/devconfig"
"go.jetpack.io/devbox/pkg/autodetect/detector"
)

func PopulateConfig(ctx context.Context, path string, stderr io.Writer) error {
pkgs, err := packages(ctx, path)
func InitConfig(ctx context.Context, path string) error {
config, err := devconfig.Init(path)
if err != nil {
return err
}
devbox, err := devbox.Open(&devopt.Opts{
Dir: path,
Stderr: stderr,
})
if err != nil {
return err

return populateConfig(ctx, path, config)
}

func DryRun(ctx context.Context, path string) ([]byte, error) {
config := devconfig.DefaultConfig()
if err := populateConfig(ctx, path, config); err != nil {
return nil, err
}
return devbox.Add(ctx, pkgs, devopt.AddOpts{})
return config.Root.Bytes(), nil
}

func DryRun(ctx context.Context, path string, stderr io.Writer) error {
func populateConfig(ctx context.Context, path string, config *devconfig.Config) error {
pkgs, err := packages(ctx, path)
if err != nil {
return err
} else if len(pkgs) == 0 {
fmt.Fprintln(stderr, "No packages to add")
return nil
}
fmt.Fprintln(stderr, "Packages to add:")
for _, pkg := range pkgs {
fmt.Fprintln(stderr, pkg)
config.PackageMutator().Add(pkg)
}
return nil
}
Expand Down