diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c33ecc9..8a81b1e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,12 +16,35 @@ env: jobs: test: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + - name: Test Rust Stable + run: cargo test + env: + RUST_TOOLCHAIN: stable + build: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 with: - fetch-depth: 0 # fetch tags for publish + toolchain: 1.60 + profile: minimal + - name: Build Rust MSRV (1.60) + run: cargo build - - run: cargo run -p xtask -- ci + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # fetch tags for publish + - name: Publish + run: cargo run -p xtask -- ci env: CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} diff --git a/src/lib.rs b/src/lib.rs index 2342a66..f6a7038 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,10 +146,10 @@ use std::{ ops::Range, panic, path::{Path, PathBuf}, - sync::Mutex, + sync::{LazyLock, Mutex}, }; -use once_cell::sync::{Lazy, OnceCell}; +use once_cell::sync::OnceCell; const HELP: &str = " You can update all `expect!` tests by running: @@ -467,7 +467,7 @@ struct Runtime { help_printed: bool, per_file: HashMap<&'static str, FileRuntime>, } -static RT: Lazy> = Lazy::new(Default::default); +static RT: LazyLock> = LazyLock::new(Default::default); impl Runtime { fn fail_expect(expect: &Expect, expected: &str, actual: &str) { @@ -694,7 +694,7 @@ fn trim_indent(mut text: &str) -> String { .collect() } -fn lines_with_ends(text: &str) -> LinesWithEnds { +fn lines_with_ends(text: &str) -> LinesWithEnds<'_> { LinesWithEnds { text } } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index e4bb9fb..a18719a 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -6,4 +6,4 @@ authors = ["Aleksey Kladov "] edition = "2018" [dependencies] -xaction = "0.2.1" +xshell = "0.2.7" diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 55c368e..715d5d6 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,8 +1,9 @@ -use std::env; +use std::{env, fs, path::PathBuf}; -use xaction::{cargo_toml, cmd, git, push_rustup_toolchain, section, Result}; +use xshell::{cmd, Shell}; -const MSRV: &str = "1.60.0"; +type Error = Box; +type Result = std::result::Result; fn main() { if let Err(err) = try_main() { @@ -21,36 +22,55 @@ fn try_main() -> Result<()> { } } - let cargo_toml = cargo_toml()?; + let sh = Shell::new()?; - { - let _s = section("TEST_STABLE"); - let _t = push_rustup_toolchain("stable"); - cmd!("cargo test").run()?; - } - - { - let _s = section("TEST_MSRV"); - let _t = push_rustup_toolchain(MSRV); - cmd!("cargo build").run()?; - } - - let version = cargo_toml.version()?; + let cargo_toml = cargo_toml(&sh)?; + let version = cargo_toml.get("version")?; let tag = format!("v{}", version); let dry_run = - env::var("CI").is_err() || git::has_tag(&tag)? || git::current_branch()? != "master"; - xaction::set_dry_run(dry_run); - - { - let _s = section("PUBLISH"); - cargo_toml.publish()?; - git::tag(&tag)?; - git::push_tags()?; + env::var("CI").is_err() || git::has_tag(&sh, &tag)? || git::current_branch(&sh)? != "master"; + + let token = env::var("CRATES_IO_TOKEN").unwrap_or("no token".to_string()); + let dry_run_flag = dry_run.then_some("--dry-run"); + cmd!(sh, "cargo publish --token {token} {dry_run_flag...}").run()?; + + if !dry_run { + cmd!(sh, "git tag {tag}").run()?; + cmd!(sh, "git push --tags").run()?; } + Ok(()) } +pub fn cargo_toml(sh: &Shell) -> Result { + let cwd = sh.current_dir(); + let path = cwd.join("Cargo.toml"); + let contents = fs::read_to_string(&path)?; + Ok(CargoToml { path, contents }) +} + +pub struct CargoToml { + path: PathBuf, + contents: String, +} + +impl CargoToml { + fn get(&self, field: &str) -> Result<&str> { + for line in self.contents.lines() { + let words = line.split_ascii_whitespace().collect::>(); + match words.as_slice() { + [n, "=", v, ..] if n.trim() == field => { + assert!(v.starts_with('"') && v.ends_with('"')); + return Ok(&v[1..v.len() - 1]); + } + _ => (), + } + } + Err(format!("can't find `{}` in {}", field, self.path.display()))? + } +} + fn print_usage() { eprintln!( "\ @@ -61,3 +81,24 @@ SUBCOMMANDS: " ) } + +mod git { + use crate::Result; + use xshell::{cmd, Shell}; + + pub(crate) fn current_branch(sh: &Shell) -> Result { + let res = cmd!(sh, "git branch --show-current").read()?; + Ok(res) + } + + pub(crate) fn has_tag(sh: &Shell, tag: &str) -> Result { + let res = tag_list(sh)?.iter().any(|it| it == tag); + Ok(res) + } + + fn tag_list(sh: &Shell) -> Result> { + let tags = cmd!(sh, "git tag --list").read()?; + let res = tags.lines().map(|it| it.trim().to_string()).collect(); + Ok(res) + } +} diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs index 97c423a..a60a99f 100644 --- a/xtask/tests/tidy.rs +++ b/xtask/tests/tidy.rs @@ -1,6 +1,8 @@ -use xaction::cmd; +use xshell::{cmd, Shell}; #[test] fn test_formatting() { - cmd!("cargo fmt --all -- --check").run().unwrap() + let sh = Shell::new().unwrap(); + + cmd!(sh, "cargo fmt --all -- --check").run().unwrap() }