Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add --envrc-dir flag to allow specifying location of direnv config#2629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
pstephan-geico-external wants to merge5 commits intojetify-com:main
base:main
Choose a base branch
Loading
frompstephan-geico-external:direnv-respect-config

Conversation

pstephan-geico-external

Summary

Fixes#2459 - devbox generate direnv does not respect --config

It seems that the previous mode of operation fordevbox generate direnv --config <some-dir> used--config to determine the location of the resulting.envrc file, rather than as the location of thedevbox.json file. But in some cases it is desired to be able to specify not only the location of not only the direnv.envrc file, but also the devbox config file. Or at least to be able to specify just the location of the devbox config with the.envrc being in the current directory.

To accomplish this, without breaking the current mode of operation, a new parameter is added,--envrc-dir, which specifies the location of the resulting.envrc file. For example, the commanddevbox generate direnv --envrc-dir ABC --config ABC/XYZ would createABC/.envrc and within that would be the commandeval "$(devbox generate direnv --print-envrc --config XYZ)"

Without the new--envrc-dir param, operation is the same as it was previously, even with the--config (which will be used to specify the location of the.envrc file, NOT the devbox config file,devbox.json.

How was it tested?

Several new tests have been created to cover cases with and without the new--envrc-dir param.

Community Contribution License

All community contributions in this pull request are licensed to the project
maintainers under the terms of the
Apache 2 License.

By creating this pull request, I represent that I have the right to license the
contributions to the project maintainers under the Apache 2 License as stated in
the
Community Contribution License.

Copy link

@darch-geico-externaldarch-geico-external left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think I only spotted one actual bug.

Copy link

@darch-geico-externaldarch-geico-external left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Obviously still needs review from an actual maintainer, but I don't see any other issues from here.

Copy link

@jguluartejguluarte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

LGTM

@LucilleHLucilleH requested a review fromCopilotJuly 1, 2025 19:12
Copy link
Contributor

@CopilotCopilotAI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Pull Request Overview

Adds a new--envrc-dir flag to thedevbox generate direnv command so users can specify where the.envrc file is written separately from the devbox config.
Key changes:

  • IntroduceEnvrcOpts to carry bothEnvrcDir andConfigDir through internal APIs
  • Update templates (envrc.tmpl,envrcContent.tmpl) to respect both flags
  • Extend CLI (boxcli/generate.go), backend logic (determineDirenvDirs), and tests to cover--envrc-dir behavior

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
testscripts/generate/*.test.txtAdded and updated shells scripts to validate new--envrc-dir flag
internal/devbox/generate/tmpl/envrcContent.tmplUpdated template to prefix files and include--config when set
internal/devbox/generate/tmpl/envrc.tmplAdjusted embeddedeval invocation to emit--config if needed
internal/devbox/generate/devcontainer_util.goRefactoredCreateEnvrc to takeEnvrcOpts and write toEnvrcDir
internal/devbox/devopt/devboxopts.goIntroducedEnvrcOpts struct embeddingEnvFlags
internal/devbox/devbox.goUpdatedGenerateEnvrcFile,PrintEnvrcContent, and related flows
internal/boxcli/generate.goRegistered--envrc-dir flag, wired intorunGenerateDirenvCmd
Comments suppressed due to low confidence (2)

internal/devbox/generate/tmpl/envrcContent.tmpl:1

  • [nitpick] The template variable.Dir is ambiguous; consider renaming it to.ConfigDir so its purpose is clearer in both templates.
{{define "DirPrefix"}}{{ if .Dir }}{{ .Dir }}/{{ end }}{{end}}

internal/devbox/devbox.go:558

  • [nitpick] Whenopts.EnvrcDir is empty, this prints"", which may confuse users. Consider special-casing the message to say "current directory" instead of empty quotes.
ux.Fsuccessf(d.stderr, "generated .envrc file in %q.\n", opts.EnvrcDir)

cmd.Context(), flags.force, generateOpts)
}

// Returns cononical paths for configDir and envrcDir. Both locations are relative to the current
Copy link
Preview

CopilotAIJul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Fix the typo 'cononical' to 'canonical' in the comment fordetermineDirenvDirs.

Suggested change
// Returnscononical paths for configDir and envrcDir. Both locations are relative to the current
// Returnscanonical paths for configDir and envrcDir. Both locations are relative to the current

Copilot uses AI. Check for mistakes.

@mikeland73mikeland73 self-requested a reviewJuly 1, 2025 20:39
Copy link
Contributor

@mikeland73mikeland73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is a cool feature!

Two main changes I think you should do:

  • --envrc-dir should not control/override--config. It should be independent.
  • Don't pre-compute relative path between the dirs. Keep existing path semantics and only compute the relative path when you need to actually pting out the.envrc

Comment on lines 164 to 167
"path to directory where the .envrc file should be generated. "+
"If not specified, the .envrc file will be generated in "+
"the current working directory.")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Should be:

"If not specified, the .envrc file will be generated in "+"the same directory as the devbox.json")

Since--config will determine where the .envrc file is created, which may not match the working directory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Maybe also clarify that if this flag is used, then we use relative path for--config

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Good Catch and good suggestion.

Comment on lines +330 to +334
// If no configDir is specified, it will be assumed to be in the same directory as the .envrc file
// which means we can just return an empty configDir.
if configDir == "" {
return "", envrcDir, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm not sure I agree with the semantics of this. --envrc-dir should dictate where the.envrc is created, not which config is used. The default for all devbox commands is the use the devbox.json in the current directory and if it doesn't exist, recursively check parent directories. I think we should preserve that.

In practice that means that using--envrc-dir and not usingconfigDir will use the "current' devbox project, but create the.envrc where specified.

Comment on lines +336 to +347
relativeConfigDir, err := filepath.Rel(envrcDir, configDir)
if err != nil {
return "", "", errors.Wrapf(err, "failed to determine relative path from %s to %s", envrcDir, configDir)
}

// If the relative path is ".", it means configDir is the same as envrcDir. Leaving it as "."
// will result in the .envrc containing "--config .", which is fine, but unnecessary and also
// a change from the previous behavior. So we will return an empty string for relativeConfigDir
// which will result in the .envrc file not containing the "--config" flag at all.
if relativeConfigDir == "." {
relativeConfigDir = ""
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

You're computing the relative path, and then joining again at the call site. Instead of precomputing the relative path, I think it would be simpler to do that when the .envrc is generated.

}

box, err := devbox.Open(&devopt.Opts{
Dir:flags.config.path,
Dir:filepath.Join(envrcDir, configDir),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

keep this asflags.config.path,


generateOpts := devopt.EnvrcOpts{
EnvrcDir: envrcDir,
ConfigDir: configDir,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

no need to supplyConfigDir since it is already supplied bydevopt.Opts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is also a relative path (but namedConfigDir) which I'm afraid would get really confusing later on.

}

// Determine the directories for .envrc and config
configDir, envrcDir, err := determineDirenvDirs(flags.config.path, flags.envrcDir)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I thinkdetermineDirenvDirs can be removed and just compute the relative path internally when generating the.envrc

}

t := template.Must(template.ParseFS(tmplFS, "tmpl/envrc.tmpl"))

// write content into file
return t.Execute(file, map[string]string{
"Flags": strings.Join(flags, " "),
"Dir": opts.ConfigDir,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Name thisConfigDir to reduce ambiguity.

Compute relative path here instead ofgenerate.go

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Make empty ifenvrcDir is not specified.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I did change the name to ConfigDir.

Comment on lines 1 to 4
{{define "DirPrefix"}}{{ if .Dir }}{{ .Dir }}/{{ end }}{{end}}
use_devbox() {
watch_file devbox.json devbox.lock
eval "$(devbox shellenv --init-hook --install --no-refresh-alias{{ if .EnvFlag }}{{ .EnvFlag }}{{ end }})"
watch_file{{template "DirPrefix" .}}devbox.json{{template "DirPrefix" .}}devbox.lock
eval "$(devbox shellenv --init-hook --install --no-refresh-alias{{ if .EnvFlag }}{{ .EnvFlag}}{{ end }} {{- if .Dir }}--config {{ .Dir -}}{{ end }})"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Templates are pretty hard to read. Ideally this is computed in Go code and just passed in. e.g.

watch_file {{ .RelativeDevboxJSONPath }} {{ .RelativeDevboxLockPath }}

You could do similar with--config flag.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@mikeland73, thanks for your feedback. I did incorporate a number of your comments. However, others relate to your intro comment:

  • --envrc-dir should not control/override--config. It should be independent.

The issue I was trying to address is that the current version incorrectly (in my opinion) uses--config to specify the location of the.envrc file when specified as part ofdevbox generate direnv. The change also allows a config file location to be specified that will be used withdirenv and the.envrc file. Thedevbox generate direnv command does not use the devbox config file, but needs to know where it can be found so that it can properly configure the.envrc file (by including the config file withdevbox generate direnv --print-envrc AND by including the config file with the output of that same command).

Before addressing your other comments, I wanted to respond to this concern as it may impact some of those other comments and we should probably resolve this concern first.

Comment on lines 164 to 167
"path to directory where the .envrc file should be generated. "+
"If not specified, the .envrc file will be generated in "+
"the current working directory.")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Good Catch and good suggestion.

}

t := template.Must(template.ParseFS(tmplFS, "tmpl/envrc.tmpl"))

// write content into file
return t.Execute(file, map[string]string{
"Flags": strings.Join(flags, " "),
"Dir": opts.ConfigDir,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I did change the name to ConfigDir.

@pstephan-geico-external
Copy link
Author

@mikeland73 thanks for your feedback. I did incorporate a number of your comments. However, others relate to your intro comment:

  • --envrc-dir should not control/override--config. It should be independent.

The issue I was trying to address is that the current version incorrectly (in my opinion) uses--config to specify the location of the.envrc file when specified as part ofdevbox generate direnv. The change also allows a config file location to be specified that will be used withdirenv and the.envrc file. Thedevbox generate direnv command does not use the devbox config file, but needs to know where it can be found so that it can properly configure the.envrc file (by including the config file withdevbox generate direnv --print-envrc AND by including the config file with the output of that same command).

@mikeland73
Copy link
Contributor

@mikeland73 thanks for your feedback. I did incorporate a number of your comments. However, others relate to your intro comment:

  • --envrc-dir should not control/override--config. It should be independent.

The issue I was trying to address is that the current version incorrectly (in my opinion) uses--config to specify the location of the.envrc file when specified as part ofdevbox generate direnv. The change also allows a config file location to be specified that will be used withdirenv and the.envrc file. Thedevbox generate direnv command does not use the devbox config file, but needs to know where it can be found so that it can properly configure the.envrc file (by including the config file withdevbox generate direnv --print-envrc AND by including the config file with the output of that same command).

TLDR:

I don't think we're that far apart. I mostly just want to simplify the logic ininternal/boxcli/generate.go and just pass the envrcDir down the stack. I also don't wantconfigDir to mean "relative path from envrc to config dir" since this is only relevant to.envrc file, but not the devbox itself. You should only compute it when generating the .envrc itself.

Longer:

I'm not sure I agree 100% that--config works incorrectly. Specifically,--config is a semi-global flag that runs a command using the context of a specific devbox.json. This means that the working directory becomes the directory where thedevbox.json resides. For example:

devbox run --config examples/development/php/latest ls

Will print out the content of the directory inexamples/development/php/latest.

I do thinkdevbox generate direnv is a bit different from most devbox commands, but it's not clear to me that creating.envrc in the working directory is strictly a better option (If I did, I would be OK with just changing the behavior of the existing flag).

That said, I like your solution of adding a new flag. I think it solves the edge case without making--config behave differently for a single command. With the new flag, I would expect--config to continue behaving the same way.

Specifically:

devbox generate direnv --config path/to/my/config --envrc-dir path/to/create/envrc

Would create a new.envrc file inpath/to/create/envrc and point to the devbox project inpath/to/my/config

You would need to figure out the relative path between them, but this is trivial (your code already does this).

What I don't totally understand is why when both flags are passed, you change the meaning of the config flag to be relative (from the envrc). This logic is needed when printing the .envrc, but outside of that context it is incorrect. In fact, you correct for this issue by rejoining paths:

box, err := devbox.Open(&devopt.Opts{Dir:         filepath.Join(envrcDir, configDir),

But at this point,configDir is a misleading variable name, since it's a relative path from the envrc.

Copy link
Contributor

@mikeland73mikeland73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The main issue in this PR isdetermineDirenvDirs. It should probably not exist, because:

  • it redefines the meaning of configDir
  • The logic is a bit weird (it computes relative path only in certain cases)
  • nit: It returns 3 values (we rarely do this in this codebase)

Related., we do not needConfigDir inEnvrcOpts becauseConfigDir is already known by the devbox struct.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

Copilot code reviewCopilotCopilot left review comments

@mikeland73mikeland73mikeland73 requested changes

@jguluartejguluartejguluarte approved these changes

@darch-geico-externaldarch-geico-externaldarch-geico-external approved these changes

Requested changes must be addressed to merge this pull request.

Assignees
No one assigned
Labels
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

devbox generate direnv does not respect --config
4 participants
@pstephan-geico-external@mikeland73@jguluarte@darch-geico-external

[8]ページ先頭

©2009-2025 Movatter.jp