@@ -16,7 +16,9 @@ reqwest = {workspace = true, features = ["blocking", "json"]}
|
||||
url.workspace = true
|
||||
semver.workspace = true
|
||||
conventional_commit_parser.workspace = true
|
||||
tempdir.workspace = true
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-test = {workspace = true, features = ["no-env-filter"]}
|
||||
pretty_assertions.workspace = true
|
@@ -10,6 +10,7 @@ impl VcsClient {
|
||||
pub fn new_noop() -> VcsClient {
|
||||
Self::Noop {}
|
||||
}
|
||||
|
||||
pub fn new_git(path: &Path) -> anyhow::Result<VcsClient> {
|
||||
if !path.to_path_buf().join(".git").exists() {
|
||||
anyhow::bail!("git directory not found in: {}", path.display().to_string())
|
||||
@@ -19,4 +20,57 @@ impl VcsClient {
|
||||
source: path.to_path_buf(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn checkout_branch(&self) -> anyhow::Result<()> {
|
||||
match self {
|
||||
VcsClient::Noop {} => {}
|
||||
VcsClient::Git { .. } => {
|
||||
if let Err(e) = self.exec_git(&["branch", "-D", "cuddle-please/release"]) {
|
||||
tracing::debug!("failed to cleaned up local branch for force-push, this may be because it didn't exist before running this command");
|
||||
}
|
||||
self.exec_git(&["checkout", "-b", "cuddle-please/release"])?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exec_git(&self, args: &[&str]) -> anyhow::Result<()> {
|
||||
match self {
|
||||
VcsClient::Noop {} => {}
|
||||
VcsClient::Git { source } => {
|
||||
let checkout_branch = std::process::Command::new("git")
|
||||
.current_dir(source.as_path())
|
||||
.args(args)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&checkout_branch.stdout)?;
|
||||
let stderr = std::str::from_utf8(&checkout_branch.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git {}", args.join(" "));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn commit_and_push(&self, version: impl Into<String>, dry_run: bool) -> anyhow::Result<()> {
|
||||
match self {
|
||||
VcsClient::Noop {} => {}
|
||||
VcsClient::Git { .. } => {
|
||||
self.exec_git(&["add", "."])?;
|
||||
self.exec_git(&[
|
||||
"commit",
|
||||
"-m",
|
||||
&format!("chore(release): {}", version.into()),
|
||||
])?;
|
||||
|
||||
tracing::trace!("git push -u -f origin cuddle-please/release");
|
||||
if !dry_run {
|
||||
self.exec_git(&["push", "-u", "-f", "origin", "cuddle-please/release"])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
182
crates/cuddle-please/tests/git.rs
Normal file
182
crates/cuddle-please/tests/git.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
use std::path::Path;
|
||||
|
||||
use cuddle_please::git_client::VcsClient;
|
||||
use pretty_assertions::assert_eq;
|
||||
use tracing_test::traced_test;
|
||||
|
||||
#[test]
|
||||
#[traced_test]
|
||||
fn exec_git_into_branch() {
|
||||
let tempdir = tempdir::TempDir::new("exec_git_into_branch").unwrap();
|
||||
|
||||
setup_git(tempdir.path()).unwrap();
|
||||
|
||||
add_commit(tempdir.path(), "first").unwrap();
|
||||
add_tag(tempdir.path(), "1.0.0").unwrap();
|
||||
|
||||
add_commit(tempdir.path(), "second").unwrap();
|
||||
add_tag(tempdir.path(), "1.0.1").unwrap();
|
||||
|
||||
let vcs = VcsClient::new_git(tempdir.path()).unwrap();
|
||||
vcs.checkout_branch().unwrap();
|
||||
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("branch")
|
||||
.current_dir(tempdir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
"* cuddle-please/release
|
||||
main
|
||||
",
|
||||
stdout
|
||||
);
|
||||
assert_eq!("", stderr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[traced_test]
|
||||
fn add_files_to_commit() {
|
||||
let tempdir = tempdir::TempDir::new("add_files_to_commit").unwrap();
|
||||
|
||||
setup_git(tempdir.path()).unwrap();
|
||||
|
||||
add_commit(tempdir.path(), "first").unwrap();
|
||||
add_tag(tempdir.path(), "1.0.0").unwrap();
|
||||
|
||||
let vcs = VcsClient::new_git(tempdir.path()).unwrap();
|
||||
vcs.checkout_branch().unwrap();
|
||||
|
||||
std::fs::File::create(tempdir.path().join("changelog")).unwrap();
|
||||
vcs.commit_and_push("with some file", true).unwrap();
|
||||
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("log")
|
||||
.current_dir(tempdir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
|
||||
assert!(stdout.contains("chore(release): with some file"));
|
||||
assert_eq!("", stderr);
|
||||
}
|
||||
#[test]
|
||||
#[traced_test]
|
||||
fn reset_branch() {
|
||||
let tempdir = tempdir::TempDir::new("add_files_to_commit").unwrap();
|
||||
|
||||
setup_git(tempdir.path()).unwrap();
|
||||
|
||||
add_commit(tempdir.path(), "first").unwrap();
|
||||
add_tag(tempdir.path(), "1.0.0").unwrap();
|
||||
|
||||
let vcs = VcsClient::new_git(tempdir.path()).unwrap();
|
||||
vcs.checkout_branch().unwrap();
|
||||
|
||||
std::fs::File::create(tempdir.path().join("changelog-first")).unwrap();
|
||||
vcs.commit_and_push("v1.0.0", true).unwrap();
|
||||
|
||||
exec_git(tempdir.path(), &["checkout", "main"]).unwrap();
|
||||
vcs.checkout_branch().unwrap();
|
||||
|
||||
std::fs::File::create(tempdir.path().join("changelog-second")).unwrap();
|
||||
vcs.commit_and_push("v1.0.1", true).unwrap();
|
||||
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("log")
|
||||
.current_dir(tempdir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
|
||||
assert!(stdout.contains("chore(release): v1.0.1"));
|
||||
assert!(!stdout.contains("chore(release): v1.0.0"));
|
||||
assert_eq!("", stderr);
|
||||
}
|
||||
|
||||
fn add_tag(path: &Path, arg: &str) -> anyhow::Result<()> {
|
||||
add_everything(path)?;
|
||||
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("tag")
|
||||
.arg("-a")
|
||||
.arg(arg)
|
||||
.arg("-m")
|
||||
.arg(arg)
|
||||
.current_dir(path)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout)?;
|
||||
let stderr = std::str::from_utf8(&output.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git init");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_commit(path: &Path, arg: &str) -> anyhow::Result<()> {
|
||||
std::fs::File::create(path.join(arg))?;
|
||||
|
||||
add_everything(path)?;
|
||||
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("commit")
|
||||
.arg("-m")
|
||||
.arg(arg)
|
||||
.current_dir(path)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout)?;
|
||||
let stderr = std::str::from_utf8(&output.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git init");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_everything(path: &Path) -> anyhow::Result<()> {
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("add")
|
||||
.arg(".")
|
||||
.current_dir(path)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout)?;
|
||||
let stderr = std::str::from_utf8(&output.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git add .");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_git(path: &Path) -> anyhow::Result<()> {
|
||||
let output = std::process::Command::new("git")
|
||||
.arg("init")
|
||||
.arg(".")
|
||||
.current_dir(path)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&output.stdout)?;
|
||||
let stderr = std::str::from_utf8(&output.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git init");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exec_git(path: &Path, args: &[&str]) -> anyhow::Result<()> {
|
||||
let checkout_branch = std::process::Command::new("git")
|
||||
.current_dir(path)
|
||||
.args(args)
|
||||
.output()?;
|
||||
|
||||
let stdout = std::str::from_utf8(&checkout_branch.stdout)?;
|
||||
let stderr = std::str::from_utf8(&checkout_branch.stderr)?;
|
||||
tracing::debug!(stdout = stdout, stderr = stderr, "git {}", args.join(" "));
|
||||
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user