diff --git a/README.md b/README.md index e5ef88e..80a4592 100644 --- a/README.md +++ b/README.md @@ -124,9 +124,11 @@ Apply environment variables defined in `[variables]` and propagate them to syste ```bash curator env # then, to update this shell: -eval "$(curator env --eval)" +eval "$(curator env --eval-only)" ``` +Use `curator env --eval-only` in shell init files if you want each shell to export the current `[variables]` values without touching `environment.d` or systemd/DBus. + ## Configuration ### inventory.toml @@ -243,7 +245,7 @@ PAGER = "less -R" Notes: - Values are imported into the user systemd and DBus environments during `curator switch` or `curator env`. -- To update a currently running shell, run `eval "$(curator env --eval)"` after applying. +- To update a currently running shell, run `eval "$(curator env --eval-only)"` after applying. - Later shell init files (e.g., `.bashrc`, `.zshrc`) can still override these values. #### `[dotfiles]` diff --git a/src/curator/cli.py b/src/curator/cli.py index 865745e..8afb969 100644 --- a/src/curator/cli.py +++ b/src/curator/cli.py @@ -1146,18 +1146,20 @@ def apply_inline_updates(entry_args: list[str], add: bool) -> None: log_success(f"Updated section [{section}] in {curator_toml}") -def env_command(eval_mode: bool = False) -> None: +def env_command(eval_only: bool = False) -> None: curator_dir, curator_toml, _, _ = get_paths() if not curator_toml.exists(): log_error("inventory.toml not found. Run 'curator init' first.") sys.exit(1) config = parse_config(curator_toml) - variables, removed_keys = apply_environment_variables( - config, curator_dir, quiet=eval_mode, propagate=True - ) + if eval_only: + env_home = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")).expanduser() + env_file = env_home / "environment.d" / "20-curator.conf" + existing_keys = _read_environment_file_keys(env_file) + variables = {k.strip(): str(v) for k, v in config.variables.items() if k.strip()} + removed_keys = existing_keys - set(variables) - if eval_mode: exports: list[str] = [] for key, value in sorted(variables.items()): exports.append(f"export {key}={_format_env_value(value)}") @@ -1167,8 +1169,9 @@ def env_command(eval_mode: bool = False) -> None: print("\n".join(exports)) return + apply_environment_variables(config, curator_dir, propagate=True) log_info("To update your current shell now, run:") - print(' eval "$(curator env --eval)"') + print(' eval "$(curator env --eval-only)"') def status_command() -> None: @@ -1290,9 +1293,9 @@ def build_parser() -> argparse.ArgumentParser: remove_parser.add_argument("entries", nargs="+", help="Entries in the form section:value") env_parser = subparsers.add_parser("env", help="Apply environment variables immediately") env_parser.add_argument( - "--eval", + "--eval-only", action="store_true", - help='Print export/unset statements for the current shell (use with: eval "$(curator env --eval)")', + help='Print export/unset statements for the current shell only (use with: eval "$(curator env --eval-only)")', ) subparsers.add_parser("status", help="Show current configuration status") subparsers.add_parser("help", help="Show help message") @@ -1316,7 +1319,7 @@ def main(argv: list[str] | None = None) -> None: elif args.command == "remove": apply_inline_updates(args.entries, add=False) elif args.command == "env": - env_command(eval_mode=args.eval) + env_command(eval_only=args.eval_only) elif args.command == "status": status_command() elif args.command == "help": diff --git a/tests/test_config.py b/tests/test_config.py index 265a561..abea4db 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -239,21 +239,24 @@ def test_env_command_eval_outputs_exports(tmp_path: Path, monkeypatch, capsys) - """ [variables] EDITOR = "nvim" -OLD = "1" """.strip() ) + env_home = tmp_path / "xdg" + env_dir = env_home / "environment.d" + env_dir.mkdir(parents=True, exist_ok=True) + env_conf = env_dir / "20-curator.conf" + env_conf.write_text("OLD=1\n") + monkeypatch.setenv("XDG_CONFIG_HOME", str(env_home)) def fake_get_paths(): return curator_dir, env_file, curator_dir / "last", curator_dir / "rollback" - def fake_apply_environment_variables(config, path, quiet=False, propagate=False): - assert quiet is True - assert propagate is True - return {"EDITOR": "nvim"}, {"OLD"} + def fail_apply_environment_variables(*_args, **_kwargs): + raise AssertionError("apply_environment_variables should not be called in eval-only mode") monkeypatch.setattr(cli, "get_paths", fake_get_paths) - monkeypatch.setattr(cli, "apply_environment_variables", fake_apply_environment_variables) + monkeypatch.setattr(cli, "apply_environment_variables", fail_apply_environment_variables) - cli.env_command(eval_mode=True) + cli.env_command(eval_only=True) out = capsys.readouterr().out.strip().splitlines() assert out == ["export EDITOR=nvim", "unset OLD"]