feat(direnv): allow direnv to detect environment variables (#6196)

This commit is contained in:
Nick Conway 2024-12-27 05:25:15 -05:00 committed by GitHub
parent 7ead2b55eb
commit 45937166c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 20 deletions

View File

@ -359,6 +359,9 @@
"default": {
"allowed_msg": "allowed",
"denied_msg": "denied",
"detect_env_vars": [
"DIRENV_FILE"
],
"detect_extensions": [],
"detect_files": [
".envrc"
@ -2868,6 +2871,15 @@
"type": "string"
}
},
"detect_env_vars": {
"default": [
"DIRENV_FILE"
],
"type": "array",
"items": {
"type": "string"
}
},
"detect_files": {
"default": [
".envrc"

View File

@ -1227,20 +1227,21 @@ The `direnv` module shows the status of the current rc file if one is present. T
### Options
| Option | Default | Description |
| ------------------- | -------------------------------------- | ----------------------------------------------------- |
| `format` | `'[$symbol$loaded/$allowed]($style) '` | The format for the module. |
| `symbol` | `'direnv '` | The symbol used before displaying the direnv context. |
| `style` | `'bold orange'` | The style for the module. |
| `disabled` | `true` | Disables the `direnv` module. |
| `detect_extensions` | `[]` | Which extensions should trigger this module. |
| `detect_files` | `['.envrc']` | Which filenames should trigger this module. |
| `detect_folders` | `[]` | Which folders should trigger this module. |
| `allowed_msg` | `'allowed'` | The message displayed when an rc file is allowed. |
| `not_allowed_msg` | `'not allowed'` | The message displayed when an rc file is not_allowed. |
| `denied_msg` | `'denied'` | The message displayed when an rc file is denied. |
| `loaded_msg` | `'loaded'` | The message displayed when an rc file is loaded. |
| `unloaded_msg` | `'not loaded'` | The message displayed when an rc file is not loaded. |
| Option | Default | Description |
| ------------------- | -------------------------------------- | ------------------------------------------------------- |
| `format` | `'[$symbol$loaded/$allowed]($style) '` | The format for the module. |
| `symbol` | `'direnv '` | The symbol used before displaying the direnv context. |
| `style` | `'bold orange'` | The style for the module. |
| `disabled` | `true` | Disables the `direnv` module. |
| `detect_extensions` | `[]` | Which extensions should trigger this module. |
| `detect_files` | `['.envrc']` | Which filenames should trigger this module. |
| `detect_folders` | `[]` | Which folders should trigger this module. |
| `detect_env_vars` | `['DIRENV_FILE']` | Which environment variables should trigger this module. |
| `allowed_msg` | `'allowed'` | The message displayed when an rc file is allowed. |
| `not_allowed_msg` | `'not allowed'` | The message displayed when an rc file is not_allowed. |
| `denied_msg` | `'denied'` | The message displayed when an rc file is denied. |
| `loaded_msg` | `'loaded'` | The message displayed when an rc file is loaded. |
| `unloaded_msg` | `'not loaded'` | The message displayed when an rc file is not loaded. |
### Variables

View File

@ -13,6 +13,7 @@ pub struct DirenvConfig<'a> {
pub style: &'a str,
pub disabled: bool,
pub detect_extensions: Vec<&'a str>,
pub detect_env_vars: Vec<&'a str>,
pub detect_files: Vec<&'a str>,
pub detect_folders: Vec<&'a str>,
pub allowed_msg: &'a str,
@ -30,6 +31,7 @@ impl<'a> Default for DirenvConfig<'a> {
style: "bold bright-yellow",
disabled: true,
detect_extensions: vec![],
detect_env_vars: vec!["DIRENV_FILE"],
detect_files: vec![".envrc"],
detect_folders: vec![],
allowed_msg: "allowed",

View File

@ -13,14 +13,16 @@ use serde::Deserialize;
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("direnv");
let config = DirenvConfig::try_load(module.config);
let has_detected_env_var = context.detect_env_vars(&config.detect_env_vars);
let direnv_applies = !config.disabled
&& context
.try_begin_scan()?
.set_extensions(&config.detect_extensions)
.set_files(&config.detect_files)
.set_folders(&config.detect_folders)
.is_match();
&& (has_detected_env_var
|| context
.try_begin_scan()?
.set_extensions(&config.detect_extensions)
.set_files(&config.detect_files)
.set_folders(&config.detect_folders)
.is_match());
if !direnv_applies {
return None;
@ -338,6 +340,40 @@ mod tests {
dir.close()
}
#[test]
fn folder_with_loaded_rc_file_in_subdirectory() -> io::Result<()> {
let dir = tempfile::tempdir()?;
let rc_path = dir.path().join(".envrc");
let sub_dir_path = dir.path().join("sub_dir");
std::fs::File::create(rc_path)?.sync_all()?;
std::fs::DirBuilder::new()
.recursive(true)
.create(&sub_dir_path)?;
let actual = ModuleRenderer::new("direnv")
.config(toml::toml! {
[direnv]
disabled = false
})
.path(&sub_dir_path)
.env("DIRENV_FILE", "file")
.cmd(
"direnv status --json",
Some(CommandOutput {
stdout: status_cmd_output_with_rc_json(dir.path(), 0, 0),
stderr: String::default(),
}),
)
.collect();
let expected = Some(format!(
"{} ",
Color::LightYellow.bold().paint("direnv loaded/allowed")
));
assert_eq!(expected, actual);
dir.close()
}
#[test]
fn folder_with_loaded_and_denied_rc_file_pre_2_33() -> io::Result<()> {
let dir = tempfile::tempdir()?;
let rc_path = dir.path().join(".envrc");