aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-06-01 16:22:10 -0500
committerToby Vincent <tobyv13@gmail.com>2023-06-01 19:03:25 -0500
commit7201e443e19b45a2feb24ef470c6380b0859e52f (patch)
tree6c5fc66926db06faa29101cb8f57793ed9e9ba2c
parenteaf5c71873705b9593ec0e6b34d7e529d74a9269 (diff)
build: improve build tooling and add CD
Implement a xtask pattern tool for packaging into distributable. Add build script to generate completion scripts and man page. Improve PKGBUILDs and CI to use new tooling and upload artifact to tag after successful CI build. Make minor changes in cli config to facilitate the new build.rs script.
-rw-r--r--.builds/ci.yml24
-rw-r--r--.cargo/config.toml2
-rw-r--r--CHANGELOG.md15
-rw-r--r--Cargo.lock128
-rw-r--r--Cargo.toml30
-rw-r--r--build.rs57
-rw-r--r--pkg/archlinux/projectr-bin/PKGBUILD26
-rw-r--r--pkg/archlinux/projectr-git/PKGBUILD40
-rw-r--r--pkg/archlinux/projectr/PKGBUILD27
-rw-r--r--src/config.rs42
-rw-r--r--src/main.rs5
-rw-r--r--xtask/Cargo.toml15
-rw-r--r--xtask/src/lib.rs102
-rw-r--r--xtask/src/main.rs65
14 files changed, 488 insertions, 90 deletions
diff --git a/.builds/ci.yml b/.builds/ci.yml
index a085bcd..9f6e9e5 100644
--- a/.builds/ci.yml
+++ b/.builds/ci.yml
@@ -1,18 +1,30 @@
image: archlinux
+oauth: git.sr.ht/OBJECTS:RW
packages:
- rust
+ - hut
sources:
- https://git.sr.ht/~tobyvin/projectr
+environment:
+ CARCH: x86_64
tasks:
+ - fmt: |
+ cd projectr
+ cargo fmt --frozen --all --check
+ - prepare: |
+ cd projectr
+ cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
- build: |
cd projectr
- cargo build --workspace --all-features
+ cargo build --frozen --release --all-features
- test: |
cd projectr
- cargo test --workspace --all-features
- - clippy: |
+ cargo check --frozen --all-targets --all-features
+ cargo test --frozen --all-targets --all-features
+ git describe --exact-match HEAD > pkgver || complete-build
+ - package: |
cd projectr
- cargo clippy --workspace --all-features --no-deps -- -D warnings
- - fmt: |
+ cargo xtask dist --tag=$(<pkgver) > pkgdist
+ - publish: |
cd projectr
- cargo fmt --all -- --check
+ hut git artifact upload $(<pkgdist) --rev=$(<pkgver)
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..35049cb
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,2 @@
+[alias]
+xtask = "run --package xtask --"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 616e439..b8d9cda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,21 @@ and this project adheres to
## [Unreleased]
+### Added
+
+- Added `cargo xtask dist` tool for packaging into distributable.
+- Added `cargo xtask out-path` for locating the build script artifacts.
+- Added build script to generate completion scripts and man pages.
+- Added PKGBUILDs for installing on Arch Linux.
+
+### Changed
+
+- Upload artifacts to tag ref on sr.ht after successful CI build.
+
+### Removed
+
+- Removed `--quiet` flag.
+
## [0.3.2] - 2023-05-21
## [0.3.1] - 2023-05-21
diff --git a/Cargo.lock b/Cargo.lock
index 7296898..2bdcb0a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,6 +3,12 @@
version = 3
[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -108,9 +114,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "4.2.7"
+version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938"
+checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc"
dependencies = [
"clap_builder",
"clap_derive",
@@ -119,9 +125,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.2.7"
+version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd"
+checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990"
dependencies = [
"anstream",
"anstyle",
@@ -131,10 +137,19 @@ dependencies = [
]
[[package]]
+name = "clap_complete"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a04ddfaacc3bc9e6ea67d024575fafc2a813027cf374b8f24f7bc233c6b6be12"
+dependencies = [
+ "clap",
+]
+
+[[package]]
name = "clap_derive"
-version = "4.2.0"
+version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
+checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b"
dependencies = [
"heck",
"proc-macro2",
@@ -144,9 +159,19 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
+checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
+
+[[package]]
+name = "clap_mangen"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bcbd911d903a985de775aabe3bcef9b88e2a7d943e36aa8691617012d2b7731"
+dependencies = [
+ "clap",
+ "roff",
+]
[[package]]
name = "colorchoice"
@@ -155,6 +180,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -176,6 +210,28 @@ dependencies = [
]
[[package]]
+name = "filetime"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "windows-sys",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -354,6 +410,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -408,6 +473,8 @@ version = "0.3.2"
dependencies = [
"anyhow",
"clap",
+ "clap_complete",
+ "clap_mangen",
"git2",
"ignore",
"tracing",
@@ -424,6 +491,15 @@ dependencies = [
]
[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "regex"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -456,6 +532,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]]
+name = "roff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
+
+[[package]]
name = "rustix"
version = "0.37.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -517,6 +599,17 @@ dependencies = [
]
[[package]]
+name = "tar"
+version = "0.4.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
name = "thread_local"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -759,3 +852,22 @@ name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
+name = "xattr"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "xtask"
+version = "0.3.2"
+dependencies = [
+ "anyhow",
+ "clap",
+ "flate2",
+ "tar",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 61dc178..2225908 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,18 +1,31 @@
-[package]
-name = "projectr"
+[workspace]
+members = ["xtask"]
+
+[workspace.package]
version = "0.3.2"
edition = "2021"
-description = "A contextual, MRU sorted, project finder."
authors = ["Toby Vincent <tobyv13@gmail.com>"]
homepage = "https://git.sr.ht/~tobyvin/projectr"
repository = "https://git.sr.ht/~tobyvin/projectr"
license = "MIT"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+[workspace.dependencies]
+anyhow = "1.0.66"
+clap = { version = "4.0.18", features = ["derive"] }
+
+[package]
+name = "projectr"
+version = { workspace = true }
+description = "A contextual, MRU sorted, project finder."
+edition = { workspace = true }
+authors = { workspace = true }
+homepage = { workspace = true }
+repository = { workspace = true }
+license = { workspace = true }
[dependencies]
-anyhow = "1.0.66"
-clap = { version = "4.0.18", features = ["derive", "env"] }
+anyhow = { workspace = true }
+clap = { workspace = true, features = ["env"] }
git2 = { version = "0.15.0", default-features = false, optional = true, features = [
"vendored-libgit2",
] }
@@ -24,6 +37,11 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
default = ["git"]
git = ["dep:git2"]
+[build-dependencies]
+clap = { workspace = true }
+clap_complete = "4.3.0"
+clap_mangen = "0.2.11"
+
[package.metadata.release]
allow-branch = ["main", "!HEAD"]
sign-commit = true
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..96686ec
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,57 @@
+use std::{fs::File, io, path::Path};
+
+use clap::{CommandFactory, ValueEnum};
+use clap_complete::Shell;
+use clap_mangen::Man;
+
+#[path = "src/config.rs"]
+mod config;
+
+fn main() {
+ // OUT_DIR is where any additional build artifacts are written; Set by Cargo.
+ let Some(out_dir) = std::env::var_os("OUT_DIR") else {
+ eprintln!("OUT_DIR environment variable not defined.");
+ std::process::exit(1);
+ };
+
+ std::fs::create_dir_all(&out_dir).unwrap();
+
+ let cmd = config::Config::command();
+ let bin_name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
+
+ if let Err(err) = generate_man_page(bin_name, &out_dir) {
+ eprintln!("failed to generate man page: {}", err);
+ }
+
+ if let Err(err) = generate_completions(bin_name, &out_dir) {
+ eprintln!("failed to generate shell completion: {}", err);
+ }
+
+ println!("cargo:rerun-if-changed=build.rs");
+}
+
+fn generate_man_page<P: AsRef<Path>>(bin_name: &str, out_dir: P) -> Result<(), io::Error> {
+ let out_dir = out_dir.as_ref().join("man");
+ std::fs::create_dir_all(&out_dir)?;
+
+ let cmd = config::Config::command();
+
+ let mut man_page = out_dir.join(bin_name);
+ man_page.set_extension("1");
+
+ let mut file = File::create(&man_page)?;
+
+ Man::new(cmd).render(&mut file)
+}
+
+fn generate_completions<P: AsRef<Path>>(bin_name: &str, out_dir: P) -> Result<(), io::Error> {
+ let out_dir = out_dir.as_ref().join("completions");
+ std::fs::create_dir_all(&out_dir)?;
+
+ let mut cmd = config::Config::command();
+
+ Shell::value_variants().iter().try_for_each(|&shell| {
+ clap_complete::generate_to(shell, &mut cmd, bin_name, out_dir.as_path())?;
+ Ok(())
+ })
+}
diff --git a/pkg/archlinux/projectr-bin/PKGBUILD b/pkg/archlinux/projectr-bin/PKGBUILD
index 7ad2558..90f9fd6 100644
--- a/pkg/archlinux/projectr-bin/PKGBUILD
+++ b/pkg/archlinux/projectr-bin/PKGBUILD
@@ -7,19 +7,25 @@ pkgdesc="A contextual, MRU sorted, project finder."
arch=("x86_64")
url="https://git.sr.ht/~tobyvin/projectr"
license=('MIT')
-optdepends=('fzf: tmux-projectr support' 'tmux: tmux-projectr support')
-provides=('projectr' 'tmux-projectr')
-conflicts=('projectr' 'tmux-projectr')
+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/"
+ 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 -Dm755 "projectr" "$pkgdir/usr/bin/projectr"
- install -Dm755 "tmux-projectr" "$pkgdir/usr/bin/tmux-projectr"
- install -Dm644 "README.md" "$pkgdir/usr/share/doc/projectr/README.md"
- install -Dm644 "LICENSE" "$pkgdir/usr/share/doc/projectr/LICENSE"
- install -Dm644 "CHANGELOG.md" "$pkgdir/usr/share/doc/projectr/CHANGELOG.md"
+ 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/PKGBUILD b/pkg/archlinux/projectr-git/PKGBUILD
index 0cf3dd4..470ede5 100644
--- a/pkg/archlinux/projectr-git/PKGBUILD
+++ b/pkg/archlinux/projectr-git/PKGBUILD
@@ -8,44 +8,56 @@ arch=('i686' 'x86_64' 'armv6h' 'armv7h')
url="https://git.sr.ht/~tobyvin/projectr"
license=('MIT')
makedepends=('cargo' 'git')
-optdepends=('fzf: tmux-projectr support' 'tmux: tmux-projectr support')
-provides=('projectr' 'tmux-projectr')
-conflicts=('projectr' 'tmux-projectr')
-source=("$pkgname::git+https://git.sr.ht/~tobyvin/projectr")
+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 "$pkgname"
- git describe --long --abbrev=7 | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
+ cd "$srcdir/${pkgname%-git}"
+
+ printf "%s" "$(git describe --long | sed 's/\([^-]*-\)g/r\1/;s/-/./g')"
}
prepare() {
- cd "$pkgname"
+ cd "$srcdir/${pkgname%-git}"
export RUSTUP_TOOLCHAIN=stable
cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
}
build() {
- cd "$pkgname"
+ cd "$srcdir/${pkgname%-git}"
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release --all-features
+ cargo xtask outdir >out_dir
}
check() {
- cd "$pkgname"
+ cd "$srcdir/${pkgname%-git}"
export RUSTUP_TOOLCHAIN=stable
cargo test --frozen --all-features
}
package() {
- cd "$pkgname"
+ cd "$srcdir/${pkgname%-git}"
+
+ local OUT_DIR=$(<out_dir)
+
+ install -Dm755 "target/release/${pkgname%-git}" "$pkgdir/usr/bin/${pkgname%-git}"
+
+ install -Dm644 "$OUT_DIR/completion/_${pkgname%-git}" "$pkgdir/usr/share/zsh/site-functions/_${pkgname%-git}"
+ install -Dm644 "$OUT_DIR/completion/${pkgname%-git}" "$pkgdir/usr/share/bash-completion/completions/${pkgname%-git}"
+ install -Dm644 "$OUT_DIR/completion/${pkgname%-git}.fish" "$pkgdir/usr/share/fish/vendor_completions.d/${pkgname%-git}.fish"
+
+ install -Dm644 "$OUT_DIR/man/${pkgname%-git}.1" "$pkgdir/usr/share/man/man1/${pkgname%-git}.1"
+
+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/${pkgname%-git}/LICENSE"
- install -Dm755 "target/release/projectr" "$pkgdir/usr/bin/projectr"
- install -Dm644 "README.md" "$pkgdir/usr/share/doc/projectr/README.md"
- install -Dm644 "LICENSE" "$pkgdir/usr/share/doc/projectr/LICENSE"
- install -Dm644 "CHANGELOG.md" "$pkgdir/usr/share/doc/projectr/CHANGELOG.md"
+ install -Dm644 README.md "$pkgdir/usr/share/doc/${pkgname%-git}/README.md"
+ install -Dm644 CHANGELOG.md "$pkgdir/usr/share/doc/${pkgname%-git}/CHANGELOG.md"
}
diff --git a/pkg/archlinux/projectr/PKGBUILD b/pkg/archlinux/projectr/PKGBUILD
index 627da48..8fade38 100644
--- a/pkg/archlinux/projectr/PKGBUILD
+++ b/pkg/archlinux/projectr/PKGBUILD
@@ -8,28 +8,29 @@ arch=('i686' 'x86_64' 'armv6h' 'armv7h')
url="https://git.sr.ht/~tobyvin/projectr"
license=('MIT')
makedepends=('cargo')
-optdepends=('fzf: tmux-projectr support' 'tmux: tmux-projectr support')
-provides=("tmux-projectr")
+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"
+ cd "$pkgname-$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
}
build() {
- cd "$pkgname-$pkgver"
+ cd "$pkgname-$pkgver"
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release --all-features
+
+ cargo xtask outdir >out_dir
}
check() {
- cd "$pkgname-$pkgver"
+ cd "$pkgname-$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo test --frozen --all-features
@@ -38,8 +39,18 @@ check() {
package() {
cd "$pkgname-$pkgver"
+ local OUT_DIR=$(<out_dir)
+
install -Dm755 "target/release/$pkgname" "$pkgdir/usr/bin/$pkgname"
- install -Dm644 "README.md" "$pkgdir/usr/share/doc/projectr/README.md"
- install -Dm644 "LICENSE" "$pkgdir/usr/share/doc/projectr/LICENSE"
- install -Dm644 "CHANGELOG.md" "$pkgdir/usr/share/doc/projectr/CHANGELOG.md"
+
+ install -Dm644 "$OUT_DIR/completion/_$pkgname" "$pkgdir/usr/share/zsh/site-functions/_$pkgname"
+ install -Dm644 "$OUT_DIR/completion/$pkgname" "$pkgdir/usr/share/bash-completion/completions/$pkgname"
+ install -Dm644 "$OUT_DIR/completion/$pkgname.fish" "$pkgdir/usr/share/fish/vendor_completions.d/$pkgname.fish"
+
+ install -Dm644 "$OUT_DIR/man/$pkgname.1" "$pkgdir/usr/share/man/man1/$pkgname.1"
+
+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
+
+ install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md"
+ install -Dm644 CHANGELOG.md "$pkgdir/usr/share/doc/$pkgname/CHANGELOG.md"
}
diff --git a/src/config.rs b/src/config.rs
index 0fc313f..ec4cebd 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,7 +1,6 @@
use std::path::PathBuf;
use clap::{Args, Parser};
-use tracing::{metadata::LevelFilter, Level};
#[derive(Debug, Clone, Default, Parser)]
#[command(author, version, about)]
@@ -25,8 +24,11 @@ pub struct Config {
#[arg(short = 'P', long = "project")]
pub include: Vec<PathBuf>,
- #[command(flatten)]
- pub verbosity: Verbosity,
+ /// Print additional information per occurrence.
+ ///
+ /// Conflicts with `--quiet`.
+ #[arg(short, long, global = true, action = clap::ArgAction::Count)]
+ pub verbosity: u8,
}
#[derive(Debug, Default, Clone, Args)]
@@ -88,37 +90,3 @@ pub struct Projects {
#[arg(long, short)]
pub tmux: bool,
}
-
-#[derive(Debug, Default, Clone, Args)]
-pub struct Verbosity {
- /// Print additional information per occurrence.
- ///
- /// Conflicts with `--quiet`.
- #[arg(short, long, global = true, action = clap::ArgAction::Count, conflicts_with = "quiet")]
- pub verbose: u8,
-
- /// Suppress all output.
- ///
- /// Conflicts with `--verbose`.
- #[arg(short, long, global = true, conflicts_with = "verbose")]
- pub quiet: bool,
-}
-
-impl From<&Verbosity> for Option<Level> {
- fn from(value: &Verbosity) -> Self {
- match 1 + value.verbose - u8::from(value.quiet) {
- 0 => None,
- 1 => Some(Level::ERROR),
- 2 => Some(Level::WARN),
- 3 => Some(Level::INFO),
- 4 => Some(Level::DEBUG),
- _ => Some(Level::TRACE),
- }
- }
-}
-
-impl From<&Verbosity> for LevelFilter {
- fn from(value: &Verbosity) -> Self {
- Option::<Level>::from(value).into()
- }
-}
diff --git a/src/main.rs b/src/main.rs
index 25a051e..103101b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,9 @@
+use std::str::FromStr;
+
use anyhow::Result;
use clap::Parser;
use projectr::{config::Config, project::Projects, tmux::Tmux, Search};
+use tracing::metadata::LevelFilter;
fn main() -> Result<()> {
let config = Config::parse();
@@ -8,7 +11,7 @@ fn main() -> Result<()> {
tracing_subscriber::fmt::fmt()
.pretty()
.with_writer(std::io::stderr)
- .with_max_level(&config.verbosity)
+ .with_max_level(LevelFilter::from_str(&config.verbosity.to_string())?)
.init();
let mut projects = Projects::from(config.parsers);
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
new file mode 100644
index 0000000..5040f0a
--- /dev/null
+++ b/xtask/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "xtask"
+version = { workspace = true }
+edition = { workspace = true }
+authors = { workspace = true }
+homepage = { workspace = true }
+repository = { workspace = true }
+license = { workspace = true }
+publish = false
+
+[dependencies]
+anyhow = { workspace = true }
+clap = { workspace = true }
+tar = "0.4.38"
+flate2 = "1.0.26"
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
new file mode 100644
index 0000000..5e876d5
--- /dev/null
+++ b/xtask/src/lib.rs
@@ -0,0 +1,102 @@
+use std::{
+ env::consts::ARCH,
+ fs::File,
+ path::{Path, PathBuf},
+};
+
+use anyhow::{ensure, Result};
+use flate2::{write::GzEncoder, Compression};
+use tar::Builder;
+
+const BIN_NAME: &str = "projectr";
+const PKG_VER: &str = env!("CARGO_PKG_VERSION");
+const PKG_INCLUDE: &[&str] = &[
+ "bin/tmux-projectr",
+ "CONTRIBUTING.md",
+ "README.md",
+ "LICENSE",
+];
+
+pub fn generate_tar_gz<P: AsRef<Path>>(
+ root: &P,
+ profile: &str,
+ tag: Option<&str>,
+) -> Result<PathBuf> {
+ let pkg_name = format!("{BIN_NAME}-{PKG_VER}-{ARCH}.tar.gz");
+
+ let target_dir = root.as_ref().join("target");
+ let profile_dir = target_dir.join(profile);
+ let dist_dir = target_dir.join("dist");
+ let out_dir = find_out_dir(&profile_dir)?;
+
+ let bin_path = profile_dir.join(BIN_NAME);
+ let pkg_path = dist_dir.join(pkg_name);
+
+ ensure!(
+ !tag.is_some_and(|t| t.trim_start_matches('v') != PKG_VER),
+ "Package version does not match provided tag: {PKG_VER} != {}",
+ tag.unwrap().trim_start_matches('v')
+ );
+
+ ensure!(
+ bin_path.exists(),
+ "Package binary does not exist: {}",
+ bin_path.display()
+ );
+
+ ensure!(
+ out_dir.exists(),
+ "Build's out directory does not exist: {}",
+ out_dir.display()
+ );
+
+ let _ = std::fs::remove_dir_all(&dist_dir);
+ std::fs::create_dir_all(&dist_dir)?;
+
+ let tar_gz = File::create(&pkg_path)?;
+ let enc = GzEncoder::new(tar_gz, Compression::default());
+ let mut tar = Builder::new(enc);
+
+ std::env::set_current_dir(root)?;
+
+ tar.append_path_with_name(bin_path, PathBuf::from("bin").join(BIN_NAME))?;
+ tar.append_dir_all(".", out_dir)?;
+ PKG_INCLUDE.iter().try_for_each(|p| tar.append_path(p))?;
+
+ tar.into_inner()?.finish()?;
+
+ Ok(pkg_path)
+}
+
+pub fn find_out_dir<P: AsRef<Path>>(profile_dir: P) -> Result<PathBuf> {
+ let build_dir = profile_dir.as_ref().join("build");
+
+ build_dir
+ .read_dir()
+ .map_err(|_| {
+ anyhow::anyhow!(
+ "Package build directory does not exist: {}",
+ build_dir.display()
+ )
+ })?
+ .flatten()
+ .filter_map(|d| {
+ d.file_name()
+ .to_str()?
+ .starts_with(BIN_NAME)
+ .then(|| d.path().join("invoked.timestamp"))
+ .filter(|p| p.exists())
+ })
+ .reduce(|acc, path_buf| {
+ std::cmp::max_by_key(path_buf, acc, |p| {
+ p.metadata()
+ .and_then(|m| m.modified())
+ .unwrap_or(std::time::SystemTime::UNIX_EPOCH)
+ })
+ })
+ .map(|p| p.with_file_name("out"))
+ .ok_or(anyhow::anyhow!(
+ "Package out directory not found: {}",
+ profile_dir.as_ref().display()
+ ))
+}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
new file mode 100644
index 0000000..2282efd
--- /dev/null
+++ b/xtask/src/main.rs
@@ -0,0 +1,65 @@
+//! See <https://github.com/matklad/cargo-xtask/>.
+//!
+//! This binary defines various auxiliary build commands, which are not
+//! expressible with just `cargo`.
+//!
+//! This binary is integrated into the `cargo` command line by using an alias in
+//! `.cargo/config`.
+
+use std::path::PathBuf;
+
+use anyhow::Result;
+use clap::{Parser, Subcommand};
+
+fn main() -> Result<()> {
+ let cli = Cli::parse();
+
+ match cli.command {
+ Commands::Dist { tag } => {
+ let targz = xtask::generate_tar_gz(&cli.directory, &cli.profile, tag.as_deref())?;
+ println!("{}", targz.display());
+ }
+ Commands::OutDir => {
+ let profile_dir = cli.directory.join("target").join(&cli.profile);
+ let out_dir = xtask::find_out_dir(profile_dir)?;
+ println!("{}", out_dir.display());
+ }
+ };
+
+ Ok(())
+}
+
+#[derive(Debug, Clone, Parser)]
+#[command(author, version, about)]
+struct Cli {
+ #[command(subcommand)]
+ command: Commands,
+
+ /// Cargo profile to use.
+ #[arg(short, long, default_value = "release")]
+ profile: String,
+
+ /// Path to root directory of package.
+ #[arg(short='C', long, default_value_os_t = get_package_dir())]
+ directory: PathBuf,
+}
+
+#[derive(Debug, Clone, Subcommand)]
+enum Commands {
+ /// Print the default value of OUT_DIR used by cargo when building the package.
+ OutDir,
+
+ /// Generate distributable package and print it's path
+ Dist {
+ /// Verify the package version matches the provided tag.
+ #[arg(short, long)]
+ tag: Option<String>,
+ },
+}
+
+fn get_package_dir() -> PathBuf {
+ std::path::Path::new(&env!("CARGO_MANIFEST_DIR"))
+ .parent()
+ .unwrap()
+ .to_path_buf()
+}