aboutsummaryrefslogtreecommitdiffstats
path: root/xtask
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-06-04 14:15:51 -0500
committerToby Vincent <tobyv13@gmail.com>2023-06-04 14:21:18 -0500
commitae8dd8c6e5c419f91b9a9ca4e270862b18c5c599 (patch)
treecdba9e0ddb78f4c6e09b514b7682629ee489b219 /xtask
parentc6e8c15b39781ce48cd3f0d829ab5c6574ccd01b (diff)
build: improve ergonomics of version replace
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/release.rs98
-rw-r--r--xtask/src/release/bump.rs (renamed from xtask/src/release/version.rs)148
2 files changed, 115 insertions, 131 deletions
diff --git a/xtask/src/release.rs b/xtask/src/release.rs
index 8bf4444..acb8888 100644
--- a/xtask/src/release.rs
+++ b/xtask/src/release.rs
@@ -4,9 +4,9 @@ use anyhow::Result;
use clap::{Args, Subcommand};
use semver::Version;
-use self::version::{Bump, Level, Replacement};
+use self::bump::{Bump, Level};
-mod version;
+mod bump;
#[derive(Debug, Clone, Args)]
pub struct Release {
@@ -15,7 +15,7 @@ pub struct Release {
/// Level of version bump version.
#[arg(global = true, required = false)]
- level: version::Level,
+ level: bump::Level,
/// Options passed to git commit.
#[arg(global = true, last = true)]
@@ -42,7 +42,7 @@ pub enum Step {
/// Bump version in package files and commit changes.
Bump {
#[arg(from_global)]
- level: version::Level,
+ level: bump::Level,
},
/// Make a release commit.
@@ -54,7 +54,7 @@ pub enum Step {
/// Create git tag for release.
Tag {
#[arg(from_global)]
- level: version::Level,
+ level: bump::Level,
},
}
@@ -85,54 +85,50 @@ impl Step {
pub fn bump(level: Level) -> Result<Bump> {
let mut bump = Bump::from(level);
- bump.bump_file("README.md", &[Replacement::Version])?;
- bump.bump_file("pkg/archlinux/projectr/PKGBUILD", &[Replacement::Version])?;
- bump.bump_file(
- "pkg/archlinux/projectr-bin/PKGBUILD",
- &[Replacement::Version],
- )?;
-
- let stdout = std::process::Command::new("git")
- .arg("describe")
- .arg("--long")
- .arg("--abbrev=7")
- .output()?
- .stdout;
- let pkgver = std::str::from_utf8(&stdout)?
- .trim()
- .trim_start_matches('v')
- .replacen("-g", ".g", 1)
- .replacen('-', "-r", 1)
- .replace('-', ".");
-
- bump.bump_file(
- "pkg/archlinux/projectr-git/PKGBUILD",
- &[Replacement::FindLine(
- |l| l.starts_with("pkgver="),
- format!("pkgver={pkgver}"),
- )],
- )?;
-
- bump.bump_file(
- "CHANGELOG.md",
- &[
- Replacement::Append(
- "## [Unreleased]".to_string(),
- format!(
- "\n## [{}] - {}",
- bump.next,
- chrono::Utc::now().format("%Y-%m-%d")
+ bump.bump_file("Cargo.toml", bump::replace_cargo)?;
+ bump.bump_file("README.md", bump::replace)?;
+ bump.bump_file("pkg/archlinux/projectr/PKGBUILD", bump::replace)?;
+ bump.bump_file("pkg/archlinux/projectr-bin/PKGBUILD", bump::replace)?;
+ bump.bump_file("pkg/archlinux/projectr-git/PKGBUILD", |buf, _| {
+ let stdout = std::process::Command::new("git")
+ .arg("describe")
+ .arg("--long")
+ .arg("--abbrev=7")
+ .output()?
+ .stdout;
+
+ let pkgver = std::str::from_utf8(&stdout)?
+ .trim()
+ .trim_start_matches('v')
+ .replacen("-g", ".g", 1)
+ .replacen('-', "-r", 1)
+ .replace('-', ".");
+
+ if let Some(from) = buf.lines().find(|l| l.starts_with("pkgver=")) {
+ Ok(buf.replace(from, &format!("pkgver={pkgver}")))
+ } else {
+ Ok(buf)
+ }
+ })?;
+
+ bump.bump_file("CHANGELOG.md", |buf, Bump { version: _, next }| {
+ let date = chrono::Utc::now().format("%Y-%m-%d");
+ Ok(buf
+ .replace(
+ "## [Unreleased]",
+ &format!(
+ "## [Unreleased]\n\n\
+ ## [{next}] - {date}"
),
- ),
- Replacement::Append(
- "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD".to_string(),
- format!(
- "[{0}]: https://git.sr.ht/~tobyvin/projectr/log/v{0}",
- bump.next
+ )
+ .replace(
+ "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD",
+ &format!(
+ "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD\n\
+ [{next}]: https://git.sr.ht/~tobyvin/projectr/log/v{next}"
),
- ),
- ],
- )?;
+ ))
+ })?;
Ok(bump)
}
diff --git a/xtask/src/release/version.rs b/xtask/src/release/bump.rs
index 0c8cffd..617cfd6 100644
--- a/xtask/src/release/version.rs
+++ b/xtask/src/release/bump.rs
@@ -70,9 +70,10 @@ impl Bump {
.success())
}
- pub fn bump_file<P>(&mut self, path: P, replacements: &[Replacement]) -> Result<()>
+ pub fn bump_file<P, F>(&mut self, path: P, mutator: F) -> Result<()>
where
P: AsRef<Path>,
+ F: Fn(String, &Self) -> Result<String>,
{
let path = path.as_ref();
@@ -84,7 +85,7 @@ impl Bump {
let file = File::open(path)?;
- self.bump(&file, &file, replacements)?;
+ self.bump(&file, &file, mutator)?;
let git_added = Command::new("git").arg("add").arg(path).status()?;
@@ -93,17 +94,16 @@ impl Bump {
Ok(())
}
- fn bump<R, W>(&self, mut reader: R, mut writer: W, replacements: &[Replacement]) -> Result<()>
+ fn bump<R, W, F>(&self, mut reader: R, mut writer: W, mutator: F) -> Result<()>
where
R: Read,
W: Write,
+ F: Fn(String, &Self) -> Result<String>,
{
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
- let buf = replacements
- .iter()
- .try_fold(buf, |acc, r| r.replace(self, acc))?;
+ let buf = mutator(buf, self)?;
writer.write_all(buf.as_bytes()).map_err(Into::into)
}
@@ -133,36 +133,27 @@ impl From<Level> for Bump {
}
}
-#[derive(Default)]
-pub enum Replacement {
- #[default]
- Version,
- CargoVersion,
- FindLine(fn(&&str) -> bool, String),
- Replace(String, String),
- Append(String, String),
+/// Utility function for replacing version with next in a string.
+pub fn replace(buf: String, Bump { version, next }: &Bump) -> Result<String> {
+ Ok(buf.replace(&version.to_string(), &next.to_string()))
}
-impl Replacement {
- pub fn replace(&self, bump: &Bump, buf: String) -> Result<String> {
- let buf = match self {
- Replacement::Version => buf.replace(&bump.version.to_string(), &bump.next.to_string()),
- Replacement::Replace(from, to) => buf.replace(from, to),
- Replacement::Append(line, append) => buf.replace(line, &format!("{line}\n{append}")),
- Replacement::FindLine(find, replace) => match buf.lines().find(find) {
- Some(line) => buf.replace(line, replace),
- None => buf,
- },
- Replacement::CargoVersion => {
- let mut cargo_toml: toml_edit::Document = buf.parse()?;
- cargo_toml["workspace"]["package"]["version"] =
- toml_edit::value(bump.next.to_string());
- cargo_toml.to_string()
- }
- };
+/// Utility function for bumping the version in a Cargo.toml file.
+pub fn replace_cargo(buf: String, Bump { version: _, next }: &Bump) -> Result<String> {
+ let mut cargo_toml: toml_edit::Document = buf.parse()?;
- Ok(buf)
- }
+ if cargo_toml["package"]["version"]["workspace"]
+ .as_bool()
+ .unwrap_or_default()
+ {
+ cargo_toml["workspace"]["package"]["version"] = toml_edit::value(next.to_string());
+ } else if cargo_toml["package"]["version"].is_str() {
+ cargo_toml["package"]["version"] = toml_edit::value(next.to_string());
+ } else {
+ anyhow::bail!("Failed to find version in Cargo.toml");
+ };
+
+ Ok(cargo_toml.to_string())
}
#[cfg(test)]
@@ -186,6 +177,7 @@ mod test {
let right = std::str::from_utf8(writer).unwrap();
let diff = SimpleDiff::from_str(left, right, "old", "new");
+ assert_ne!(left, right);
println!("{diff}")
}
@@ -200,9 +192,7 @@ mod test {
let reader = content.as_bytes();
let mut writer = Vec::new();
- let replacements = &[Replacement::CargoVersion];
-
- bump.bump(reader, &mut writer, replacements).unwrap();
+ bump.bump(reader, &mut writer, replace_cargo).unwrap();
println!("{file}: {bump}");
print_diff(reader, &writer)
@@ -219,25 +209,25 @@ mod test {
let reader = content.as_bytes();
let mut writer = Vec::new();
- let replacements = &[
- Replacement::Append(
- "## [Unreleased]".to_string(),
- format!(
- "\n## [{}] - {}",
- bump.next,
- chrono::Utc::now().format("%Y-%m-%d")
- ),
- ),
- Replacement::Append(
- "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD".to_string(),
- format!(
- "[{0}]: https://git.sr.ht/~tobyvin/projectr/log/v{0}",
- bump.next
- ),
- ),
- ];
-
- bump.bump(reader, &mut writer, replacements).unwrap();
+ bump.bump(reader, &mut writer, |buf, Bump { version: _, next }| {
+ let date = chrono::Utc::now().format("%Y-%m-%d");
+ Ok(buf
+ .replace(
+ "## [Unreleased]",
+ &format!(
+ "## [Unreleased]\n\n\
+ ## [{next}] - {date}"
+ ),
+ )
+ .replace(
+ "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD",
+ &format!(
+ "[Unreleased]: https://git.sr.ht/~tobyvin/projectr/log/HEAD\n\
+ [{next}]: https://git.sr.ht/~tobyvin/projectr/log/v{next}"
+ ),
+ ))
+ })
+ .unwrap();
println!("{file}: {bump}");
print_diff(reader, &writer)
@@ -254,9 +244,7 @@ mod test {
let reader = content.as_deref().unwrap().as_bytes();
let mut writer = Vec::new();
- let replacements = &[Replacement::Version];
-
- bump.bump(reader, &mut writer, replacements).unwrap();
+ bump.bump(reader, &mut writer, replace).unwrap();
println!("{file}: {bump}");
print_diff(reader, &writer)
@@ -273,28 +261,28 @@ mod test {
let reader = content.as_bytes();
let mut writer = Vec::new();
- let stdout = std::process::Command::new("git")
- .arg("describe")
- .arg("--long")
- .arg("--abbrev=7")
- .output()
- .unwrap()
- .stdout;
-
- let pkgver = std::str::from_utf8(&stdout)
- .unwrap()
- .trim()
- .trim_start_matches('v')
- .replacen("-g", ".g", 1)
- .replacen('-', "-r", 1)
- .replace('-', ".");
-
- let replacements = &[Replacement::FindLine(
- |l| l.starts_with("pkgver="),
- format!("pkgver={pkgver}"),
- )];
-
- bump.bump(reader, &mut writer, replacements).unwrap();
+ bump.bump(reader, &mut writer, |buf, _| {
+ let stdout = std::process::Command::new("git")
+ .arg("describe")
+ .arg("--long")
+ .arg("--abbrev=7")
+ .output()?
+ .stdout;
+
+ let pkgver = std::str::from_utf8(&stdout)?
+ .trim()
+ .trim_start_matches('v')
+ .replacen("-g", ".g", 1)
+ .replacen('-', "-r", 1)
+ .replace('-', ".");
+
+ if let Some(from) = buf.lines().find(|l| l.starts_with("pkgver=")) {
+ Ok(buf.replace(from, &format!("pkgver={pkgver}")))
+ } else {
+ Ok(buf)
+ }
+ })
+ .unwrap();
println!("{file}: {bump}");
print_diff(reader, &writer)