Skip to content

Commit

Permalink
feat: enhence dotenv (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden authored Oct 18, 2024
1 parent 7714274 commit 5ba3eda
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 23 deletions.
8 changes: 5 additions & 3 deletions src/argc_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use indexmap::IndexMap;

#[cfg(feature = "eval-bash")]
use crate::utils::{
argc_var_name, escape_shell_words, expand_dotenv, AFTER_HOOK, ARGC_REQUIRE_TOOLS, BEFORE_HOOK,
VARIABLE_PREFIX,
argc_var_name, escape_shell_words, AFTER_HOOK, ARGC_LOAD_DOTENV, ARGC_REQUIRE_TOOLS,
BEFORE_HOOK, VARIABLE_PREFIX,
};

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -109,7 +109,9 @@ impl ArgcValue {
}
}
ArgcValue::Dotenv(value) => {
list.push(expand_dotenv(value));
let value = escape_shell_words(value);
list.push(ARGC_LOAD_DOTENV.to_string());
list.push(format!("_argc_load_dotenv {value}"));
}
ArgcValue::RequireTools(tools) => {
require_tools = tools.to_vec();
Expand Down
13 changes: 7 additions & 6 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
command::Command,
param::{FlagOptionParam, Param, PositionalParam},
utils::{escape_shell_words, expand_dotenv, ARGC_REQUIRE_TOOLS},
utils::{escape_shell_words, ARGC_LOAD_DOTENV, ARGC_REQUIRE_TOOLS},
ChoiceValue, DefaultValue,
};
use anyhow::Result;
Expand Down Expand Up @@ -248,11 +248,6 @@ pub fn build(source: &str, root_name: &str, wrap_width: Option<usize>) -> Result

fn build_root(cmd: &Command, wrap_width: Option<usize>) -> String {
let command = build_command(cmd, wrap_width);
let dotenv = if let Some(value) = cmd.dotenv() {
format!("\n {}", expand_dotenv(value))
} else {
String::new()
};
let (before_hook, after_hook) = cmd.exist_hooks();
let before_hook = if before_hook {
"\n _argc_before"
Expand All @@ -266,6 +261,12 @@ fn build_root(cmd: &Command, wrap_width: Option<usize>) -> String {
util_fns.push_str(util_fn);
}
}
let dotenv = if let Some(value) = cmd.dotenv() {
util_fns.push_str(&format!("\n{ARGC_LOAD_DOTENV}\n"));
format!("\n _argc_load_dotenv {}", escape_shell_words(value))
} else {
String::new()
};
let require_tools = if command.contains("_argc_tools") {
util_fns.push_str(&format!("\n{ARGC_REQUIRE_TOOLS}\n"));
r#"
Expand Down
18 changes: 14 additions & 4 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pub mod navite;

use anyhow::Result;
use std::collections::HashMap;
use std::{collections::HashMap, env};

pub trait Runtime
where
Expand Down Expand Up @@ -65,9 +65,19 @@ where
continue;
}
if let Some((key, value)) = line.split_once('=') {
let key = key.trim().to_string();
let value = value.trim().to_string();
output.insert(key, value);
let env_name = key.trim().to_string();
let env_value = value.trim().to_string();
let env_value = if (env_value.starts_with('"') && env_value.ends_with('"'))
|| (env_value.starts_with('\'') && env_value.ends_with('\''))
{
&env_value[1..env_value.len() - 1]
} else {
&env_value
};

if env::var(&env_name).is_err() {
output.insert(env_name, env_value.to_string());
}
}
}
Some(output)
Expand Down
20 changes: 16 additions & 4 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,22 @@ pub const ARGC_REQUIRE_TOOLS: &str = r#"_argc_require_tools() {
}"#;

#[cfg(any(feature = "build", feature = "eval-bash"))]
pub fn expand_dotenv(value: &str) -> String {
let value = escape_shell_words(value);
format!("[ -f {value} ] && set -o allexport && . {value} && set +o allexport")
}
pub const ARGC_LOAD_DOTENV: &str = r#"_argc_load_dotenv() {
local env_file="$1" env_vars=""
if [[ -f "$env_file" ]]; then
while IFS='=' read -r key value; do
if [[ "$key" == $'#'* ]] || [[ -z "$key" ]]; then
continue
fi
if [[ -z "${!key+x}" ]]; then
env_vars="$env_vars $key=$value"
fi
done < <(cat "$env_file"; echo "")
if [[ -n "$env_vars" ]]; then
eval "export $env_vars"
fi
fi
}"#;

pub fn to_cobol_case(value: &str) -> String {
Converter::new()
Expand Down
20 changes: 17 additions & 3 deletions tests/snapshots/integration__meta__dotenv.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,26 @@ RUN
prog

# OUTPUT
[ -f .env ] && set -o allexport && . .env && set +o allexport
_argc_load_dotenv() {
local env_file="$1" env_vars=""
if [[ -f "$env_file" ]]; then
while IFS='=' read -r key value; do
if [[ "$key" == $'#'* ]] || [[ -z "$key" ]]; then
continue
fi
if [[ -z "${!key+x}" ]]; then
env_vars="$env_vars $key=$value"
fi
done < <(cat "$env_file"; echo "")
if [[ -n "$env_vars" ]]; then
eval "export $env_vars"
fi
fi
}
_argc_load_dotenv .env
argc__args=( prog )
argc__positionals=( )

# BUILD_OUTPUT
argc__args=([0]="prog")
argc__positionals=()


20 changes: 17 additions & 3 deletions tests/snapshots/integration__meta__dotenv_custom_path.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,26 @@ RUN
prog

# OUTPUT
[ -f .env.local ] && set -o allexport && . .env.local && set +o allexport
_argc_load_dotenv() {
local env_file="$1" env_vars=""
if [[ -f "$env_file" ]]; then
while IFS='=' read -r key value; do
if [[ "$key" == $'#'* ]] || [[ -z "$key" ]]; then
continue
fi
if [[ -z "${!key+x}" ]]; then
env_vars="$env_vars $key=$value"
fi
done < <(cat "$env_file"; echo "")
if [[ -n "$env_vars" ]]; then
eval "export $env_vars"
fi
fi
}
_argc_load_dotenv .env.local
argc__args=( prog )
argc__positionals=( )

# BUILD_OUTPUT
argc__args=([0]="prog")
argc__positionals=()


0 comments on commit 5ba3eda

Please sign in to comment.