diff options
Diffstat (limited to 'xtask')
-rw-r--r-- | xtask/src/bump.rs (renamed from xtask/src/release/bump.rs) | 22 | ||||
-rw-r--r-- | xtask/src/main.rs | 57 | ||||
-rw-r--r-- | xtask/src/release.rs | 134 |
3 files changed, 68 insertions, 145 deletions
diff --git a/xtask/src/release/bump.rs b/xtask/src/bump.rs index 86a1c96..da54e23 100644 --- a/xtask/src/release/bump.rs +++ b/xtask/src/bump.rs @@ -43,7 +43,7 @@ impl FromStr for Level { #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Bump { - pub version: Version, + pub prev: Version, pub next: Version, } @@ -62,7 +62,7 @@ impl Bump { .success()) } - pub fn bump_file<P, F>(&mut self, path: P, mutator: F) -> Result<()> + pub fn bump_file<P, F>(&self, path: P, mutator: F) -> Result<()> where P: AsRef<Path>, F: Fn(String, &Self) -> Result<String>, @@ -108,17 +108,23 @@ impl Bump { impl Display for Bump { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} -> {}", self.version, self.next) + write!(f, "{} -> {}", self.prev, self.next) } } /// Utility function for replacing version with next in a string. -pub fn replace(buf: String, Bump { version, next }: &Bump) -> Result<String> { +pub fn replace( + buf: String, + Bump { + prev: version, + next, + }: &Bump, +) -> Result<String> { Ok(buf.replace(&version.to_string(), &next.to_string())) } /// Utility function for bumping the version in a Cargo.toml file. -pub fn cargo(buf: String, Bump { version: _, next }: &Bump) -> Result<String> { +pub fn cargo(buf: String, Bump { prev: _, next }: &Bump) -> Result<String> { let mut cargo_toml: toml_edit::Document = buf.parse()?; if cargo_toml["package"]["version"]["workspace"] @@ -158,7 +164,7 @@ pub fn vsc_pkgbuild(buf: String, _: &Bump) -> Result<String> { } } -pub fn changelog(buf: String, Bump { version: _, next }: &Bump) -> Result<String> { +pub fn changelog(buf: String, Bump { prev: _, next }: &Bump) -> Result<String> { let date = chrono::Utc::now().format("%Y-%m-%d"); let lines: Vec<String> = buf @@ -205,7 +211,7 @@ mod test { let version = PKG_VER.parse().unwrap_or_else(|_| Version::new(0, 1, 0)); Ok(Bump { next: Level::default().bump(&version), - version, + prev: version, }) } @@ -242,7 +248,7 @@ mod test { let reader = content.as_bytes(); let mut writer = Vec::new(); - bump.bump(reader, &mut writer, |buf, Bump { version: _, next }| { + bump.bump(reader, &mut writer, |buf, Bump { prev: _, next }| { let date = chrono::Utc::now().format("%Y-%m-%d"); Ok(buf .replace( diff --git a/xtask/src/main.rs b/xtask/src/main.rs index ebdeecb..76fca16 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -11,12 +11,14 @@ use std::{fs::File, process::Command}; use anyhow::{anyhow, bail, ensure, Context, Result}; use build_info::BuildInfo; +use bump::{Bump, Level}; use clap::{Parser, Subcommand}; use flate2::{write::GzEncoder, Compression}; use once_cell::sync::Lazy; +use semver::Version; use tar::Builder; -mod release; +mod bump; const PKG_NAME: &str = "projectr"; const PKG_VER: &str = env!("CARGO_PKG_VERSION"); @@ -41,7 +43,20 @@ fn main() -> Result<()> { let targz = generate_tar_gz(version)?; println!("{}", targz.display()); } - Commands::Release(release) => release.run()?, + Commands::Release { level } => { + let Bump { prev, next } = release(level, cli.pre_release)?; + + println!("Bumped version: {prev} -> {next}"); + println!(); + println!("Create release commit:"); + println!("git commit -m 'chore: release projectr version {next}'"); + println!(); + println!("Create release tag:"); + println!("git shortlog v{prev}..HEAD | git tag -s v{next} --file -"); + println!(); + println!("Push refs:"); + println!("git push --follow-tags"); + } }; Ok(()) @@ -70,7 +85,11 @@ enum Commands { Dist, /// Automation for create a new release. - Release(release::Release), + Release { + /// Level of version bump. + #[arg(required = false)] + level: bump::Level, + }, } fn version(pre_release: bool) -> Result<String> { @@ -162,6 +181,38 @@ fn build_binary() -> Result<PathBuf> { Ok(binary) } +pub fn release(level: Level, pre_release: bool) -> Result<Bump> { + let prev = PKG_VER.parse().unwrap_or_else(|_| Version::new(0, 1, 0)); + let mut next = level.bump(&prev); + + if pre_release { + next.pre = semver::Prerelease::new("dev")? + } + + let bump = Bump { next, prev }; + + bump.bump_file("./Cargo.toml", bump::cargo)?; + bump.bump_file("./README.md", bump::replace)?; + bump.bump_file("./CHANGELOG.md", bump::changelog)?; + 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", bump::vsc_pkgbuild)?; + + let cargo_update = Command::new("cargo") + .arg("update") + .arg("--workspace") + .status()?; + anyhow::ensure!(cargo_update.success(), "Failed to update cargo lockfile"); + + let git_added = Command::new("git") + .arg("add") + .arg("./Cargo.lock") + .status()?; + anyhow::ensure!(git_added.success(), "Failed to add Cargo.lock to git"); + + Ok(bump) +} + static PROJECT_ROOT: Lazy<PathBuf> = Lazy::new(|| { let dir = std::env::current_dir().unwrap_or_else(|_| { Path::new(env!("CARGO_MANIFEST_DIR")) diff --git a/xtask/src/release.rs b/xtask/src/release.rs deleted file mode 100644 index 3e8f02e..0000000 --- a/xtask/src/release.rs +++ /dev/null @@ -1,134 +0,0 @@ -use std::process::{Command, Stdio}; - -use anyhow::Result; -use clap::{Args, Subcommand}; -use semver::Version; - -use crate::PKG_VER; - -use self::bump::{Bump, Level}; - -mod bump; - -#[derive(Debug, Clone, Subcommand)] -pub enum Step { - /// Bump version in package files and commit changes. - Bump { - /// Level of version bump version. - #[arg(required = false)] - level: bump::Level, - }, - - /// Make a release commit. - Commit { - /// Options passed to git commit. - #[arg(last = true)] - git_commit_args: Vec<String>, - }, - - /// Create git tag for release. - Tag, -} - -#[derive(Debug, Clone, Args)] -pub struct Release { - #[command(subcommand)] - step: Step, -} - -impl Release { - pub fn run(self) -> Result<()> { - match self.step { - Step::Bump { level } => { - let bump = Self::bump(level)?; - println!("Bumped version: {bump}"); - } - Step::Commit { git_commit_args } => { - let version = PKG_VER.parse()?; - Self::commit(version, git_commit_args)? - } - Step::Tag => { - let stdout = Command::new("git") - .arg("describe") - .arg("--abbrev=0") - .output()? - .stdout; - - let prev = std::str::from_utf8(&stdout)? - .trim() - .trim_start_matches('v') - .parse()?; - - let next = PKG_VER.parse()?; - Self::tag(prev, next)?; - } - }; - - Ok(()) - } - - pub fn bump(level: Level) -> Result<Bump> { - let version = PKG_VER.parse().unwrap_or_else(|_| Version::new(0, 1, 0)); - let next = level.bump(&version); - - let mut bump = Bump { next, version }; - - bump.bump_file("./Cargo.toml", bump::cargo)?; - bump.bump_file("./README.md", bump::replace)?; - bump.bump_file("./CHANGELOG.md", bump::changelog)?; - 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", bump::vsc_pkgbuild)?; - - let cargo_update = Command::new("cargo") - .arg("update") - .arg("--workspace") - .status()?; - anyhow::ensure!(cargo_update.success(), "Failed to update cargo lockfile"); - - let git_added = Command::new("git") - .arg("add") - .arg("./Cargo.lock") - .status()?; - anyhow::ensure!(git_added.success(), "Failed to add Cargo.lock to git"); - - Ok(bump) - } - - pub fn commit(version: Version, git_commit_args: Vec<String>) -> Result<()> { - let git_commit = Command::new("git") - .arg("commit") - .arg("-em") - .arg(format!("chore: release projectr version {version}")) - .args(git_commit_args) - .status()?; - - anyhow::ensure!(git_commit.success(), "Failed to commit changes"); - - Ok(()) - } - - pub fn tag(from: Version, to: Version) -> Result<String> { - let tag_name = format!("v{}", to); - - let shortlog_child = Command::new("git") - .arg("shortlog") - .arg(format!("v{}..HEAD", from)) - .arg("--abbrev=7") - .stdout(Stdio::piped()) - .spawn()?; - - let git_commit = Command::new("git") - .arg("tag") - .arg("-s") - .arg(&tag_name) - .arg("--file") - .arg("-") - .stdin(Stdio::from(shortlog_child.stdout.unwrap())) // Pipe through. - .status()?; - - anyhow::ensure!(git_commit.success(), "Failed to commit changes"); - - Ok(tag_name) - } -} |