Skip to content
Closed
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
34 changes: 27 additions & 7 deletions boxcli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,44 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"go.jetpack.io/devbox"
"go.jetpack.io/devbox/boxcli/usererr"
)

func InitCmd() *cobra.Command {
fixes := &[]string{}

command := &cobra.Command{
Use: "init [<dir>]",
Short: "Initialize a directory as a devbox project",
Args: cobra.MaximumNArgs(1),
RunE: runInitCmd,
RunE: initCmdFunc(fixes),
}
command.Flags().StringSliceVar(fixes, "fix", nil, "Run a comma-separated list of fixes on a devbox config: 'prompt'")
return command
}

func runInitCmd(cmd *cobra.Command, args []string) error {
path := pathArg(args)
func initCmdFunc(fixes *[]string) runFunc {
return func(cmd *cobra.Command, args []string) error {
path := pathArg(args)

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

// New configs come with the latest and greatest fixes already,
// so no need to apply any.
if created || len(*fixes) == 0 {
return nil
}

_, err := devbox.InitConfig(path)
if err != nil {
return errors.WithStack(err)
if len(*fixes) > 1 || (*fixes)[0] != "prompt" {
return usererr.New("The only currently available fix is 'prompt'.")
}
box, err := devbox.Open(path)
if err != nil {
return err
}
return box.Fix()
}
return nil
}
54 changes: 53 additions & 1 deletion devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
package devbox

import (
"fmt"
"path/filepath"
"strings"

"github.com/pkg/errors"
"go.jetpack.io/devbox/cuecfg"
Expand All @@ -24,7 +26,19 @@ const configFilename = "devbox.json"
// exist.
func InitConfig(dir string) (created bool, err error) {
cfgPath := filepath.Join(dir, configFilename)
return cuecfg.InitFile(cfgPath, &Config{})
created, err = cuecfg.InitFile(cfgPath, &Config{})
if err != nil {
return created, err
}
if created {
// Apply any available fixes to new configs.
box, err := Open(dir)
if err != nil {
return created, err
}
return created, box.Fix()
}
return created, err
}

// Devbox provides an isolated development environment that contains a set of
Expand Down Expand Up @@ -109,6 +123,44 @@ func (d *Devbox) Plan() (*plansdk.Plan, error) {
return plansdk.MergeUserPlan(userPlan, automatedPlan)
}

// Fix applies one or more automated fixes to the config.
func (d *Devbox) Fix() error {
// This method currently only applies the "prompt" fix, but if we ever
// want to support more fixes we can add a variadic argument for a list
// of fixes.

needsFix := true
for _, cmd := range d.cfg.Shell.InitHook.Cmds {
// Don't do anything if we or the user have already added a
// command that looks like it sets a prompt. This obviously
// isn't bulletproof, but it's good enough to make the fix
// itself idempotent.
if strings.Contains(cmd, "PS1=") {
needsFix = false
break
}
}
if !needsFix {
return nil
}

// Include the config's directory name in the prompt if we can get it.
// Otherwise just use a generic devbox prompt.
prompt := ` PS1="(devbox) $PS1"`
if abs, err := filepath.Abs(d.srcDir); err == nil {
prompt = fmt.Sprintf(` PS1="(devbox:%s) $PS1"`, filepath.Base(abs))
}
d.cfg.Shell.InitHook.Cmds = append(d.cfg.Shell.InitHook.Cmds, []string{
`# Here you can remove or customize the prompt for your project's devbox shell.`,
`# By convention, individual users can set DEVBOX_NO_PROMPT=1 in their shell's`,
`# rc file to opt out of prompt customization.`,
`if [ -z "$DEVBOX_NO_PROMPT" ]; then`,
prompt,
`fi`,
}...)
return errors.Wrap(d.saveCfg(), "fix: save config")
}

// Generate creates the directory of Nix files and the Dockerfile that define
// the devbox environment.
func (d *Devbox) Generate() error {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.19
require (
cuelang.org/go v0.4.3
github.com/bmatcuk/doublestar/v4 v4.2.0
github.com/creekorful/mvnparser v1.5.0
github.com/denisbrodbeck/machineid v1.0.1
github.com/fatih/color v1.13.0
github.com/google/go-cmp v0.4.0
Expand All @@ -25,7 +26,6 @@ require golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect
require (
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/cockroachdb/apd/v2 v2.0.1 // indirect
github.com/creekorful/mvnparser v1.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
Expand Down
3 changes: 0 additions & 3 deletions nix/shellrc.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ PATH="$(
echo "${nix_path:+$nix_path:}${non_nix_path}"
)"

# Prepend to the prompt to make it clear we're in a devbox shell.
export PS1="(devbox) $PS1"

# End Devbox Post-init Hook

{{- if .UserHook }}
Expand Down
3 changes: 0 additions & 3 deletions nix/testdata/shellrc/basic/shellrc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ PATH="$(
echo "${nix_path:+$nix_path:}${non_nix_path}"
)"

# Prepend to the prompt to make it clear we're in a devbox shell.
export PS1="(devbox) $PS1"

# End Devbox Post-init Hook

# Begin Devbox User Hook
Expand Down
3 changes: 0 additions & 3 deletions nix/testdata/shellrc/nohook/shellrc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,4 @@ PATH="$(
echo "${nix_path:+$nix_path:}${non_nix_path}"
)"

# Prepend to the prompt to make it clear we're in a devbox shell.
export PS1="(devbox) $PS1"

# End Devbox Post-init Hook
3 changes: 0 additions & 3 deletions nix/testdata/shellrc/noshellrc/shellrc.golden
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ PATH="$(
echo "${nix_path:+$nix_path:}${non_nix_path}"
)"

# Prepend to the prompt to make it clear we're in a devbox shell.
export PS1="(devbox) $PS1"

# End Devbox Post-init Hook

# Begin Devbox User Hook
Expand Down