Implement the shared automation CLI.
This commit is contained in:
188
crates/bds-cli/tests/process.rs
Normal file
188
crates/bds-cli/tests/process.rs
Normal file
@@ -0,0 +1,188 @@
|
||||
use std::process::Command;
|
||||
|
||||
fn cli(home: &std::path::Path, args: &[&str]) -> std::process::Output {
|
||||
Command::new(env!("CARGO_BIN_EXE_bds-cli"))
|
||||
.env("HOME", home)
|
||||
.args(args)
|
||||
.output()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn process_exit_codes_help_and_shared_state_roundtrip() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let home = root.path().join("home");
|
||||
let project = root.path().join("project");
|
||||
std::fs::create_dir_all(&home).unwrap();
|
||||
std::fs::create_dir_all(&project).unwrap();
|
||||
|
||||
let help = cli(&home, &["--help"]);
|
||||
assert!(help.status.success());
|
||||
assert!(String::from_utf8_lossy(&help.stdout).contains("rebuild"));
|
||||
|
||||
let invalid = cli(&home, &["not-a-command"]);
|
||||
assert_eq!(invalid.status.code(), Some(1));
|
||||
assert!(!invalid.stderr.is_empty());
|
||||
|
||||
let added = cli(
|
||||
&home,
|
||||
&[
|
||||
"project",
|
||||
"add",
|
||||
project.to_str().unwrap(),
|
||||
"--name",
|
||||
"Process Blog",
|
||||
],
|
||||
);
|
||||
assert!(
|
||||
added.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&added.stderr)
|
||||
);
|
||||
assert!(
|
||||
cli(&home, &["project", "switch", "process-blog"])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
|
||||
let created = Command::new(env!("CARGO_BIN_EXE_bds-cli"))
|
||||
.env("HOME", &home)
|
||||
.args(["--json", "post", "--stdin", "--no-translate"])
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.and_then(|mut child| {
|
||||
use std::io::Write as _;
|
||||
child
|
||||
.stdin
|
||||
.take()
|
||||
.unwrap()
|
||||
.write_all(br#"{"title":"Process post","content":"Body","language":"en"}"#)?;
|
||||
child.wait_with_output()
|
||||
})
|
||||
.unwrap();
|
||||
assert!(
|
||||
created.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&created.stderr)
|
||||
);
|
||||
let value: serde_json::Value = serde_json::from_slice(&created.stdout).unwrap();
|
||||
assert_eq!(value["ok"], true);
|
||||
assert_eq!(value["data"]["slug"], "process-post");
|
||||
|
||||
let get_missing = cli(&home, &["config", "get", "missing"]);
|
||||
assert_eq!(get_missing.status.code(), Some(1));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn process_upload_push_and_pull_dispatch_successfully() {
|
||||
use std::os::unix::fs::PermissionsExt as _;
|
||||
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let home = root.path().join("home");
|
||||
let project = root.path().join("project");
|
||||
let remote = root.path().join("remote.git");
|
||||
let peer = root.path().join("peer");
|
||||
let fake_bin = root.path().join("bin");
|
||||
for directory in [&home, &project, &fake_bin] {
|
||||
std::fs::create_dir_all(directory).unwrap();
|
||||
}
|
||||
assert!(
|
||||
cli(
|
||||
&home,
|
||||
&[
|
||||
"project",
|
||||
"add",
|
||||
project.to_str().unwrap(),
|
||||
"--name",
|
||||
"External Blog",
|
||||
],
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
cli(&home, &["project", "switch", "external-blog"])
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
|
||||
std::fs::write(
|
||||
project.join("meta/publishing.json"),
|
||||
r#"{"sshHost":"example.test","sshUser":"deploy","sshRemotePath":"/srv/blog","sshMode":"rsync"}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let rsync = fake_bin.join("rsync");
|
||||
std::fs::write(&rsync, "#!/bin/sh\nexit 0\n").unwrap();
|
||||
let mut permissions = std::fs::metadata(&rsync).unwrap().permissions();
|
||||
permissions.set_mode(0o755);
|
||||
std::fs::set_permissions(&rsync, permissions).unwrap();
|
||||
let upload = Command::new(env!("CARGO_BIN_EXE_bds-cli"))
|
||||
.env("HOME", &home)
|
||||
.env("PATH", &fake_bin)
|
||||
.env("SSH_AUTH_SOCK", root.path().join("agent.sock"))
|
||||
.arg("upload")
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(
|
||||
upload.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&upload.stderr)
|
||||
);
|
||||
|
||||
git(&project, &["init", "-b", "main"]);
|
||||
git(&project, &["config", "user.email", "cli@example.test"]);
|
||||
git(&project, &["config", "user.name", "CLI Test"]);
|
||||
git(&project, &["add", "."]);
|
||||
git(&project, &["commit", "-m", "Initial"]);
|
||||
git(root.path(), &["init", "--bare", remote.to_str().unwrap()]);
|
||||
git(
|
||||
&project,
|
||||
&["remote", "add", "origin", remote.to_str().unwrap()],
|
||||
);
|
||||
git(&project, &["push", "-u", "origin", "main"]);
|
||||
git(&remote, &["symbolic-ref", "HEAD", "refs/heads/main"]);
|
||||
|
||||
let pushed = cli(&home, &["push"]);
|
||||
assert!(
|
||||
pushed.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&pushed.stderr)
|
||||
);
|
||||
|
||||
git(
|
||||
root.path(),
|
||||
&["clone", remote.to_str().unwrap(), peer.to_str().unwrap()],
|
||||
);
|
||||
git(&peer, &["config", "user.email", "peer@example.test"]);
|
||||
git(&peer, &["config", "user.name", "Peer Test"]);
|
||||
std::fs::write(peer.join("remote-change.txt"), "change").unwrap();
|
||||
git(&peer, &["add", "remote-change.txt"]);
|
||||
git(&peer, &["commit", "-m", "Remote change"]);
|
||||
git(&peer, &["push"]);
|
||||
|
||||
let pulled = cli(&home, &["pull"]);
|
||||
assert!(
|
||||
pulled.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&pulled.stderr)
|
||||
);
|
||||
assert!(project.join("remote-change.txt").is_file());
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn git(cwd: &std::path::Path, args: &[&str]) {
|
||||
let output = Command::new("git")
|
||||
.current_dir(cwd)
|
||||
.args(args)
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"git {} failed:\n{}",
|
||||
args.join(" "),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user