use callisto_graph::commands::{plan_version, VersionOptions};
use callisto_graph::infer::NoInference;
use callisto_graph::locate::IgnoreWalkLocator;
use callisto_graph::Workspace;
use callisto_model::{CommandError, CommandOutput, CommandRunner, PackageId, Severity};
use std::fs;
use std::path::Path;
struct NoopRunner;
impl CommandRunner for NoopRunner {
fn run(
&self,
_program: &str,
_args: &[&str],
_cwd: &Path,
) -> Result<CommandOutput, CommandError> {
Ok(CommandOutput {
exit_code: Some(0),
stdout: String::new(),
stderr: String::new(),
})
}
}
fn git_init_with_commit(root: &Path) {
for args in [
vec!["init", "-q"],
vec!["config", "user.email", "test@example.com"],
vec!["config", "user.name", "Test"],
] {
std::process::Command::new("git")
.args(&args)
.current_dir(root)
.output()
.expect("git command should run");
}
fs::write(root.join(".gitkeep"), "").unwrap();
for args in [vec!["add", "."], vec!["commit", "-q", "-m", "init"]] {
std::process::Command::new("git")
.args(&args)
.current_dir(root)
.output()
.expect("git command should run");
}
}
#[test]
fn test_plan_version_produces_correct_bumps_in_cascade() {
let tmp = tempfile::tempdir().unwrap();
let root = tmp.path();
git_init_with_commit(root);
fs::create_dir_all(root.join("pkg-core")).unwrap();
fs::write(
root.join("pkg-core/Cargo.toml"),
"[package]\nname = \"pkg-core\"\nversion = \"1.0.0\"\n",
)
.unwrap();
fs::create_dir_all(root.join("pkg-app")).unwrap();
fs::write(
root.join("pkg-app/Cargo.toml"),
"[package]\nname = \"pkg-app\"\nversion = \"1.0.0\"\n\n[dependencies]\npkg-core = \"1.0.0\"\n",
)
.unwrap();
fs::create_dir_all(root.join(".changeset")).unwrap();
fs::write(
root.join(".changeset/breaking-api.md"),
"---\n\"pkg-core\": major\n---\n\nBreaking API change.\n",
)
.unwrap();
let locator = IgnoreWalkLocator::new(root);
let runner = NoopRunner;
let ws = Workspace::load(root.to_path_buf(), &locator, &runner)
.expect("workspace should load from temp dir");
let inference = NoInference;
let opts = VersionOptions {
strict: false,
strict_graph: false,
allow_empty_changesets: true,
};
let plan = plan_version(&ws, &inference, &opts).expect("plan_version should succeed");
let pkg_core = PackageId::parse("pkg-core").unwrap();
let pkg_app = PackageId::parse("pkg-app").unwrap();
let bump_for = |id: &PackageId| plan.bumps.iter().find(|b| &b.package == id);
let core_bump = bump_for(&pkg_core).expect("pkg-core should have a planned bump");
assert_eq!(
core_bump.severity,
Severity::Major,
"pkg-core should receive a Major bump from the changeset"
);
let app_bump =
bump_for(&pkg_app).expect("pkg-app should receive a cascade bump from pkg-core's major");
assert!(
app_bump.severity != Severity::None,
"pkg-app cascade bump should be non-None, got {:?}",
app_bump.severity
);
}