From 74793d28cf25ea1cd6203bdc8e27a265175be1c1 Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Sat, 15 Jul 2023 18:34:02 -0500 Subject: build: move PKGBUILDs into seperate repos --- CONTRIBUTING.md | 64 +++++++++++ pkg/archlinux/projectr-bin/.gitignore | 6 -- pkg/archlinux/projectr-bin/PKGBUILD | 31 ------ pkg/archlinux/projectr-git/.gitignore | 7 -- pkg/archlinux/projectr-git/PKGBUILD | 64 ----------- pkg/archlinux/projectr/.gitignore | 6 -- pkg/archlinux/projectr/PKGBUILD | 56 ---------- xtask/src/main.rs | 193 +++++++++++++++++++++++++--------- 8 files changed, 207 insertions(+), 220 deletions(-) delete mode 100644 pkg/archlinux/projectr-bin/.gitignore delete mode 100644 pkg/archlinux/projectr-bin/PKGBUILD delete mode 100644 pkg/archlinux/projectr-git/.gitignore delete mode 100644 pkg/archlinux/projectr-git/PKGBUILD delete mode 100644 pkg/archlinux/projectr/.gitignore delete mode 100644 pkg/archlinux/projectr/PKGBUILD diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 80ce27e..627bce2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,6 +18,67 @@ specific questions and discussions should also be submitted there. For help sending patches, please consult [git-send-email.io], or feel free to ask for help in [~tobyvin/projectr-discuss@lists.sr.ht]. +### Style + +All changes are automatically verified by CI to conform to its rustfmt +guidelines. If a CI build is failing because of formatting issues, you can +install rustfmt using `rustup component add rustfmt` and then format all code +using `cargo fmt`. + +Unless otherwise specified, this project follows the [Rust compiler's style +guidelines]. + +All comments should be fully punctuated with a trailing period. This applies +both to regular and documentation comments. + +### Documentation + +Code should be documented where appropriate. The existing code can be used as a +guidance here and the general `rustfmt` rules can be followed for formatting. + +Additionally, changes which have a direct effect on the user (opposed to things +like code refactorings or documentation/tests) should be documented in the +`CHANGELOG.md` file. The existing entries should be used as a style guideline. +The change log should be used to document changes from a user-perspective, +instead of explaining the technical background (like commit messages). More +information about the change log format can be found [Keep a Changelog]. + +## Release + +This procedure assumes the changes have been committed and the `main` branch has +been checked out. + +1. Bump the version. The version to bump should be determined using the changes + made, in accordance with [SemVer]. + +```console +cargo xtask bump minor +``` + +1. Create a release commit + +```console +git commit -m 'chore: release projectr version v0.5.0' +``` + +1. Create a tag for the release commit + +```console +git shortlog v0.4.1..HEAD | git tag -s v0.5.0 --file - +``` + +1. Push the git refs + +```console +git push --follow-tags +``` + +1. Publish the crate to [crates.io] + +```console +cargo publish +``` + ## Conduct projectr and related community should follow the [Rust Code of Conduct]. For any @@ -32,3 +93,6 @@ questions or issues related to please submit a post on the https://lists.sr.ht/~tobyvin/projectr-devel [git-send-email.io]: https://git-send-email.io [Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct +[Rust compiler's style guidelines]: https://rust-lang.github.io/api-guidelines +[Keep a Changelog]: https://keepachangelog.com +[SemVer]: https://semver.org/ diff --git a/pkg/archlinux/projectr-bin/.gitignore b/pkg/archlinux/projectr-bin/.gitignore deleted file mode 100644 index e269fad..0000000 --- a/pkg/archlinux/projectr-bin/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.xz -*.zst -*.gz - -src/ -pkg/ diff --git a/pkg/archlinux/projectr-bin/PKGBUILD b/pkg/archlinux/projectr-bin/PKGBUILD deleted file mode 100644 index 59442a6..0000000 --- a/pkg/archlinux/projectr-bin/PKGBUILD +++ /dev/null @@ -1,31 +0,0 @@ -# Contributor: Toby Vincent -# Maintainer: Toby Vincent -pkgname=projectr-bin -pkgver=0.4.1 -pkgrel=1 -pkgdesc="A contextual, MRU sorted, project finder." -arch=("x86_64") -url="https://git.sr.ht/~tobyvin/projectr" -license=('MIT') -optdepends=('tmux-projectr: fzf tmux support') -provides=("${pkgname%-bin}=$pkgver") -conflicts=("${pkgname%-bin}=$pkgver") -source_x86_64=("https://git.sr.ht/~tobyvin/projectr/refs/download/v$pkgver/projectr-$pkgver-$CARCH.tar.gz") -sha256sums_x86_64=('20e1ce1a4c39abead71c4a6e01b2b2da8c595c5170165762d58a43b40354471d') - -package() { - cd "$srcdir/${pkgname%-bin}" - - install -Dm755 "target/release/${pkgname%-bin}" "$pkgdir/usr/bin/${pkgname%-bin}" - - install -Dm644 "completion/_${pkgname%-bin}" "$pkgdir/usr/share/zsh/site-functions/_${pkgname%-bin}" - install -Dm644 "completion/${pkgname%-bin}" "$pkgdir/usr/share/bash-completion/completions/${pkgname%-bin}" - install -Dm644 "completion/${pkgname%-bin}.fish" "$pkgdir/usr/share/fish/vendor_completions.d/${pkgname%-bin}.fish" - - install -Dm644 "man/${pkgname%-bin}.1" "$pkgdir/usr/share/man/man1/${pkgname%-bin}.1" - - install -Dm644 LICENSE "$pkgdir/usr/share/licenses/${pkgname%-bin}/LICENSE" - - install -Dm644 README.md "$pkgdir/usr/share/doc/${pkgname%-bin}/README.md" - install -Dm644 CHANGELOG.md "$pkgdir/usr/share/doc/${pkgname%-bin}/CHANGELOG.md" -} diff --git a/pkg/archlinux/projectr-git/.gitignore b/pkg/archlinux/projectr-git/.gitignore deleted file mode 100644 index aed6942..0000000 --- a/pkg/archlinux/projectr-git/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*.xz -*.zst -*.gz - -src/ -pkg/ -*-git/ diff --git a/pkg/archlinux/projectr-git/PKGBUILD b/pkg/archlinux/projectr-git/PKGBUILD deleted file mode 100644 index 0a7a8f4..0000000 --- a/pkg/archlinux/projectr-git/PKGBUILD +++ /dev/null @@ -1,64 +0,0 @@ -# Contributor: Toby Vincent -# Maintainer: Toby Vincent -pkgname=projectr-git -pkgver=0.4.0.r1.g4a6f485 -pkgrel=1 -pkgdesc="A contextual, MRU sorted, project finder." -arch=('i686' 'x86_64' 'armv6h' 'armv7h') -url="https://git.sr.ht/~tobyvin/projectr" -license=('MIT') -makedepends=('cargo' 'git') -optdepends=('tmux-projectr: fzf-tmux support') -provides=("${pkgname%-git}") -conflicts=("${pkgname%-git}") -source=("${pkgname%-git}::git+https://git.sr.ht/~tobyvin/projectr") -b2sums=('SKIP') - -pkgver() { - cd "$srcdir/${pkgname%-git}" - - printf "%s" "$(git describe --long --abbrev=7 | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')" -} - -prepare() { - cd "$srcdir/${pkgname%-git}" - - export RUSTUP_TOOLCHAIN=stable - cargo fetch --locked --target "$CARCH-unknown-linux-gnu" -} - -build() { - cd "$srcdir/${pkgname%-git}" - - export RUSTUP_TOOLCHAIN=stable - export CARGO_TARGET_DIR=target - cargo build --frozen --release --all-features - cargo xtask out-dir >out_dir -} - -check() { - cd "$srcdir/${pkgname%-git}" - - export RUSTUP_TOOLCHAIN=stable - cargo test --frozen --all-features -} - -package() { - cd "$srcdir/${pkgname%-git}" - - local OUT_DIR=$( -# Maintainer: Toby Vincent -pkgname=projectr -pkgver=0.4.1 -pkgrel=1 -pkgdesc="A contextual, MRU sorted, project finder." -arch=('i686' 'x86_64' 'armv6h' 'armv7h') -url="https://git.sr.ht/~tobyvin/projectr" -license=('MIT') -makedepends=('cargo') -optdepends=('tmux-projectr: fzf-tmux support') -source=("$pkgname-$pkgver.tar.gz::https://static.crates.io/crates/$pkgname/$pkgname-$pkgver.crate") -b2sums=('53241e79e55a2957b7956725e4da288abda9e94d4409399782c50ed7418bc1c5445b8b54b6e5276dd9775ab0e14af19e192200d7b984ca3da3a1b48bf2de4791') - -prepare() { - cd "$pkgname-$pkgver" - - export RUSTUP_TOOLCHAIN=stable - cargo fetch --locked --target "$CARCH-unknown-linux-gnu" -} - -build() { - cd "$pkgname-$pkgver" - - export RUSTUP_TOOLCHAIN=stable - export CARGO_TARGET_DIR=target - cargo build --frozen --release --all-features - - cargo xtask out-dir >out_dir -} - -check() { - cd "$pkgname-$pkgver" - - export RUSTUP_TOOLCHAIN=stable - cargo test --frozen --all-features -} - -package() { - cd "$pkgname-$pkgver" - - local OUT_DIR=$( Result<()> { match cli.command { Commands::OutDir => println!("{}", out_dir()?.display()), - Commands::Version => match version(cli.pre_release) { + Commands::Version => match version(cli.force) { Ok(v) => println!("{v}"), Err(_) => std::process::exit(1), }, Commands::Dist => { - let version = version(cli.pre_release)?; + let version = version(cli.force)?; let targz = generate_tar_gz(version)?; println!("{}", targz.display()); } - 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"); + Commands::Bump { level, pre_release } => { + let prev = version(cli.force)?; + let next = bump(prev, level, pre_release)?; + println!("{next}"); } }; @@ -65,9 +56,9 @@ fn main() -> Result<()> { #[derive(Debug, Clone, Parser)] #[command(author, version, about)] struct Cli { - /// Disable version/git tag check and appends `-dev` to the version - #[arg(short, long, global = true, required = false)] - pre_release: bool, + /// Disable version/git tag check + #[arg(short, long, global = true)] + force: bool, #[command(subcommand)] command: Commands, @@ -84,17 +75,43 @@ enum Commands { /// Generate distributable package. Dist, - /// Automation for create a new release. - Release { - /// Level of version bump. - #[arg(required = false)] - level: bump::Level, + /// Bump the version and update version dependant locations in files. + Bump { + /// SemVer field to increment. + #[arg(value_enum, required = false)] + level: Level, + /// Set pre-release field. + #[arg(short, long)] + pre_release: Option, }, } -fn version(pre_release: bool) -> Result { +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum Level { + Major, + Minor, + #[default] + Patch, +} + +impl std::str::FromStr for Level { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result { + match s.to_lowercase().as_str() { + "major" => Ok(Level::Major), + "minor" => Ok(Level::Minor), + "patch" => Ok(Level::Patch), + s => Err(anyhow::anyhow!("Invalid bump level: {s}")), + } + } +} + +fn version(force: bool) -> Result { use build_info::VersionControl::Git; + let version: Version = PKG_VER.parse()?; + let BuildInfo { version_control: Some(Git(git)), .. @@ -102,10 +119,8 @@ fn version(pre_release: bool) -> Result { bail!("Failed to get version control info."); }; - if pre_release { - Ok(format!("{PKG_VER}-dev")) - } else if git.tags.contains(&format!("v{PKG_VER}")) { - Ok(PKG_VER.to_owned()) + if force || git.tags.contains(&format!("v{version}")) { + Ok(version) } else { Err(anyhow!("Failed to find git tag matching package version.")) } @@ -136,7 +151,7 @@ fn out_dir() -> Result { .context("Failed to find `out` directory for latest build") } -fn generate_tar_gz(version: String) -> Result { +fn generate_tar_gz(version: Version) -> Result { let target = build_info::format!("{}", $.target.triple); let dist_pkg = DIST_DIR.join(format!("{PKG_NAME}-v{version}-{target}.tar.gz")); @@ -181,22 +196,22 @@ fn build_binary() -> Result { Ok(binary) } -pub fn release(level: Level, pre_release: bool) -> Result { - let prev = PKG_VER.parse().unwrap_or_else(|_| Version::new(0, 1, 0)); - let mut next = level.bump(&prev); +fn bump(prev: Version, level: Level, pre_release: Option) -> Result { + let mut next = prev.clone(); - if pre_release { - next.pre = semver::Prerelease::new("dev")? - } + match level { + Level::Major => next.major += 1, + Level::Minor => next.minor += 1, + Level::Patch => next.patch += 1, + }; - let bump = Bump { next, prev }; + if let Some(pre) = pre_release { + next.pre = pre; + } - 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)?; + bump_cargo(&next)?; + bump_readme(&prev, &next)?; + bump_changelog(&next)?; let cargo_update = Command::new("cargo") .arg("update") @@ -210,7 +225,85 @@ pub fn release(level: Level, pre_release: bool) -> Result { .status()?; anyhow::ensure!(git_added.success(), "Failed to add Cargo.lock to git"); - Ok(bump) + Ok(next) +} + +fn bump_readme(prev: &Version, next: &Version) -> Result<()> { + bump_file("./README.md", |contents| { + Ok(contents.replace(&prev.to_string(), &next.to_string())) + }) +} + +fn bump_changelog(next: &Version) -> Result<()> { + bump_file("./CHANGELOG.md", |contents| { + let date = chrono::Utc::now().format("%Y-%m-%d"); + + let lines: Vec = contents + .lines() + .flat_map(|line| { + if line.starts_with("## [Unreleased]") { + vec![ + line.to_owned(), + "".to_owned(), + format!("## [{next}] - {date}"), + ] + } else if line.starts_with("[Unreleased]: ") { + vec![ + line.to_owned(), + line.replace("[Unreleased]", &format!("[{next}]")) + .replace("HEAD", &format!("v{next}")), + ] + } else { + vec![line.to_owned()] + } + }) + .collect(); + + Ok(lines.join("\n")) + }) +} + +fn bump_cargo(next: &Version) -> Result<()> { + bump_file("./Cargo.toml", |contents| { + let mut cargo_toml: toml_edit::Document = contents.parse()?; + + 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()) + }) +} + +fn bump_file(path: P, mutator: F) -> Result<()> +where + P: AsRef, + F: Fn(String) -> Result, +{ + let path = path.as_ref(); + + let mut reader = BufReader::new(File::open(path)?); + let mut buf = String::new(); + reader.read_to_string(&mut buf)?; + + let buf = mutator(buf)?; + + let mut writer = BufWriter::new(File::open(path)?); + writer.write_all(buf.as_bytes())?; + writer.flush()?; + + let git_added = Command::new("git").arg("add").arg(path).status()?; + + anyhow::ensure!(git_added.success(), "Failed to add bumped files to git"); + + Ok(()) } static PROJECT_ROOT: Lazy = Lazy::new(|| { -- cgit v1.2.3-70-g09d2