diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 549dd59b..1692d5f1 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -9,12 +9,17 @@ on: pull_request: branches: - "*" - tags-ignore: - - "*" schedule: # * is a special character in YAML so you have to quote this string - cron: "23 3 * * *" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + name: 💣 Audit 💣 jobs: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7b431819..85d93ec4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,13 @@ on: # * is a special character in YAML so you have to quote this string - cron: "13 3 * * *" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + name: 🦀 Rust 🦀 jobs: diff --git a/.vscode/settings.json b/.vscode/settings.json index 40d13449..5a90ea79 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { "rust-analyzer.cargo.features": [ - "build","cargo","git","gitoxide","rustc","si","color","serde","trace" + "build","cargo","git","gitoxide","rustc","si","color","serde","trace","header" ] } \ No newline at end of file diff --git a/run_all.fish b/run_all.fish index 08d8b873..d7095f8a 100755 --- a/run_all.fish +++ b/run_all.fish @@ -3,7 +3,7 @@ cargo fmt --all -- --check; and \ cargo clippy -p vergen --all-targets --features build,cargo,git,gitcl,rustc,si -- -Dwarnings; and \ cargo clippy -p vergen --all-targets --features build,cargo,git,git2,rustc,si -- -Dwarnings; and \ cargo clippy -p vergen --all-targets --features build,cargo,git,gitoxide,rustc,si -- -Dwarnings; and \ -cargo clippy -p vergen-pretty --all-targets --features color,trace -- -Dwarnings; and \ +cargo clippy -p vergen-pretty --all-targets --features color,header,trace -- -Dwarnings; and \ cargo build-all-features; and \ cargo test-all-features; and \ cargo test -p vergen -F build,cargo,git,gitcl,rustc,si; and \ @@ -11,11 +11,18 @@ cargo test -p vergen -F build,cargo,git,git2,rustc,si; and \ cargo test -p vergen -F build,cargo,git,gitoxide,rustc,si; and \ cargo test -p vergen-pretty -F __vergen_test; and \ cargo test -p vergen-pretty -F __vergen_test,color; and \ +cargo test -p vergen-pretty -F __vergen_test,header; and \ cargo test -p vergen-pretty -F __vergen_test,trace; and \ cargo test -p vergen-pretty -F __vergen_test,serde; and \ +cargo test -p vergen-pretty -F __vergen_test,color,header; and \ cargo test -p vergen-pretty -F __vergen_test,color,serde; and \ cargo test -p vergen-pretty -F __vergen_test,color,trace; and \ +cargo test -p vergen-pretty -F __vergen_test,header,serde; and \ +cargo test -p vergen-pretty -F __vergen_test,header,trace; and \ cargo test -p vergen-pretty -F __vergen_test,serde,trace; and \ -cargo test -p vergen-pretty -F __vergen_test,color,serde,trace; and \ +cargo test -p vergen-pretty -F __vergen_test,color,header,serde; and \ +cargo test -p vergen-pretty -F __vergen_test,color,header,trace; and \ +cargo test -p vergen-pretty -F __vergen_test,header,serde,trace; and \ +cargo test -p vergen-pretty -F __vergen_test,color,header,serde,trace; and \ cargo doc -p vergen -F build,cargo,git,gitcl,rustc,si; and \ -cargo doc -p vergen-pretty -F color,trace +cargo doc -p vergen-pretty -F color,header,trace diff --git a/vergen-pretty/Cargo.toml b/vergen-pretty/Cargo.toml index 072eea0b..d5782801 100644 --- a/vergen-pretty/Cargo.toml +++ b/vergen-pretty/Cargo.toml @@ -10,15 +10,16 @@ license = "MIT OR Apache-2.0" name = "vergen-pretty" readme = "README.md" repository = "https://github.com/rustyhorde/vergen" -version = "0.1.2" +version = "0.2.0" [package.metadata.cargo-all-features] -denylist = ["console", "lazy_static", "serde", "tracing", "unstable", "vergen"] +denylist = ["console", "lazy_static", "serde", "tracing", "unstable", "vergen", "rand"] [features] default = [] unstable = [] color = ["console", "lazy_static"] +header = ["console", "rand"] trace = ["tracing"] __vergen_test = ["vergen"] @@ -28,6 +29,7 @@ console = { version = "0.15.5", optional = true } convert_case = "0.6.0" derive_builder = "0.12.0" lazy_static = { version = "1.4.0", optional = true } +rand = { version = "0.8.5", optional = true } serde = { version = "1.0.160", features = ["derive"], optional = true } tracing = { version = "0.1.37", features = [ "max_level_trace", @@ -47,6 +49,8 @@ vergen = { version = "8.1.0", path = "../vergen", features = [ ], optional = true } [dev-dependencies] +lazy_static = "1.4.0" +regex = "1.8.1" serde_json = "1.0.96" tracing-subscriber = { version = "0.3.17", features = ["fmt"] } diff --git a/vergen-pretty/src/header/mod.rs b/vergen-pretty/src/header/mod.rs new file mode 100644 index 00000000..3d3c02e5 --- /dev/null +++ b/vergen-pretty/src/header/mod.rs @@ -0,0 +1,177 @@ +// Copyright (c) 2022 pud developers +// +// Licensed under the Apache License, Version 2.0 +// or the MIT +// license , at your +// option. All files in the project carrying such notice may not be copied, +// modified, or distributed except according to those terms. + +// Header + +use crate::{vergen_pretty_env, PrefixBuilder, PrettyBuilder}; + +use anyhow::Result; +use console::Style; +use rand::Rng; +use std::io::Write; + +fn from_u8(val: u8) -> Style { + let style = Style::new(); + match val { + 0 => style.green(), + 1 => style.yellow(), + 2 => style.blue(), + 3 => style.magenta(), + 4 => style.cyan(), + 5 => style.white(), + _ => style.red(), + } +} + +/// Generate a pretty header +/// +/// # Errors +/// +pub fn header(prefix: &'static str, writer: Option<&mut T>) -> Result<()> +where + T: Write + ?Sized, +{ + let mut rng = rand::thread_rng(); + let app_style = from_u8(rng.gen_range(0..7)); + if let Some(writer) = writer { + output_to_writer(writer, app_style.clone(), prefix)?; + } + trace(app_style, prefix)?; + Ok(()) +} + +#[cfg(feature = "color")] +fn output_to_writer(writer: &mut T, app_style: Style, prefix: &'static str) -> Result<()> +where + T: Write + ?Sized, +{ + let prefix = PrefixBuilder::default() + .lines(prefix.lines().map(str::to_string).collect()) + .style(app_style) + .build()?; + PrettyBuilder::default() + .env(vergen_pretty_env!()) + .prefix(prefix) + .build()? + .display(writer)?; + Ok(()) +} + +#[cfg(not(feature = "color"))] +fn output_to_writer(writer: &mut T, _app_style: Style, prefix: &'static str) -> Result<()> +where + T: Write + ?Sized, +{ + let prefix = PrefixBuilder::default() + .lines(prefix.lines().map(str::to_string).collect()) + .build()?; + PrettyBuilder::default() + .env(vergen_pretty_env!()) + .prefix(prefix) + .build()? + .display(writer)?; + Ok(()) +} + +#[cfg(all(feature = "trace", feature = "color"))] +fn trace(app_style: Style, prefix: &'static str) -> Result<()> { + let prefix = PrefixBuilder::default() + .lines(prefix.lines().map(str::to_string).collect()) + .style(app_style) + .build()?; + PrettyBuilder::default() + .env(vergen_pretty_env!()) + .prefix(prefix) + .build()? + .trace(); + Ok(()) +} + +#[cfg(all(feature = "trace", not(feature = "color")))] +fn trace(_app_style: Style, prefix: &'static str) -> Result<()> { + let prefix = PrefixBuilder::default() + .lines(prefix.lines().map(str::to_string).collect()) + .build()?; + PrettyBuilder::default() + .env(vergen_pretty_env!()) + .prefix(prefix) + .build()? + .trace(); + Ok(()) +} + +#[cfg(not(feature = "trace"))] +fn trace(_app_style: Style, _prefix: &'static str) -> Result<()> { + Ok(()) +} + +#[cfg(test)] +mod test { + use super::from_u8; + #[cfg(feature = "__vergen_test")] + use super::header; + use console::Style; + use lazy_static::lazy_static; + use regex::Regex; + + #[cfg(feature = "__vergen_test")] + const HEADER_PREFIX: &str = r#"██████╗ ██╗ ██╗██████╗ ██╗ ██╗ +██╔══██╗██║ ██║██╔══██╗██║ ██║ +██████╔╝██║ ██║██║ ██║██║ █╗ ██║ +██╔═══╝ ██║ ██║██║ ██║██║███╗██║ +██║ ╚██████╔╝██████╔╝╚███╔███╔╝ +╚═╝ ╚═════╝ ╚═════╝ ╚══╝╚══╝ + +4a61736f6e204f7a696173 +"#; + + lazy_static! { + static ref BUILD_TIMESTAMP: Regex = Regex::new(r#"Timestamp \( build\)"#).unwrap(); + static ref BUILD_SEMVER: Regex = Regex::new(r#"Semver \( rustc\)"#).unwrap(); + static ref GIT_BRANCH: Regex = Regex::new(r#"Branch \( git\)"#).unwrap(); + } + + #[test] + fn from_u8_works() { + assert_eq!(from_u8(0), Style::new().green()); + assert_eq!(from_u8(1), Style::new().yellow()); + assert_eq!(from_u8(2), Style::new().blue()); + assert_eq!(from_u8(3), Style::new().magenta()); + assert_eq!(from_u8(4), Style::new().cyan()); + assert_eq!(from_u8(5), Style::new().white()); + assert_eq!(from_u8(6), Style::new().red()); + assert_eq!(from_u8(7), Style::new().red()); + } + + #[test] + #[cfg(debug_assertions)] + #[cfg(feature = "__vergen_test")] + fn header_writes() { + let mut buf = vec![]; + assert!(header(HEADER_PREFIX, Some(&mut buf)).is_ok()); + assert!(!buf.is_empty()); + let header_str = String::from_utf8_lossy(&buf); + println!("{header_str}"); + assert!(BUILD_TIMESTAMP.is_match(&header_str)); + assert!(BUILD_SEMVER.is_match(&header_str)); + assert!(GIT_BRANCH.is_match(&header_str)); + } + + #[test] + #[cfg(not(debug_assertions))] + #[cfg(feature = "__vergen_test")] + fn header_writes() { + let mut buf = vec![]; + assert!(header(&TestConfig::default(), HEADER_PREFIX, Some(&mut buf)).is_ok()); + assert!(!buf.is_empty()); + let header_str = String::from_utf8_lossy(&buf); + assert!(BUILD_TIMESTAMP.is_match(&header_str)); + assert!(BUILD_SEMVER.is_match(&header_str)); + assert!(GIT_BRANCH.is_match(&header_str)); + } +} diff --git a/vergen-pretty/src/lib.rs b/vergen-pretty/src/lib.rs index 7791b9bd..2e1ac22e 100644 --- a/vergen-pretty/src/lib.rs +++ b/vergen-pretty/src/lib.rs @@ -252,11 +252,15 @@ deny(rustdoc::missing_doc_code_examples) )] +#[cfg(feature = "header")] +mod header; mod pretty; mod utils; #[cfg(feature = "color")] pub use console::Style; +#[cfg(feature = "header")] +pub use header::header; pub use pretty::prefix::Prefix; pub use pretty::prefix::PrefixBuilder; pub use pretty::suffix::Suffix; @@ -267,6 +271,10 @@ pub use pretty::PrettyBuilderError; #[cfg(feature = "trace")] pub use tracing::Level; +#[cfg(all(test, not(feature = "header")))] +use lazy_static as _; +#[cfg(all(test, not(feature = "header")))] +use regex as _; #[cfg(all(test, not(feature = "serde")))] use serde_json as _; #[cfg(all(test, not(feature = "trace")))] diff --git a/vergen-pretty/tarpaulin.toml b/vergen-pretty/tarpaulin.toml index bcb83791..11db0bef 100644 --- a/vergen-pretty/tarpaulin.toml +++ b/vergen-pretty/tarpaulin.toml @@ -2,4 +2,4 @@ features = "__vergen_test" [all] -features = "__vergen_test color serde trace" \ No newline at end of file +features = "__vergen_test color header serde trace" \ No newline at end of file