Skip to content

Commit

Permalink
[bin-wrappers] Don't use wrappers on run (jetify-com#1361)
Browse files Browse the repository at this point in the history
## Summary

When doing `devbox run` the environment is always correct because
commands are run in a new sub-process with correct computed environment
therefore wrappers are not needed. This is a low handing fruit that
should improve performance when doing `devbox run`

## How was it tested?

```
➜  devbox git:(main) ✗ devbox run which go
/Users/mike/dev/jetpack-repos/devbox/.devbox/nix/profile/default/bin/go
➜  devbox git:(main) ✗ devbox shell
Starting a devbox shell...
(devbox) ➜  devbox git:(main) ✗ which go
/Users/mike/dev/jetpack-repos/devbox/.devbox/virtenv/.wrappers/bin/go
```
  • Loading branch information
mikeland73 authored Aug 11, 2023
1 parent dd6d815 commit 0466f6a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 33 deletions.
18 changes: 14 additions & 4 deletions internal/boxcli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package boxcli

import (
"fmt"
"os"
"strconv"
"strings"

"github.com/samber/lo"
Expand Down Expand Up @@ -96,12 +98,20 @@ func runScriptCmd(cmd *cobra.Command, args []string, flags runCmdFlags) error {
if err != nil {
return err
}

omitBinWrappersFromPath := true
// This is for testing. Once we completely remove bin wrappers we can remove
// this. It helps simulate shell using "run".
if ok, _ := strconv.ParseBool(os.Getenv("DEVBOX_INCLUDE_BIN_WRAPPERS_IN_PATH")); ok {
omitBinWrappersFromPath = false
}
// Check the directory exists.
box, err := devbox.Open(&devopt.Opts{
Dir: path,
Writer: cmd.ErrOrStderr(),
Pure: flags.pure,
Env: env,
Dir: path,
Writer: cmd.ErrOrStderr(),
Pure: flags.pure,
Env: env,
OmitBinWrappersFromPath: omitBinWrappersFromPath,
})
if err != nil {
return redact.Errorf("error reading devbox.json: %w", err)
Expand Down
20 changes: 9 additions & 11 deletions internal/impl/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type Devbox struct {
pure bool
allowInsecureAdds bool
customProcessComposeFile string
OmitBinWrappersFromPath bool

// Possible TODO: hardcode this to stderr. Allowing the caller to specify the
// writer is error prone. Since it is almost always stderr, we should default
Expand Down Expand Up @@ -93,6 +94,7 @@ func Open(opts *devopt.Opts) (*Devbox, error) {
pure: opts.Pure,
customProcessComposeFile: opts.CustomProcessComposeFile,
allowInsecureAdds: opts.AllowInsecureAdds,
OmitBinWrappersFromPath: opts.OmitBinWrappersFromPath,
}

lock, err := lock.GetFile(box)
Expand Down Expand Up @@ -845,21 +847,17 @@ func (d *Devbox) computeNixEnv(ctx context.Context, usePrintDevEnvCache bool) (m
addEnvIfNotPreviouslySetByDevbox(env, pluginEnv)

env["PATH"] = JoinPathLists(
// Prepend the bin-wrappers directory to the PATH. This ensures that
// bin-wrappers execute before the unwrapped binaries.
filepath.Join(d.projectDir, plugin.WrapperBinPath),
// Adding profile bin path is a temporary hack. Some packages .e.g. curl
// don't export the correct bin in the package, instead they export
// as a propagated build input. This can be fixed in 2 ways:
// * have NixBins() recursively look for bins in propagated build inputs
// * Turn existing planners into flakes (i.e. php, haskell) and use the bins
// in the profile.
// Landau: I prefer option 2 because it doesn't require us to re-implement
// nix recursive bin lookup.
nix.ProfileBinPath(d.projectDir),
env["PATH"],
)

if !d.OmitBinWrappersFromPath {
env["PATH"] = JoinPathLists(
filepath.Join(d.projectDir, plugin.WrapperBinPath),
env["PATH"],
)
}

// Include env variables in devbox.json
configEnv := d.configEnvs(env)
addEnvIfNotPreviouslySetByDevbox(env, configEnv)
Expand Down
1 change: 1 addition & 0 deletions internal/impl/devopt/devboxopts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Opts struct {
Pure bool
IgnoreWarnings bool
CustomProcessComposeFile string
OmitBinWrappersFromPath bool
Writer io.Writer
}

Expand Down
6 changes: 5 additions & 1 deletion internal/impl/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,11 @@ func (d *Devbox) extraPackagesInProfile(ctx context.Context) ([]*nixprofile.NixP
if err != nil {
return nil, err
}
devboxInputs := d.InstallablePackages()
devboxInputs, err := d.AllInstallablePackages()
if err != nil {
return nil, err
}

if len(devboxInputs) == len(profileItems) {
// Optimization: skip comparison if number of packages are the same. This only works
// because we assume that all packages in `devbox.json` have just been added to the
Expand Down
33 changes: 16 additions & 17 deletions testscripts/languages/php.test.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
exec devbox run -- php index.php
exec devbox run php index.php
stdout 'done\n'

exec devbox rm php81Extensions.ds
exec devbox run -- php index.php
stdout 'ds extension is not enabled'
# temporarily disable rm test until we fix. It requires ensuring that package
# in profile matches the flake we are installing.
# For non-flakes, this involves comparing versions. For flakes we need to compare
# the content (or hash)

exec devbox add php81Extensions.ds
exec devbox run -- php index.php
stdout 'done\n'
# exec devbox rm php81Extensions.ds
# exec devbox run php index.php
# stdout 'ds extension is not enabled'

# exec devbox add php81Extensions.ds
# exec devbox run php index.php
# stdout 'done\n'

-- devbox.json --
{
"packages": [
"php81",
"php81Packages.composer",
"php81Extensions.ds"
],
"shell": {
"init_hook": null
},
"nixpkgs": {
"commit": "f80ac848e3d6f0c12c52758c0f25c10c97ca3b62"
}
"php81@latest",
"php81Packages.composer@latest",
"php81Extensions.ds@latest"
]
}

-- index.php --
Expand Down
1 change: 1 addition & 0 deletions testscripts/run/path.test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ stdout '/nix/var/nix/profiles/default/bin/nix'

# Relative paths in PATH are removed, others are cleaned
env PATH=./relative/path:/some//dirty/../clean/path:$PATH
env DEVBOX_INCLUDE_BIN_WRAPPERS_IN_PATH=1
exec devbox run echo '$PATH'
! stdout 'relative/path'
! stdout '/some//dirty/../clean/path'
Expand Down

0 comments on commit 0466f6a

Please sign in to comment.