Skip to content
This repository was archived by the owner on May 21, 2026. It is now read-only.

Commit a55b151

Browse files
committed
Load direnv directories by default, fix #14
1 parent 018d68c commit a55b151

3 files changed

Lines changed: 120 additions & 2 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,34 @@ QUICKENV_LOG=debug make
144144
# ...
145145
```
146146

147+
## Command Reference
148+
149+
```
150+
An unintrusive environment manager
151+
152+
Usage: quickenv <COMMAND>
153+
154+
Commands:
155+
reload Execute .envrc in the current or parent directory, and cache the new variables
156+
vars Dump out cached environment variables
157+
shim Create a new shim binary in ~/.quickenv/bin/
158+
unshim Remove a shim binary from ~/.quickenv/bin/
159+
exec Run a program with .envrc loaded without having to shim it
160+
which Determine which program quickenv's shim would launch under the hood
161+
help Print this message or the help of the given subcommand(s)
162+
163+
Options:
164+
-h, --help Print help
165+
-V, --version Print version
166+
167+
Environment variables:
168+
QUICKENV_LOG=debug to enable debug output (in shim commands as well)
169+
QUICKENV_LOG=error to silence everything but errors
170+
QUICKENV_NO_SHIM=1 to disable loading of .envrc, and effectively disable shims
171+
QUICKENV_SHIM_EXEC=1 to directly exec() shims instead of spawning them as subprocess. This can help with attaching debuggers.
172+
QUICKENV_NO_SHIM_WARNINGS=1 to disable nags about running 'quickenv shim' everytime a new binary is added
173+
QUICKENV_PRELUDE can be overridden to customize the shell code injected before executing each envrc. By default, quickenv loads ~/.config/direnv/lib/*.sh files and then runs 'eval "$(direnv stdlib)"' to mimic direnv's behavior.
174+
```
147175
## License
148176

149177
Licensed under `MIT`, see `LICENSE`.

src/main.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::core::resolve_envrc_context;
3333
QUICKENV_NO_SHIM=1 to disable loading of .envrc, and effectively disable shims
3434
QUICKENV_SHIM_EXEC=1 to directly exec() shims instead of spawning them as subprocess. This can help with attaching debuggers.
3535
QUICKENV_NO_SHIM_WARNINGS=1 to disable nags about running 'quickenv shim' everytime a new binary is added
36-
QUICKENV_PRELUDE='eval \"$(direnv stdlib)\"' can be overridden to something else to get rid of the direnv stdlib and therefore direnv dependency, or to inject additional code before executing each envrc.
36+
QUICKENV_PRELUDE can be overridden to customize the shell code injected before executing each envrc. By default, quickenv loads ~/.config/direnv/lib/*.sh files and then runs 'eval \"$(direnv stdlib)\"' to mimic direnv's behavior.
3737
"
3838
)]
3939
struct Args {
@@ -286,7 +286,19 @@ fn compute_envvars(quickenv_home: &Path) -> Result<(), Error> {
286286
};
287287

288288
let prelude = std::env::var("QUICKENV_PRELUDE")
289-
.unwrap_or_else(|_| r#"eval "$(direnv stdlib)""#.to_owned());
289+
.unwrap_or_else(|_| {
290+
// Load direnv lib files (mimicking direnv's default behavior)
291+
// and then load direnv stdlib
292+
let direnv_config_dir = std::env::var("XDG_CONFIG_HOME")
293+
.unwrap_or_else(|_| {
294+
std::env::var("HOME")
295+
.map(|home| format!("{home}/.config"))
296+
.unwrap_or_else(|_| "/tmp/.config".to_string())
297+
});
298+
format!(
299+
"for f in {direnv_config_dir}/direnv/lib/*.sh; do [ -r \"$f\" ] && . \"$f\"; done; eval \"$(direnv stdlib)\""
300+
)
301+
});
290302

291303
write!(
292304
temp_script,

tests/acceptance.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,3 +713,81 @@ sleep 1
713713

714714
Ok(())
715715
}
716+
717+
#[test]
718+
fn test_direnv_lib_loading() -> Result<(), Error> {
719+
let harness = setup()?;
720+
721+
// Create a fake direnv lib directory and file
722+
let direnv_lib_dir = harness.join(".config/direnv/lib");
723+
create_dir_all(&direnv_lib_dir)?;
724+
725+
// Create a lib file that exports a custom function and variable
726+
write(
727+
direnv_lib_dir.join("test_lib.sh"),
728+
r#"#!/bin/bash
729+
# Test direnv lib file
730+
export DIRENV_LIB_LOADED=true
731+
my_custom_function() {
732+
echo "custom function from direnv lib"
733+
}
734+
"#,
735+
)?;
736+
737+
// Create .envrc that uses the function and variable from the lib
738+
write(
739+
harness.join(".envrc"),
740+
r#"my_custom_function
741+
echo "DIRENV_LIB_LOADED is: $DIRENV_LIB_LOADED"
742+
export PATH=test_bin:$PATH
743+
"#,
744+
)?;
745+
746+
// Create a test binary
747+
create_dir_all(harness.join("test_bin"))?;
748+
write(
749+
harness.join("test_bin/hello"),
750+
"#!/bin/sh\necho hello from test bin",
751+
)?;
752+
set_executable(harness.join("test_bin/hello"))?;
753+
754+
// Set XDG_CONFIG_HOME to point to our test config
755+
let mut test_harness = harness;
756+
test_harness.set_var("XDG_CONFIG_HOME", test_harness.join(".config"));
757+
758+
// Test that lib loading works during reload
759+
assert_cmd!(test_harness, quickenv "reload", @r###"
760+
success: true
761+
exit_code: 0
762+
----- stdout -----
763+
custom function from direnv lib
764+
DIRENV_LIB_LOADED is: true
765+
766+
----- stderr -----
767+
[WARN quickenv] 1 unshimmed commands (1 new). Use 'quickenv shim' to make them available.
768+
Set QUICKENV_NO_SHIM_WARNINGS=1 to silence this message.
769+
"###);
770+
771+
// Test that lib loading works when executing shimmed commands
772+
assert_cmd!(test_harness, quickenv "shim" "hello", @r###"
773+
success: true
774+
exit_code: 0
775+
----- stdout -----
776+
777+
----- stderr -----
778+
Created 1 new shims in [scrubbed $HOME]/.quickenv/bin/.
779+
Use 'quickenv unshim <command>' to remove them again.
780+
"###);
781+
782+
// The environment should be loaded properly when running the shimmed command
783+
assert_cmd!(test_harness, hello, @r###"
784+
success: true
785+
exit_code: 0
786+
----- stdout -----
787+
hello from test bin
788+
789+
----- stderr -----
790+
"###);
791+
792+
Ok(())
793+
}

0 commit comments

Comments
 (0)