pub mod common;
use common::{
assert_cmd, assert_cmd_capture, assert_ref, assert_ref_missing, exec_garden, garden_capture,
garden_exec, BareRepoFixture,
};
use garden::errors;
use garden::git;
use anyhow::Result;
use function_name::named;
use which::which;
#[test]
#[named]
fn init_adds_repository() -> Result<()> {
let fixture = common::BareRepoFixture::new(function_name!());
exec_garden(&["--chdir", &fixture.root(), "init"])?;
fixture.path("garden.yaml");
let pathbuf = fixture.pathbuf("garden.yaml");
let app_context = garden::model::ApplicationContext::from_path(&pathbuf)?;
let cfg = app_context.get_root_config();
assert_eq!(1, cfg.trees.len());
assert_eq!(function_name!(), cfg.trees[0].get_name());
assert_eq!("${GARDEN_CONFIG_DIR}", cfg.trees[0].get_path().get_expr());
Ok(())
}
#[test]
#[named]
fn grow_clone() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
])?;
let worktree = fixture.worktree("example/tree/repo");
assert_ref(&worktree, "origin/default");
assert_ref(&worktree, "origin/dev");
Ok(())
}
#[test]
#[named]
fn grow_clone_shallow() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/shallow",
])?;
let worktree = fixture.worktree("example/tree/shallow");
assert_ref(&worktree, "origin/default");
assert_ref(&worktree, "origin/dev");
let cmd = ["git", "rev-list", "HEAD"];
let output = assert_cmd_capture(&cmd, &worktree);
let lines = output.split('\n');
assert_eq!(
lines.count(),
1,
"git rev-list HEAD outputs only one commit "
);
Ok(())
}
#[test]
#[named]
fn grow_clone_single_branch() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/single-branch",
])?;
let worktree = fixture.worktree("example/tree/single-branch");
assert_ref(&worktree, "origin/default");
assert_ref_missing(&worktree, "origin/dev");
let cmd = ["git", "rev-list", "HEAD"];
let output = assert_cmd_capture(&cmd, &worktree);
let lines = output.split('\n');
assert_eq!(
lines.count(),
1,
"git rev-list HEAD outputs only one commit "
);
Ok(())
}
#[test]
#[named]
fn grow_branch_default() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/branches.yaml",
"grow",
"default",
"dev",
])?;
let worktree_default = fixture.worktree("default");
let worktree_dev = fixture.worktree("dev");
let cmd = ["git", "symbolic-ref", "--short", "HEAD"];
let output = assert_cmd_capture(&cmd, &worktree_default);
let lines = output.split('\n').collect::<Vec<&str>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0], "default");
let cmd = ["git", "symbolic-ref", "--short", "HEAD"];
let output = assert_cmd_capture(&cmd, &worktree_dev);
let lines = output.split('\n').collect::<Vec<&str>>();
assert_eq!(lines.len(), 1);
assert_eq!(lines[0], "dev");
assert_ref(&worktree_default, "origin/default");
assert_ref(&worktree_default, "origin/dev");
assert_ref(&worktree_dev, "origin/default");
assert_ref(&worktree_dev, "origin/dev");
Ok(())
}
#[test]
#[named]
fn grow_bare_repo() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/bare.yaml",
"grow",
"bare.git",
])?;
let bare_repo = fixture.path("bare.git");
assert_ref(&bare_repo, "default");
assert_ref(&bare_repo, "dev");
let cmd = ["git", "config", "--bool", "core.bare"];
let output = assert_cmd_capture(&cmd, &bare_repo);
assert_eq!(output.as_str(), "true");
Ok(())
}
#[test]
#[named]
fn grow_bare_repo_with_config() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/bare.yaml",
"grow",
"bare",
])?;
let bare_repo = fixture.path("bare");
let repo = std::path::PathBuf::from(&bare_repo);
assert!(repo.exists());
assert_ref(&bare_repo, "default");
assert_ref(&bare_repo, "dev");
let cmd = ["git", "config", "core.bare"];
let output = assert_cmd_capture(&cmd, &bare_repo);
assert_eq!(output.as_str(), "true");
Ok(())
}
#[test]
#[named]
fn grow_remotes() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
])?;
let worktree = fixture.path("example/tree/repo");
let cmd = ["git", "config", "remote.origin.url"];
let output = assert_cmd_capture(&cmd, &worktree);
assert!(
output.ends_with("/repos/example.git"),
"{} does not end with {}",
output,
"/repos/example.git"
);
let cmd = ["git", "config", "remote.publish.url"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("git@github.com:user/example.git", output);
let cmd = ["git", "config", "remote.publish.tagopt"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("--no-tags", output);
Ok(())
}
#[test]
#[named]
fn grow_symlinks() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
"link",
"example/link",
])?;
let repo = fixture.pathbuf("example/tree/repo/.git");
assert!(repo.exists());
let link = fixture.pathbuf("link");
assert!(link.exists(), "{link:?} must exist");
assert!(link.read_link().is_ok());
let target = link.read_link().unwrap();
assert_eq!("example/tree/repo", target.to_string_lossy());
let link = fixture.pathbuf("example/link");
assert!(link.exists(), "{link:?} does not exist");
assert!(link.read_link().is_ok());
let target = link.read_link().unwrap();
assert_eq!("tree/repo", target.to_string_lossy());
Ok(())
}
#[test]
#[named]
fn grow_gitconfig() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
])?;
let worktree = fixture.path("example/tree/repo");
let cmd = ["git", "config", "remote.origin.annex-ignore"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("true", output);
let cmd = ["git", "config", "user.name"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("A U Thor", output);
let cmd = ["git", "config", "user.email"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("author@example.com", output);
Ok(())
}
#[test]
#[named]
fn grow_gitconfig_append_value() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
])?;
let worktree = fixture.path("example/tree/repo");
let cmd = ["git", "config", "--get-all", "remote.origin.pushurl"];
let output = assert_cmd_capture(&cmd, &worktree);
assert_eq!("url1\nurl2", output);
Ok(())
}
#[test]
#[named]
fn grow_branches_for_clone() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/branches.yaml",
"grow",
"local",
])?;
let local_repo = fixture.path("local");
let cmd = ["git", "symbolic-ref", "HEAD"];
let output = assert_cmd_capture(&cmd, &local_repo);
assert_eq!("refs/heads/local", output);
let cmd_dev = ["git", "rev-parse", "local"];
let cmd_local = ["git", "rev-parse", "dev"];
let output_local = assert_cmd_capture(&cmd_local, &local_repo);
let output_dev = assert_cmd_capture(&cmd_dev, &local_repo);
assert_eq!(output_dev, output_local);
let cmd = ["git", "config", "branch.dev.remote"];
let output = assert_cmd_capture(&cmd, &local_repo);
assert_eq!("origin", output);
let cmd = ["git", "config", "branch.local.remote"];
let output = assert_cmd_capture(&cmd, &local_repo);
assert_eq!("origin", output);
let cmd = ["git", "config", "branch.dev.merge"];
let output = assert_cmd_capture(&cmd, &local_repo);
assert_eq!("refs/heads/dev", output);
let cmd = ["git", "config", "branch.local.merge"];
let output = assert_cmd_capture(&cmd, &local_repo);
assert_eq!("refs/heads/default", output);
Ok(())
}
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "s390x",
target_arch = "x86"
)))]
#[test]
#[named]
fn grow_worktree_and_parent() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/worktree.yaml",
"grow",
"dev",
])?;
let worktree_default = fixture.worktree("default");
let worktree_dev = fixture.worktree("dev");
assert_ref(&worktree_default, "default");
assert_ref(&worktree_dev, "dev");
let output = garden_capture(&[
"--chdir",
&fixture.root(),
"--config",
"tests/data/worktree.yaml",
"echo",
"dev",
"--",
"hello",
]);
assert_eq!("dev hello", output);
let output = garden_capture(&[
"--chdir",
&fixture.root(),
"--config",
"tests/data/worktree.yaml",
"echo",
"default",
"--",
"hello",
]);
assert_eq!("default hello", output);
Ok(())
}
#[test]
#[named]
fn grow_default_remote_name() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/default-remote-name",
])?;
let repo = fixture.worktree("example/tree/default-remote");
let cmd_main = ["git", "rev-parse", "default"];
let cmd_custom_main = ["git", "rev-parse", "custom/default"];
let main_commit_id = assert_cmd_capture(&cmd_main, &repo);
let custom_main_commit_id = assert_cmd_capture(&cmd_custom_main, &repo);
assert_eq!(main_commit_id, custom_main_commit_id);
let cmd = ["git", "config", "checkout.defaultRemoteName"];
let output = assert_cmd_capture(&cmd, &repo);
assert_eq!("custom", output);
let cmd = ["git", "config", "remote.origin.url"];
let output = assert_cmd_capture(&cmd, &repo);
assert_eq!("git://git.example.org/example.git", output);
Ok(())
}
#[test]
#[named]
fn grow_default_remote_url() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/default-remote-url",
])?;
let repo = fixture.worktree("example/tree/default-remote");
let cmd_main = ["git", "rev-parse", "default"];
let cmd_custom_main = ["git", "rev-parse", "custom/default"];
let main_commit_id = assert_cmd_capture(&cmd_main, &repo);
let custom_main_commit_id = assert_cmd_capture(&cmd_custom_main, &repo);
assert_eq!(main_commit_id, custom_main_commit_id);
let cmd = ["git", "config", "checkout.defaultRemoteName"];
let output = assert_cmd_capture(&cmd, &repo);
assert_eq!("custom", output);
Ok(())
}
#[test]
#[named]
fn grow_branch_from_non_default_remote() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/branches.yaml",
"grow",
"custom-remote",
])?;
let repo = fixture.worktree("custom-remote");
let command = ["git", "symbolic-ref", "HEAD"];
let ref_name = assert_cmd_capture(&command, &repo);
assert_eq!(ref_name, "refs/heads/custom-dev");
let cmd_local_branch = ["git", "rev-parse", "custom-dev"];
let cmd_upstream_branch = ["git", "rev-parse", "custom/dev"];
let local_id = assert_cmd_capture(&cmd_local_branch, &repo);
let upstream_id = assert_cmd_capture(&cmd_upstream_branch, &repo);
assert_eq!(local_id, upstream_id);
let cmd_upstream_name = ["git", "config", "branch.custom-dev.remote"];
let upstream_name = assert_cmd_capture(&cmd_upstream_name, &repo);
assert_eq!(upstream_name, "custom");
let cmd_upstream_name = ["git", "config", "branch.custom-dev.merge"];
let upstream_name = assert_cmd_capture(&cmd_upstream_name, &repo);
assert_eq!(upstream_name, "refs/heads/dev");
let cmd_local_branch = ["git", "rev-parse", "extra-default"];
let cmd_upstream_branch = ["git", "rev-parse", "extra/default"];
let local_id = assert_cmd_capture(&cmd_local_branch, &repo);
let upstream_id = assert_cmd_capture(&cmd_upstream_branch, &repo);
assert_eq!(local_id, upstream_id);
let cmd_upstream_name = ["git", "config", "branch.extra-default.remote"];
let upstream_name = assert_cmd_capture(&cmd_upstream_name, &repo);
assert_eq!(upstream_name, "extra");
let cmd_upstream_name = ["git", "config", "branch.extra-default.merge"];
let upstream_name = assert_cmd_capture(&cmd_upstream_name, &repo);
assert_eq!(upstream_name, "refs/heads/default");
Ok(())
}
#[test]
fn cmd_dry_run() {
let output = garden_capture(&["--quiet", "--chdir", "tests/data", "basename"]);
assert_eq!(output, "data");
let output = garden_capture(&["--quiet", "--chdir", "tests/data", "basename", "--dry-run"]);
assert_eq!(output, "");
}
#[test]
fn cmd_override_variables() {
let output = garden_capture(&["--quiet", "--chdir", "tests/data/commands", "echo-name"]);
assert_eq!(output, "default-name");
let output = garden_capture(&[
"--chdir",
"tests/data/commands",
"--quiet",
"--define",
"name=test",
"echo-name",
]);
assert_eq!(output, "test");
let output = garden_capture(&[
"--chdir",
"tests/data/commands",
"echo-name",
"--quiet",
"--define",
"name=test",
]);
assert_eq!(output, "test");
}
#[test]
fn eval_garden_config_dir() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CONFIG_DIR}",
]);
let expect = "/tests/data";
assert!(
output.ends_with(expect),
"GARDEN_ROOT ({output}) does not end with {expect}"
);
}
#[test]
#[named]
fn eval_garden_root() {
let fixture = BareRepoFixture::new(function_name!());
let output = garden_capture(&[
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_ROOT}",
]);
let expect = "/tests/tmp/eval_garden_root";
assert!(
output.ends_with(expect),
"GARDEN_ROOT ({output}) does not end with {expect}"
);
let output = garden_capture(&[
"--chdir",
&fixture.root(),
"--config",
"tests/data/default.yaml",
"eval",
"${GARDEN_ROOT}",
]);
let expect = "/tests/data";
assert!(
output.ends_with(expect),
"GARDEN_ROOT ({output}) does not end with {expect}"
);
}
#[test]
fn eval_builtin_command_variables() {
let expect = "";
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CMD_VERBOSE}",
]);
assert_eq!(output, expect);
let expect = "-v";
let output = garden_capture(&[
"--verbose",
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CMD_VERBOSE}",
]);
assert_eq!(output, expect);
let expect = "-vv";
let output = garden_capture(&[
"-vv",
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CMD_VERBOSE}",
]);
assert_eq!(output, expect);
let expect = "";
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CMD_QUIET}",
]);
assert_eq!(output, expect);
let expect = "--quiet";
let output = garden_capture(&[
"--quiet",
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_CMD_QUIET}",
]);
assert_eq!(output, expect);
}
#[test]
fn eval_builtin_command_variables_in_subcommand() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"echo-quiet-verbose",
"-v",
]);
let expect = "quiet=\nverbose=-v";
assert_eq!(output, expect);
let output = garden_capture(&[
"--verbose",
"--config",
"tests/data/garden.yaml",
"echo-quiet-verbose",
"--verbose",
"--quiet",
]);
let expect = "quiet=--quiet\nverbose=-vv";
assert_eq!(output, expect);
let output = garden_capture(&[
"--verbose",
"--config",
"tests/data/garden.yaml",
"cmd",
"-vv",
".",
"echo-quiet-verbose",
]);
let expect = "quiet=\nverbose=-vvv";
assert_eq!(output, expect);
}
#[test]
fn eval_override_variables() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--define",
"tree_value=test",
"eval",
"${tree_value}",
"current",
]);
assert_eq!(output, "test");
let output = garden_capture(&[
"--config",
"tests/data/variables.yaml",
"--define",
"var_0=test",
"eval",
"${var_0}",
]);
assert_eq!(output, "test");
let output = garden_capture(&[
"--config",
"tests/data/variables.yaml",
"eval",
"--define",
"var_0=test",
"${var_0}",
]);
assert_eq!(output, "test");
}
#[test]
fn eval_override_expressions() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--define",
"value=${tree_value}",
"eval",
"${value}",
"current",
]);
assert_eq!(output, "tree");
}
#[test]
fn eval_default_config_dir() {
let output = garden_capture(&[
"--config",
"tests/data/config/garden.yaml",
"eval",
"${GARDEN_ROOT}",
]);
assert!(output.ends_with("/tests/data/config"));
let output = garden_capture(&[
"--config",
"tests/data/config/garden.yaml",
"exec",
"current",
"pwd",
]);
assert!(output.ends_with("/tests/data/config"));
}
#[test]
fn eval_environment_tree_names() {
let expect = "trees/prebuilt/env/value";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_VALUE}",
"trees/prebuilt",
]);
assert_eq!(expect, actual);
let expect = "graft/grafted-env/env/value";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_VALUE}",
"graft::grafted-env",
]);
assert_eq!(expect, actual);
let expect = "garden/env:graft/grafted-env/env/value:trees/prebuilt/env/value";
let actual = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_ENV_VALUE}",
"trees/prebuilt",
"garden/env",
]);
assert_eq!(expect, actual);
let expect = "garden/env:graft/grafted-env/env/value:trees/prebuilt/env/value";
let actual = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_ENV_VALUE}",
"graft::grafted-env",
"garden/env",
]);
assert_eq!(expect, actual);
}
#[test]
fn eval_environment_tree_paths() {
let expect = "/tests/data/trees/prebuilt";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_PATH}",
"trees/prebuilt",
]);
assert!(
actual.ends_with(expect),
"{actual} does not end with {expect}"
);
assert_eq!(1, actual.split(':').count());
let expect = "/tests/data/grafted-env";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_PATH}",
"graft::grafted-env",
]);
assert!(
actual.ends_with(expect),
"{actual} does not end with {expect}"
);
assert_eq!(1, actual.split(':').count());
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_PATH}",
"trees/prebuilt",
"garden/env",
]);
let actual_items: Vec<&str> = actual.split(':').collect();
assert_eq!(actual_items.len(), 3);
assert_eq!(actual_items[0], "garden/path");
let expect = "/tests/data/grafted-env";
assert!(
actual_items[1].ends_with(expect),
"{} does not end with {expect}",
actual_items[1]
);
let expect = "/tests/data/trees/prebuilt";
assert!(
actual_items[2].ends_with(expect),
"{} does not end with {expect}",
actual_items[2]
);
let actual = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ENV_PATH}",
"graft::grafted-env",
"garden/env",
]);
let actual_items: Vec<&str> = actual.split(':').collect();
assert_eq!(actual_items.len(), 3);
assert_eq!(actual_items[0], "garden/path");
let expect = "/tests/data/grafted-env";
assert!(
actual_items[1].ends_with(expect),
"{} does not end with {expect}",
actual_items[1]
);
let expect = "/tests/data/trees/prebuilt";
assert!(
actual_items[2].ends_with(expect),
"{} does not end with {expect}",
actual_items[2]
);
}
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "s390x",
target_arch = "x86"
)))]
#[test]
#[named]
fn git_worktree_details() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
let details = git::worktree_details(&fixture.pathbuf("repos/example.git"))?;
assert_eq!(details.branch, ""); assert_eq!(details.tree_type, garden::model::GitTreeType::Bare);
let cmd = ["git", "init", "--quiet", "tree"];
assert_cmd(&cmd, &fixture.root());
let cmd = ["git", "symbolic-ref", "HEAD", "refs/heads/branch"];
assert_cmd(&cmd, &fixture.path("tree"));
let details = git::worktree_details(&fixture.pathbuf("tree"))?;
assert_eq!(details.branch, "branch");
assert_eq!(details.tree_type, garden::model::GitTreeType::Tree);
let cmd = ["git", "clone", "--quiet", "repos/example.git", "parent"];
assert_cmd(&cmd, &fixture.root());
let details = git::worktree_details(&fixture.pathbuf("parent"))?;
assert_eq!(details.branch, "default");
assert_eq!(details.tree_type, garden::model::GitTreeType::Tree);
let cmd = [
"git",
"worktree",
"add",
"--track",
"-B",
"dev",
"../child",
"origin/dev",
];
assert_cmd(&cmd, &fixture.path("parent"));
let details = git::worktree_details(&fixture.pathbuf("parent"))?;
assert_eq!(details.branch, "default");
assert_eq!(details.tree_type, garden::model::GitTreeType::Parent);
let parent_path = garden::path::abspath(&fixture.pathbuf("parent"));
let details = git::worktree_details(&fixture.pathbuf("child"))?;
assert_eq!(details.branch, "dev");
assert_eq!(
details.tree_type,
garden::model::GitTreeType::Worktree(parent_path)
);
Ok(())
}
#[test]
fn eval_root_with_root() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--root",
"tests/tmp",
"eval",
"${GARDEN_ROOT}",
]);
assert!(output.ends_with("/tests/tmp"));
let path = std::path::PathBuf::from(&output);
assert!(path.exists());
assert!(path.is_absolute());
}
#[test]
fn eval_config_dir_with_chdir_and_root() {
let output = garden_capture(&[
"--chdir",
"tests/tmp",
"--config",
"tests/data/garden.yaml",
"--root",
"tests/tmp",
"eval",
"${GARDEN_CONFIG_DIR}",
]);
assert!(output.ends_with("/tests/data"));
let path = std::path::PathBuf::from(&output);
assert!(path.exists());
assert!(path.is_absolute());
}
#[test]
fn eval_exec_pwd_with_root_and_chdir() {
let output = garden_capture(&[
"--chdir",
"tests/tmp",
"--config",
"tests/data/garden.yaml",
"--root",
"tests/tmp",
"eval",
"$ pwd",
]);
assert!(output.ends_with("/tests/tmp"));
let path = std::path::PathBuf::from(&output);
assert!(path.exists());
assert!(path.is_absolute());
}
#[test]
fn eval_root_with_root_and_chdir() {
let output = garden_capture(&[
"--chdir",
"tests/tmp",
"--config",
"tests/data/garden.yaml",
"--root",
"tests/tmp",
"eval",
"${GARDEN_ROOT}",
]);
assert!(output.ends_with("/tests/tmp"));
let path = std::path::PathBuf::from(&output);
assert!(path.exists());
assert!(path.is_absolute());
}
#[test]
fn eval_grafted_variable_with_namespace() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${graft::variable}",
]);
assert_eq!(output, "graft value");
}
#[test]
fn eval_grafted_variable_at_global_scope() {
let output = garden_capture(&["--config", "tests/data/garden.yaml", "eval", "${variable}"]);
assert_eq!(output, "global graft value");
}
#[test]
fn eval_graft_variable_at_tree_scope() {
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"eval",
"${variable}",
"trees/prebuilt",
]);
assert_eq!(output, "prebuilt graft value");
}
#[test]
fn eval_graft_variables_with_circular_dependencies() {
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${circular-variable}",
"graft::current",
]);
assert_eq!(output, "graft-root-");
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${root-variable}",
"root-tree",
]);
assert_eq!(output, "root-tree-graft-");
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${graft::circular-variable}",
"root-tree",
]);
assert_eq!(output, "graft-root-tree-");
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${graft::circular-variable}",
]);
assert_eq!(output, "graft-root-");
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${root-variable}",
]);
assert_eq!(output, "root-graft-");
}
#[test]
fn eval_environment_variables_with_circular_dependencies() {
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${ENV_CIRCULAR_VARIABLE}",
"graft::current",
]);
assert_eq!(output, "graft/current/variables/graft/current/");
let output = garden_capture(&[
"--config",
"tests/data/circular.yaml",
"eval",
"${ENV_CIRCULAR_VARIABLE}",
"root-tree",
]);
assert_eq!(output, "root-tree/variables/root-tree/");
}
#[test]
fn eval_required_variables() {
let (status, out, err) = garden_exec(&[
"--config",
"tests/data/variables-required.yaml",
"eval",
"${required-value}",
]);
assert_eq!(status, errors::EX_DATAERR);
assert_eq!(out, "");
assert_eq!(err, "error: required variable 'required-value' is empty");
let (status, out, err) = garden_exec(&[
"--quiet",
"--config",
"tests/data/variables-required.yaml",
"example",
]);
assert_eq!(status, errors::EX_DATAERR);
assert_eq!(out, "");
assert_eq!(err, "error: required variable 'required-value' is empty");
let (status, out, err) = garden_exec(&[
"--quiet",
"--config",
"tests/data/variables-required.yaml",
"example2",
]);
assert_eq!(status, errors::EX_DATAERR);
assert_eq!(out, "default-value =");
assert_eq!(err, "error: required variable 'required-value' is empty");
}
#[test]
#[named]
fn git_branches() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
let root = fixture.root();
fixture.assert_worktree(&root);
let cmd = ["git", "branch", "abc"];
assert_cmd(&cmd, &root);
let cmd = ["git", "branch", "xyz"];
assert_cmd(&cmd, &root);
let branches = git::branches(&fixture.root_pathbuf());
assert_eq!(branches.len(), 3); assert!(branches.contains(&"abc".to_string()));
assert!(branches.contains(&"xyz".to_string()));
Ok(())
}
#[test]
fn eval_grafted_builtin_variables() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_CONFIG_DIR}",
"graft::prebuilt",
]);
let expect = "/tests/data/grafts";
assert!(
output.ends_with(expect),
"Grafted GARDEN_CONFIG_DIR ({output}) must use the grafted {expect} path"
);
let output = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${TREE_PATH}",
"graft::prebuilt",
]);
let expect = "/tests/data/trees/prebuilt";
assert!(
output.ends_with(expect),
"Grafted TREE_PATH ({output}) must be in {expect}"
);
let output = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${TREE_PATH}",
"graft-no-root::tree",
]);
let expect = "/tests/data/grafts/trees/tree";
assert!(
output.ends_with(expect),
"Grafted TREE_PATH ({output}) must be in {expect}"
);
let output = garden_capture(&[
"--chdir",
"tests/data",
"eval",
"${GARDEN_ROOT}",
"graft::prebuilt",
]);
let expect = "/tests/data";
assert!(
output.ends_with(expect),
"Grafted GARDEN_ROOT ({output}) must use {expect} from the current directory"
);
let output = garden_capture(&[
"--chdir",
"tests",
"--config",
"tests/data/garden.yaml",
"eval",
"${GARDEN_ROOT}",
"graft::prebuilt",
]);
let expect = "/tests";
assert!(
output.ends_with(expect),
"Grafted GARDEN_ROOT ({output}) must use {expect} from the current directory"
);
}
#[test]
fn cmd_dash_dash_arguments() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"echo-dir",
"echo-args",
"echo-dir",
"echo-args",
"--",
"d",
"e",
"f",
"--",
"g",
"h",
"i",
]);
let msg = format!(
"data\ngarden\n{}",
"arguments -- a b c -- d e f -- g h i -- x y z"
);
assert_eq!(output, format!("{msg}\n{msg}"));
}
#[test]
fn cmd_dash_dash_arguments_custom() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"echo-args",
".",
".",
"--",
"d",
"e",
"f",
"--",
"g",
"h",
"i",
]);
let msg = "garden\narguments -- a b c -- d e f -- g h i -- x y z";
assert_eq!(format!("{msg}\n{msg}"), output);
}
#[test]
fn cmd_default_tree() {
let expect = "hello world";
let actual = garden_capture(&[
"--config",
"tests/data/commands/garden.yaml",
"echo",
"--",
"hello",
"world",
]);
assert_eq!(expect, actual);
let expect = "/tests/data/commands";
let actual = garden_capture(&["--config", "tests/data/commands/garden.yaml", "pwd"]);
assert!(
actual.ends_with(expect),
"pwd output ({actual}) must be in {expect}"
);
let expect = "/tests/data/commands";
let actual = garden_capture(&[
"--config",
"tests/data/commands/garden.yaml",
"eval",
"${GARDEN_ROOT}",
]);
assert!(
actual.ends_with(expect),
"GARDEN_ROOT ({actual}) must be in {expect}"
);
let expect = "/tests/data/commands";
let actual = garden_capture(&[
"--config",
"tests/data/commands/garden.yaml",
"eval",
"${GARDEN_CONFIG_DIR}",
]);
assert!(
actual.ends_with(expect),
"GARDEN_CONFIG_DIR ({actual}) must be in {expect}"
);
let expect = "/tests/data/commands";
let actual = garden_capture(&[
"--config",
"tests/data/commands/garden.yaml",
"eval",
"${TREE_PATH}",
".",
]);
assert!(
actual.ends_with(expect),
"TREE_PATH ({actual}) must be in {expect}"
);
let expect = ".";
let actual = garden_capture(&[
"--config",
"tests/data/commands/garden.yaml",
"eval",
"${TREE_NAME}",
".",
]);
assert_eq!(expect, actual);
}
#[test]
fn cmd_dot_default_no_args() {
let output = garden_capture(&["--quiet", "--chdir", "tests/data", "echo-dir"]);
assert_eq!("data", output);
}
#[test]
fn cmd_dot_default_no_args_echo() {
let output = garden_capture(&["--quiet", "--chdir", "tests/data", "echo-args"]);
let msg = "garden\narguments -- a b c -- -- x y z";
assert_eq!(msg, output);
}
#[test]
fn cmd_dot_default_double_dash() {
let output = garden_capture(&["--quiet", "--chdir", "tests/data", "echo-args", "--"]);
let msg = "garden\narguments -- a b c -- -- x y z";
assert_eq!(msg, output);
}
#[test]
fn cmd_dot_default_double_dash_args() {
let output = garden_capture(&[
"--quiet",
"--chdir",
"tests/data",
"echo-args",
"--",
"d",
"e",
"f",
"--",
"g",
"h",
"i",
]);
let msg = "garden\narguments -- a b c -- d e f -- g h i -- x y z";
assert_eq!(msg, output);
}
#[test]
fn cmd_breadth_first_and_depth_first() {
let expect = "tree1\ntree2\nx1\nx2";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"--breadth-first",
"trees",
"tree-name",
"tree-var",
]);
assert_eq!(expect, actual);
let expect = "tree1\nx1\ntree2\nx2";
let actual = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"trees",
"tree-name",
"tree-var",
]);
assert_eq!(expect, actual);
}
#[test]
fn cmd_no_errexit() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"error-command",
]);
assert_eq!(output, "ok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"--no-errexit",
".",
"error-command",
]);
assert_eq!(output, "ok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--define",
"garden.shell-errexit=false",
"--quiet",
"error-command",
]);
assert_eq!(output, "ok\nafter error");
}
#[test]
fn cmd_no_errexit_for_command_lists() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"error-command-list",
]);
assert_eq!(output, "ok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"--no-errexit",
".",
"error-command-list",
]);
assert_eq!(output, "ok\nafter error");
}
#[test]
fn cmd_keep_going_and_no_errexit() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command",
"tree1",
"tree2",
]);
assert_eq!(output, "ok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command",
"--no-errexit",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command",
"--keep-going",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command",
"--keep-going",
"--no-errexit",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nafter error\nok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command-list",
"tree1",
"tree2",
]);
assert_eq!(output, "ok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command-list",
"--no-errexit",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command-list",
"--keep-going",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"error-command-list",
"--keep-going",
"--no-errexit",
"tree1",
"tree2",
]);
assert_eq!(output, "ok\nafter error\nok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"tree*",
"error-command",
"error-command-list",
]);
assert_eq!(output, "ok");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"--no-errexit",
"tree*",
"error-command",
"error-command-list",
]);
assert_eq!(output, "ok\nafter error");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
"--keep-going",
"tree*",
"error-command",
"error-command-list",
]);
assert_eq!(output, "ok\nok\nok\nok");
}
#[test]
fn cmd_pre_and_post_commands() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"echo-pre-and-post",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 4);
assert_eq!(output, "pre\ncmd\ndata\npost");
let output = garden_capture(&["--chdir", "tests/data", "--quiet", "echo-pre-and-post"]);
let output_len = output.lines().count();
assert_eq!(output_len, 4);
assert_eq!(output, "pre\ncmd\ndata\npost");
}
#[test]
fn cmd_pre_and_post_nested_commands() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"echo-pre-and-post-nested",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 6);
assert_eq!(output, "pre\ncmd\ndata\npost\nnested\nfini");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"echo-pre-and-post-nested",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 6);
assert_eq!(output, "pre\ncmd\ndata\npost\nnested\nfini");
}
#[test]
fn cmd_shell_with_custom_command() {
if which("zsh").is_err() {
return;
}
let output = garden_capture(&[
"--config",
"tests/data/shell/custom.yaml",
"--quiet",
"shell-words",
]);
assert_eq!(output, "a b c");
let output = garden_capture(&[
"--config",
"tests/data/shell/custom.yaml",
"--define",
"garden.shell=zsh -o shwordsplit -c",
"--quiet",
"shell-words",
]);
assert_eq!(output, "a\nb\nc");
}
#[test]
fn cmd_exec_group_with_grafted_trees() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"exec",
"grafted-group",
"pwd",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 2);
for line in output.lines() {
assert!(line.ends_with("/tests/data/trees/prebuilt"));
}
}
#[test]
fn cmd_exec_garden_with_grafted_trees() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"exec",
"grafted-garden",
"pwd",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 2);
for line in output.lines() {
assert!(line.ends_with("/tests/data/trees/prebuilt"));
}
}
#[test]
fn cmd_exec_grafted_group() {
let output = garden_capture(&[
"--quiet",
"--chdir",
"tests/data",
"exec",
"graft::prebuilt-group",
"pwd",
]);
let output_len = output.lines().count();
assert_eq!(output_len, 2);
for line in output.lines() {
assert!(line.ends_with("/tests/data/trees/prebuilt"));
}
}
#[test]
fn cmd_garden_discovery() {
let expect = "/tests/data";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees/prebuilt",
"--config",
"default.yaml",
"eval",
"${GARDEN_CONFIG_DIR}",
]);
assert!(
actual.ends_with(expect),
"GARDEN_CONFIG_DIR ({actual}) should be in {expect}"
);
let expect = "/tests/data";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees/prebuilt",
"--config",
"default.yaml",
"eval",
"${GARDEN_ROOT}",
]);
assert!(
actual.ends_with(expect),
"GARDEN_ROOT ({actual}) should be in {expect}"
);
let expect = "/tests/data/trees/prebuilt";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees/prebuilt",
"eval",
"${GARDEN_ROOT}",
]);
assert!(
actual.ends_with(expect),
"GARDEN_ROOT ({actual}) should be in {expect}"
);
let expect = "/tests/data/trees/prebuilt";
let actual = garden_capture(&[
"--root",
"${GARDEN_CONFIG_DIR}",
"--chdir",
"tests/data/trees/prebuilt",
"eval",
"${TREE_PATH}",
".",
]);
assert!(
actual.ends_with(expect),
"TREE_PATH ({actual}) should be in {expect}"
);
let expect = "/tests/data/trees/prebuilt";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees/prebuilt",
"--config",
"default.yaml",
"eval",
"${TREE_PATH}",
".",
]);
assert!(
actual.ends_with(expect),
"TREE_PATH ({actual}) should be in {expect}"
);
let expect = "prebuilt";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees/prebuilt",
"--config",
"default.yaml",
"eval",
"${TREE_NAME}",
".",
]);
assert_eq!(expect, actual);
let expect = "/tests/data";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees",
"--config",
"default.yaml",
"eval",
"${TREE_PATH}",
".",
]);
assert!(
actual.ends_with(expect),
"TREE_PATH ({actual}) should be in {expect}"
);
let expect = "current";
let actual = garden_capture(&[
"--chdir",
"tests/data/trees",
"--config",
"default.yaml",
"eval",
"${TREE_NAME}",
".",
]);
assert_eq!(expect, actual);
}
#[test]
fn cmd_custom_filtered_trees() {
let expect = "current\nprebuilt";
let actual = garden_capture(&["--config", "tests/data/default.yaml", "name", "*"]);
assert_eq!(expect, actual);
let expect = "current";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"name",
"--trees",
"cur*",
"*",
]);
assert_eq!(expect, actual);
let expect = "prebuilt";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"name",
"--trees",
"pre*",
"*",
]);
assert_eq!(expect, actual);
let expect = "current\nprebuilt";
let actual = garden_capture(&["--config", "tests/data/default.yaml", "cmd", "*", "name"]);
assert_eq!(expect, actual);
let expect = "current";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"cmd",
"--trees",
"cur*",
"*",
"name",
]);
assert_eq!(expect, actual);
let expect = "prebuilt";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"cmd",
"--trees",
"pre*",
"*",
"name",
]);
assert_eq!(expect, actual);
}
#[test]
fn cmd_exec_filtered_trees() {
let actual = garden_capture(&["--config", "tests/data/default.yaml", "exec", "*", "pwd"]);
assert_eq!(actual.lines().count(), 2);
let expect = "/tests/data";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"exec",
"--trees",
"cur*",
"*",
"pwd",
]);
assert_eq!(actual.lines().count(), 1);
assert!(actual.ends_with(expect));
let expect = "/tests/data/trees/prebuilt";
let actual = garden_capture(&[
"--config",
"tests/data/default.yaml",
"exec",
"--trees",
"pre*",
"*",
"pwd",
]);
assert_eq!(actual.lines().count(), 1);
assert!(actual.ends_with(expect));
}
#[test]
fn cmd_shell_variables() {
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"echo-variable",
"--",
"test",
"value",
]);
assert_eq!(output, "garden test shell value expr");
let output = garden_capture(&[
"--chdir",
"tests/data",
"--quiet",
"cmd",
".",
"echo-escaped",
"--",
"test",
"value",
]);
assert_eq!(output, "test array value");
}
#[test]
fn cmd_zsh_shell_wordsplit() {
if which("zsh").is_err() {
return;
}
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--define",
"garden.shell=zsh",
"--quiet",
"echo-wordsplit-variable",
]);
assert_eq!(output, "a\nb\nc");
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--define",
"garden.shell=zsh",
"--define",
"garden.shell-wordsplit=false",
"--quiet",
"echo-wordsplit-variable",
]);
assert_eq!(output, "a b c");
let output = garden_capture(&[
"--config",
"tests/data/garden.yaml",
"--define",
"garden.shell=zsh",
"--quiet",
"echo-wordsplit-variable",
"--no-wordsplit",
]);
assert_eq!(output, "a b c");
}
#[test]
fn cmd_custom_shell() {
let output = garden_capture(&[
"--quiet",
"--config",
"tests/data/shell/custom.yaml",
"echo-shell",
]);
assert_eq!(output, "hello\nworld");
}
#[test]
fn cmd_custom_force_run() {
let output = garden_capture(&[
"--quiet",
"--config",
"tests/data/default.yaml",
"name",
"missing",
]);
assert_eq!(output, "");
let output = garden_capture(&[
"--quiet",
"--config",
"tests/data/default.yaml",
"name",
"--force",
"missing",
]);
assert_eq!(output, "missing");
}
#[test]
#[named]
fn cmd_prune_depth() -> Result<()> {
let fixture = BareRepoFixture::new(function_name!());
exec_garden(&[
"--verbose",
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"grow",
"example/tree",
])?;
let example_path = fixture.pathbuf("example");
let mut example_tree_path = example_path.clone();
example_tree_path.push("tree");
assert!(example_tree_path.exists(), "example/tree must exist");
let cmd = ["git", "init", "--quiet", "example/unknown"];
assert_cmd(&cmd, &fixture.root());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"example",
])?;
let mut example_unknown_path = example_path;
example_unknown_path.push("unknown");
assert!(example_tree_path.exists(), "example/tree must exist");
assert!(
example_unknown_path.exists(),
"example/unknown must exist (dry-run)"
);
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"example",
])?;
assert!(example_tree_path.exists(), "example/tree must be retained");
assert!(
!example_unknown_path.exists(),
"example/unknown must be removed"
);
assert_cmd(
&["git", "init", "--quiet", "level0-unknown"],
&fixture.root(),
);
assert_cmd(
&["git", "init", "--quiet", "level1/unknown"],
&fixture.root(),
);
assert_cmd(
&["git", "init", "--quiet", "level1/level2/unknown"],
&fixture.root(),
);
assert_cmd(
&["git", "init", "--quiet", "level1/level2/level3/unknown"],
&fixture.root(),
);
let level0_unknown_path = fixture.pathbuf("level0-unknown");
let level1_path = fixture.pathbuf("level1"); let mut level2_path = level1_path.clone();
level2_path.push("level2"); let mut level3_path = level2_path.clone();
level3_path.push("level3"); let mut level1_unknown_path = level1_path.clone();
level1_unknown_path.push("unknown"); let mut level2_unknown_path = level2_path.clone();
level2_unknown_path.push("unknown"); let mut level3_unknown_path = level3_path.clone();
level3_unknown_path.push("unknown");
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level3_path.exists());
assert!(level0_unknown_path.exists());
assert!(level1_unknown_path.exists());
assert!(level2_unknown_path.exists());
assert!(level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"--exact-depth",
"1",
])?;
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level3_path.exists());
assert!(level0_unknown_path.exists());
assert!(!level1_unknown_path.exists()); assert!(level2_unknown_path.exists());
assert!(level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"--max-depth",
"0",
])?;
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level3_path.exists());
assert!(
!level0_unknown_path.exists(),
"level0-unknown must be removed"
);
assert!(level2_unknown_path.exists());
assert!(level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"bogus-filter",
])?;
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level3_path.exists());
assert!(level2_unknown_path.exists());
assert!(level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"--min-depth",
"4",
])?;
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level3_path.exists());
assert!(level2_unknown_path.exists());
assert!(level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"--min-depth",
"3",
])?;
assert!(level1_path.exists());
assert!(level2_path.exists());
assert!(level2_unknown_path.exists());
assert!(!level3_path.exists());
assert!(!level3_unknown_path.exists());
exec_garden(&[
"--verbose",
"--chdir",
&fixture.root(),
"--config",
"tests/data/garden.yaml",
"prune",
"--no-prompt",
"--rm",
"level1",
])?;
assert!(!level1_path.exists());
assert!(!level2_path.exists());
assert!(!level1_unknown_path.exists());
assert!(!level2_unknown_path.exists());
Ok(())
}
#[test]
fn cmd_parallel_commands() {
let expect = "a\na\nz\nz";
let actual = garden_capture(&[
"--chdir",
"tests/data/parallel",
"--define",
"garden.tree-branches=false",
"exec",
"--quiet",
"--jobs=0",
"all",
"sh",
"-c",
"echo a; sleep 0.1; echo z",
]);
assert_eq!(expect, actual);
let actual = garden_capture(&[
"--chdir",
"tests/data/parallel",
"--define",
"garden.tree-branches=false",
"echo-values",
"--quiet",
"all",
"-j",
]);
assert_eq!(expect, actual);
}