mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-09 03:20:56 +00:00
Remove --no-dotenv flag, always load ~/.arc/.env, never load ./.env
The local .env loading was unnecessary since arc install writes all config to ~/.arc/.env. Simplifies dotenv behavior to unconditionally load from the home directory only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fc77a2fb24
commit
0d9b300aaf
4 changed files with 30 additions and 39 deletions
|
|
@ -9,12 +9,11 @@ These flags apply to all subcommands:
|
|||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--no-dotenv` | Skip loading `.env` file |
|
||||
| `--debug` | Enable DEBUG-level logging (default is INFO) |
|
||||
| `-h, --help` | Print help |
|
||||
| `-V, --version` | Print version |
|
||||
|
||||
Arc loads environment variables from `.env` in the current directory and `~/.arc/.env` (unless `--no-dotenv` is set).
|
||||
Arc loads environment variables from `~/.arc/.env`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -631,7 +631,6 @@ pub async fn run_with_args_and_client(
|
|||
}
|
||||
|
||||
pub async fn run() -> anyhow::Result<()> {
|
||||
let _ = dotenvy::dotenv();
|
||||
let cli = Cli::parse();
|
||||
let mut args = cli.args;
|
||||
args.apply_cli_defaults(None, None, None, None);
|
||||
|
|
|
|||
|
|
@ -11,10 +11,6 @@ use tracing::debug;
|
|||
#[derive(Parser)]
|
||||
#[command(name = "arc", version, long_version = arc_util::version::LONG_VERSION.as_str())]
|
||||
struct Cli {
|
||||
/// Skip loading .env file
|
||||
#[arg(long, global = true)]
|
||||
no_dotenv: bool,
|
||||
|
||||
/// Enable DEBUG-level logging (default is INFO)
|
||||
#[arg(long, global = true)]
|
||||
debug: bool,
|
||||
|
|
@ -176,11 +172,11 @@ async fn main_inner() -> Result<()> {
|
|||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
|
||||
let cli = Cli::parse();
|
||||
if !cli.no_dotenv {
|
||||
if let Some(home) = dirs::home_dir() {
|
||||
let _ = dotenvy::from_path(home.join(".arc").join(".env"));
|
||||
if let Some(home) = dirs::home_dir() {
|
||||
let env_path = home.join(".arc").join(".env");
|
||||
if dotenvy::from_path(&env_path).is_ok() {
|
||||
debug!(path = %env_path.display(), "Loaded environment file");
|
||||
}
|
||||
dotenvy::dotenv().ok();
|
||||
}
|
||||
|
||||
let command_name = match &cli.command {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@ fn arc() -> Command {
|
|||
Command::cargo_bin("arc").unwrap()
|
||||
}
|
||||
|
||||
/// Load .env into the process so subprocess inherits API keys
|
||||
/// even when current_dir is set to a tempdir.
|
||||
fn load_dotenv() {
|
||||
dotenvy::dotenv().ok();
|
||||
}
|
||||
|
||||
// == Models ===================================================================
|
||||
|
||||
#[test]
|
||||
|
|
@ -99,14 +93,7 @@ fn prompt_errors_without_prompt_text() {
|
|||
#[test]
|
||||
fn prompt_reads_from_stdin() {
|
||||
let result = arc()
|
||||
.args([
|
||||
"--no-dotenv",
|
||||
"llm",
|
||||
"prompt",
|
||||
"--no-stream",
|
||||
"-m",
|
||||
"test-model",
|
||||
])
|
||||
.args(["llm", "prompt", "--no-stream", "-m", "test-model"])
|
||||
.write_stdin("hello from stdin")
|
||||
.assert()
|
||||
.failure();
|
||||
|
|
@ -119,7 +106,6 @@ fn prompt_reads_from_stdin() {
|
|||
fn prompt_concatenates_stdin_and_arg() {
|
||||
let result = arc()
|
||||
.args([
|
||||
"--no-dotenv",
|
||||
"llm",
|
||||
"prompt",
|
||||
"--no-stream",
|
||||
|
|
@ -198,7 +184,6 @@ fn prompt_usage_shows_tokens() {
|
|||
fn prompt_schema_rejects_invalid_json() {
|
||||
arc()
|
||||
.args([
|
||||
"--no-dotenv",
|
||||
"llm",
|
||||
"prompt",
|
||||
"--no-stream",
|
||||
|
|
@ -320,11 +305,12 @@ fn exec_help_flag_prints_help() {
|
|||
|
||||
#[test]
|
||||
fn exec_missing_api_key_exits_with_error() {
|
||||
let tmp = std::env::temp_dir();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
arc()
|
||||
.args(["--no-dotenv", "exec", "test prompt"])
|
||||
.args(["exec", "test prompt"])
|
||||
.env_clear()
|
||||
.current_dir(&tmp)
|
||||
.env("HOME", tmp.path().to_str().unwrap())
|
||||
.current_dir(tmp.path())
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(predicate::str::contains("API key not set"));
|
||||
|
|
@ -343,7 +329,7 @@ fn exec_invalid_permissions_value() {
|
|||
#[test]
|
||||
#[ignore = "requires API key"]
|
||||
fn exec_creates_file() {
|
||||
load_dotenv();
|
||||
dotenvy::dotenv().ok();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
arc()
|
||||
.args([
|
||||
|
|
@ -373,7 +359,7 @@ fn exec_creates_file() {
|
|||
#[test]
|
||||
#[ignore = "requires API key"]
|
||||
fn exec_shell_command() {
|
||||
load_dotenv();
|
||||
dotenvy::dotenv().ok();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
arc()
|
||||
.args([
|
||||
|
|
@ -396,7 +382,7 @@ fn exec_shell_command() {
|
|||
#[test]
|
||||
#[ignore = "requires API key"]
|
||||
fn exec_read_only_blocks_write() {
|
||||
load_dotenv();
|
||||
dotenvy::dotenv().ok();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
arc()
|
||||
.args([
|
||||
|
|
@ -423,7 +409,7 @@ fn exec_read_only_blocks_write() {
|
|||
#[test]
|
||||
#[ignore = "requires API key"]
|
||||
fn exec_json_output_format() {
|
||||
load_dotenv();
|
||||
dotenvy::dotenv().ok();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
let output = arc()
|
||||
.args([
|
||||
|
|
@ -462,7 +448,7 @@ fn exec_json_output_format() {
|
|||
#[test]
|
||||
#[ignore = "requires API key"]
|
||||
fn exec_read_and_edit() {
|
||||
load_dotenv();
|
||||
dotenvy::dotenv().ok();
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
std::fs::write(tmp.path().join("data.txt"), "old content").expect("write data.txt");
|
||||
arc()
|
||||
|
|
@ -648,12 +634,23 @@ fn dry_run_legacy_tool() {
|
|||
.success();
|
||||
}
|
||||
|
||||
// == Dotenv ===================================================================
|
||||
|
||||
#[test]
|
||||
fn no_dotenv_flag_is_rejected() {
|
||||
arc()
|
||||
.args(["--no-dotenv", "doctor"])
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(predicate::str::contains("unexpected argument"));
|
||||
}
|
||||
|
||||
// == Doctor ===================================================================
|
||||
|
||||
#[test]
|
||||
fn doctor_runs_and_prints_header() {
|
||||
arc()
|
||||
.args(["--no-dotenv", "doctor"])
|
||||
.args(["doctor"])
|
||||
.env_clear()
|
||||
.assert()
|
||||
.stdout(predicate::str::contains("Arc Doctor"));
|
||||
|
|
@ -662,7 +659,7 @@ fn doctor_runs_and_prints_header() {
|
|||
#[test]
|
||||
fn doctor_verbose_runs_and_prints_header() {
|
||||
arc()
|
||||
.args(["--no-dotenv", "doctor", "-v"])
|
||||
.args(["doctor", "-v"])
|
||||
.env_clear()
|
||||
.assert()
|
||||
.stdout(predicate::str::contains("Arc Doctor"));
|
||||
|
|
@ -671,7 +668,7 @@ fn doctor_verbose_runs_and_prints_header() {
|
|||
#[test]
|
||||
fn doctor_no_color_when_no_color_set() {
|
||||
arc()
|
||||
.args(["--no-dotenv", "doctor"])
|
||||
.args(["doctor"])
|
||||
.env_clear()
|
||||
.env("NO_COLOR", "1")
|
||||
.assert()
|
||||
|
|
@ -681,7 +678,7 @@ fn doctor_no_color_when_no_color_set() {
|
|||
#[test]
|
||||
fn doctor_dry_run_flag_accepted() {
|
||||
arc()
|
||||
.args(["--no-dotenv", "doctor", "--dry-run"])
|
||||
.args(["doctor", "--dry-run"])
|
||||
.env_clear()
|
||||
.assert()
|
||||
.stdout(predicate::str::contains("Arc Doctor"));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue