diff --git a/Cargo.lock b/Cargo.lock index fb3edb2..e46ac01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,7 +131,7 @@ dependencies = [ "actix-utils", "futures-core", "futures-util", - "mio 1.0.3", + "mio", "socket2", "tokio", "tracing", @@ -826,15 +826,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" -[[package]] -name = "colored" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -846,15 +837,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width 0.1.14", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -987,31 +978,6 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[package]] -name = "crossterm" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio 0.8.11", - "parking_lot", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -1241,9 +1207,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" @@ -1564,15 +1530,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fuzzy-matcher" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" -dependencies = [ - "thread_local", -] - [[package]] name = "fxhash" version = "0.2.1" @@ -2910,9 +2867,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ "bitflags 2.6.0", - "crossterm", + "console", "dyn-clone", - "fuzzy-matcher", "fxhash", "newline-converter", "once_cell", @@ -3301,18 +3257,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "mio" version = "1.0.3" @@ -3679,7 +3623,7 @@ dependencies = [ "async_zip", "chrono", "clap", - "colored", + "console", "dirs", "fs-err", "full_moon", @@ -3690,6 +3634,7 @@ dependencies = [ "inquire", "keyring", "open", + "paste", "pathdiff", "relative-path", "reqwest", @@ -3711,7 +3656,7 @@ dependencies = [ "url", "urlencoding", "wax", - "winreg", + "windows-registry 0.4.0", ] [[package]] @@ -4187,7 +4132,7 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "windows-registry", + "windows-registry 0.2.0", ] [[package]] @@ -4724,27 +4669,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio 0.8.11", - "signal-hook", -] - [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -5170,7 +5094,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -5764,11 +5688,22 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-result", - "windows-strings", + "windows-result 0.2.0", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result 0.3.0", + "windows-strings 0.3.0", + "windows-targets 0.53.0", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -5778,23 +5713,32 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08106ce80268c4067c0571ca55a9b4e9516518eaa1a1fe9b37ca403ae1d1a34" +dependencies = [ + "windows-targets 0.53.0", +] + [[package]] name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-strings" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "b888f919960b42ea4e11c2f408fadb55f78a9f236d5eef084103c8ce52893491" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.53.0", ] [[package]] @@ -5815,21 +5759,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -5839,7 +5768,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -5847,10 +5776,20 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-targets" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] [[package]] name = "windows_aarch64_gnullvm" @@ -5859,10 +5798,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows_aarch64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" @@ -5871,10 +5810,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_i686_gnu" -version = "0.48.5" +name = "windows_aarch64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" @@ -5882,6 +5821,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" @@ -5889,10 +5834,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" @@ -5901,10 +5846,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +name = "windows_i686_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -5913,10 +5858,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" +name = "windows_x86_64_gnu" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" @@ -5925,10 +5870,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +name = "windows_x86_64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" @@ -5936,6 +5881,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.6.20" @@ -5945,16 +5896,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.55.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" -dependencies = [ - "cfg-if", - "windows-sys 0.59.0", -] - [[package]] name = "write16" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 320d295..6214662 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,13 +17,14 @@ bin = [ "dep:indicatif", "dep:inquire", "dep:toml_edit", - "dep:colored", + "dep:console", "dep:anyhow", "dep:keyring", "dep:open", - "gix/worktree-mutation", + "dep:paste", "dep:serde_json", - "dep:winreg", + "dep:windows-registry", + "gix/worktree-mutation", "fs-err/expose_original_error", "tokio/rt", "tokio/rt-multi-thread", @@ -79,16 +80,17 @@ schemars = { git = "https://github.com/daimond113/schemars", rev = "bc7c7d6", fe anyhow = { version = "1.0.95", optional = true } open = { version = "5.3.2", optional = true } keyring = { version = "3.6.1", features = ["crypto-rust", "windows-native", "apple-native", "async-secret-service", "async-io"], optional = true } -colored = { version = "3.0.0", optional = true } +console = { version = "0.15.10", optional = true } toml_edit = { version = "0.22.22", optional = true } clap = { version = "4.5.26", features = ["derive"], optional = true } dirs = { version = "6.0.0", optional = true } tracing-subscriber = { version = "0.3.19", features = ["env-filter"], optional = true } indicatif = { version = "0.17.9", optional = true } -inquire = { version = "0.7.5", optional = true } +inquire = { version = "0.7.5", default-features = false, features = ["console", "one-liners"], optional = true } +paste = { version = "1.0.15", optional = true } [target.'cfg(target_os = "windows")'.dependencies] -winreg = { version = "0.55.0", optional = true } +windows-registry = { version = "0.4.0", optional = true } [workspace] resolver = "2" diff --git a/src/cli/commands/add.rs b/src/cli/commands/add.rs index 45848ae..6bef863 100644 --- a/src/cli/commands/add.rs +++ b/src/cli/commands/add.rs @@ -2,7 +2,6 @@ use std::str::FromStr; use anyhow::Context; use clap::Args; -use colored::Colorize; use semver::VersionReq; use crate::cli::{config::read_config, AnyPackageIdentifier, VersionedPackageName}; @@ -64,8 +63,7 @@ impl AddCommand { .cloned(); if let Some(index) = self.index.as_ref().filter(|_| index.is_none()) { - println!("{}: index {index} not found", "error".red().bold()); - return Ok(()); + anyhow::bail!("index {index} not found"); } let index = match index { @@ -91,8 +89,7 @@ impl AddCommand { .cloned(); if let Some(index) = self.index.as_ref().filter(|_| index.is_none()) { - println!("{}: wally index {index} not found", "error".red().bold()); - return Ok(()); + anyhow::bail!("wally index {index} not found"); } let index = index.context("no wally index found")?; @@ -159,9 +156,7 @@ impl AddCommand { .pop_last() .map(|(v_id, _)| v_id) else { - println!("{}: no versions found for package", "error".red().bold()); - - return Ok(()); + anyhow::bail!("no versions found for package"); }; let project_target = manifest.target.kind(); diff --git a/src/cli/commands/auth/login.rs b/src/cli/commands/auth/login.rs index fa1b6e9..429aec8 100644 --- a/src/cli/commands/auth/login.rs +++ b/src/cli/commands/auth/login.rs @@ -1,12 +1,15 @@ use anyhow::Context; use clap::Args; -use colored::Colorize; +use console::style; use serde::Deserialize; use std::thread::spawn; use tokio::time::sleep; use url::Url; -use crate::cli::auth::{get_token_login, set_token}; +use crate::cli::{ + auth::{get_token_login, set_token}, + style::URL_STYLE, +}; use pesde::{ source::{ pesde::PesdePackageSource, @@ -89,8 +92,8 @@ impl LoginCommand { println!( "copy your one-time code: {}\npress enter to open {} in your browser...", - response.user_code.bold(), - response.verification_uri.as_str().blue() + style(response.user_code).bold(), + URL_STYLE.apply_to(response.verification_uri.as_str()) ); spawn(move || { @@ -184,7 +187,7 @@ impl LoginCommand { let token = format!("Bearer {token}"); println!( "logged in as {} for {index_url}", - get_token_login(&reqwest, &token).await?.bold() + style(get_token_login(&reqwest, &token).await?).bold() ); token diff --git a/src/cli/commands/auth/whoami.rs b/src/cli/commands/auth/whoami.rs index cf8ad5f..bc7d7cc 100644 --- a/src/cli/commands/auth/whoami.rs +++ b/src/cli/commands/auth/whoami.rs @@ -1,6 +1,6 @@ use crate::cli::auth::{get_token_login, get_tokens}; use clap::Args; -use colored::Colorize; +use console::style; #[derive(Debug, Args)] pub struct WhoAmICommand {} @@ -18,7 +18,7 @@ impl WhoAmICommand { println!( "logged in as {} into {index_url}", - get_token_login(&reqwest, token).await?.bold() + style(get_token_login(&reqwest, token).await?).bold() ); Ok(()) diff --git a/src/cli/commands/deprecate.rs b/src/cli/commands/deprecate.rs index 658729e..317884d 100644 --- a/src/cli/commands/deprecate.rs +++ b/src/cli/commands/deprecate.rs @@ -1,7 +1,6 @@ use crate::cli::get_index; use anyhow::Context; use clap::Args; -use colored::Colorize; use pesde::{ names::PackageName, source::{ @@ -83,20 +82,10 @@ impl DeprecateCommand { let prefix = if self.undo { "un" } else { "" }; match status { StatusCode::CONFLICT => { - println!( - "{}", - format!("version is already {prefix}deprecated") - .red() - .bold() - ); + anyhow::bail!("version is already {prefix}deprecated"); } StatusCode::FORBIDDEN => { - println!( - "{}", - format!("unauthorized to {prefix}deprecate under this scope") - .red() - .bold() - ); + anyhow::bail!("unauthorized to {prefix}deprecate under this scope"); } code if !code.is_success() => { anyhow::bail!("failed to {prefix}deprecate package: {code} ({text})"); diff --git a/src/cli/commands/execute.rs b/src/cli/commands/execute.rs index c701ede..fc5d4cc 100644 --- a/src/cli/commands/execute.rs +++ b/src/cli/commands/execute.rs @@ -5,7 +5,7 @@ use crate::cli::{ }; use anyhow::Context; use clap::Args; -use colored::Colorize; +use console::style; use fs_err::tokio as fs; use indicatif::MultiProgress; use pesde::{ @@ -190,7 +190,7 @@ impl ExecuteCommand { .context("failed to build dependency graph")?; multi_progress.suspend(|| { - eprintln!("{}", format!("using {}", format!("{id}").bold()).dimmed()) + eprintln!("{}", style(format!("using {}", style(id).bold())).dim()); }); root_progress.reset(); diff --git a/src/cli/commands/init.rs b/src/cli/commands/init.rs index 17895e4..5dc8cc5 100644 --- a/src/cli/commands/init.rs +++ b/src/cli/commands/init.rs @@ -1,7 +1,9 @@ -use crate::cli::config::read_config; +use crate::cli::{ + config::read_config, + style::{ERROR_PREFIX, INFO_STYLE, SUCCESS_STYLE}, +}; use anyhow::Context; use clap::Args; -use colored::Colorize; use inquire::validator::Validation; use pesde::{ errors::ManifestReadError, @@ -42,8 +44,7 @@ impl InitCommand { pub async fn run(self, project: Project) -> anyhow::Result<()> { match project.read_manifest().await { Ok(_) => { - println!("{}", "project already initialized".red()); - return Ok(()); + anyhow::bail!("project already initialized"); } Err(ManifestReadError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => return Err(e.into()), @@ -133,10 +134,8 @@ impl InitCommand { let refreshed_sources = RefreshedSources::new(); if target_env.is_roblox() - || inquire::prompt_confirmation( - "would you like to setup Roblox compatibility scripts?", - ) - .unwrap() + || inquire::prompt_confirmation("would you like to setup Roblox compatibility scripts?") + .unwrap() { refreshed_sources .refresh( @@ -270,8 +269,7 @@ impl InitCommand { } } else { println!( - "{}", - "no scripts package configured, this can cause issues with Roblox compatibility".red() + "{ERROR_PREFIX}: no scripts package configured, this can cause issues with Roblox compatibility" ); if !inquire::prompt_confirmation("initialize regardless?").unwrap() { return Ok(()); @@ -283,8 +281,8 @@ impl InitCommand { println!( "{}\n{}: run `install` to fully finish setup", - "initialized project".green(), - "tip".cyan().bold() + SUCCESS_STYLE.apply_to("initialized project"), + INFO_STYLE.apply_to("tip") ); Ok(()) } diff --git a/src/cli/commands/patch.rs b/src/cli/commands/patch.rs index 1da6f3d..e75c9bc 100644 --- a/src/cli/commands/patch.rs +++ b/src/cli/commands/patch.rs @@ -1,9 +1,12 @@ use std::sync::Arc; -use crate::cli::{up_to_date_lockfile, VersionedPackageName}; +use crate::cli::{ + style::{CLI_STYLE, INFO_STYLE, WARN_PREFIX}, + up_to_date_lockfile, VersionedPackageName, +}; use anyhow::Context; use clap::Args; -use colored::Colorize; +use console::style; use fs_err::tokio as fs; use pesde::{ patches::setup_patches_repo, @@ -68,17 +71,13 @@ impl PatchCommand { setup_patches_repo(&directory)?; println!( - concat!( - "done! modify the files in the directory, then run `", - env!("CARGO_BIN_NAME"), - r#" patch-commit {}` to apply. -{}: do not commit these changes -{}: the {} file will be ignored when patching"# - ), - directory.display().to_string().bold().cyan(), - "warning".yellow(), - "note".blue(), - MANIFEST_FILE_NAME + r#"done! modify the files in the directory, then run {} {}{} to apply. +{WARN_PREFIX}: do not commit these changes +{}: the {MANIFEST_FILE_NAME} file will be ignored when patching"#, + CLI_STYLE.apply_to(concat!("`", env!("CARGO_BIN_NAME"), " patch-commit")), + style(format!("'{}'", directory.display())).cyan().bold(), + CLI_STYLE.apply_to("`"), + INFO_STYLE.apply_to("note") ); open::that(directory)?; diff --git a/src/cli/commands/publish.rs b/src/cli/commands/publish.rs index da057d8..3c879e0 100644 --- a/src/cli/commands/publish.rs +++ b/src/cli/commands/publish.rs @@ -1,8 +1,12 @@ -use crate::cli::{display_err, run_on_workspace_members, up_to_date_lockfile}; +use crate::cli::{ + display_err, run_on_workspace_members, + style::{ERROR_PREFIX, ERROR_STYLE, SUCCESS_STYLE, WARN_PREFIX}, + up_to_date_lockfile, +}; use anyhow::Context; use async_compression::Level; use clap::Args; -use colored::Colorize; +use console::style; use fs_err::tokio as fs; use pesde::{ manifest::{target::Target, DependencyType}, @@ -56,10 +60,9 @@ impl PublishCommand { if let Err(err) = full_moon::parse(contents) { eprintln!( - "{}: {name} is not a valid Luau file:\n{}", - "error".red().bold(), + "{ERROR_PREFIX}: {name} is not a valid Luau file:\n{}", err.into_iter() - .map(|err| format!("\t- {err}")) + .map(|err| format!("\t- {}", ERROR_STYLE.apply_to(err))) .collect::>() .join("\n") ); @@ -84,14 +87,20 @@ impl PublishCommand { println!( "\n{}\n", - format!("[now publishing {} {}]", manifest.name, manifest.target) - .bold() - .on_bright_black() + style(format!( + "[now publishing {} {}]", + manifest.name, manifest.target + )) + .bold() + .on_black() ); if manifest.private { if !is_root { - println!("{}", "package is private, cannot publish".red().bold()); + println!( + "{}", + ERROR_STYLE.apply_to("package is private, cannot publish") + ); } return Ok(()); @@ -209,10 +218,7 @@ impl PublishCommand { .context("failed to get included files")?; if paths.insert(PathBuf::from(MANIFEST_FILE_NAME)) { - println!( - "{}: {MANIFEST_FILE_NAME} was not included, adding it", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: {MANIFEST_FILE_NAME} was not included, adding it",); } if paths.iter().any(|p| p.starts_with(".git")) { @@ -225,17 +231,11 @@ impl PublishCommand { "readme" | "readme.md" | "readme.txt" ) }) { - println!( - "{}: no README file included, consider adding one", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: no README file included, consider adding one",); } if !paths.iter().any(|p| p.starts_with("docs")) { - println!( - "{}: docs directory not included, consider adding one", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: docs directory not included, consider adding one",); } for path in &paths { @@ -306,20 +306,14 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p .unwrap() .to_path_buf(), ) { - println!( - "{}: {name} was not included, adding {relative_export_path}", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: {name} was not included, adding {relative_export_path}",); } if roblox_target .as_mut() .is_some_and(|build_files| build_files.insert(first_part.to_string())) { - println!( - "{}: {name} was not in build files, adding {first_part}", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: {name} was not in build files, adding {first_part}",); } } @@ -327,8 +321,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p for build_file in build_files.iter() { if build_file.eq_ignore_ascii_case(MANIFEST_FILE_NAME) { println!( - "{}: {MANIFEST_FILE_NAME} is in build files, please remove it", - "warn".yellow().bold() + "{WARN_PREFIX}: {MANIFEST_FILE_NAME} is in build files, please remove it", ); continue; @@ -381,10 +374,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p .unwrap() .to_path_buf(), ) { - println!( - "{}: script {name} was not included, adding {path}", - "warn".yellow().bold() - ); + println!("{WARN_PREFIX}: script {name} was not included, adding {path}",); } } } @@ -521,7 +511,10 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p } { - println!("\n{}", "please confirm the following information:".bold()); + println!( + "\n{}", + style("please confirm the following information:").bold() + ); println!("name: {}", manifest.name); println!("version: {}", manifest.version); println!( @@ -594,7 +587,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p if !self.dry_run && !self.yes && !inquire::Confirm::new("is this information correct?").prompt()? { - println!("\n{}", "publish aborted".red().bold()); + println!("\n{}", ERROR_STYLE.apply_to("publish aborted")); return Ok(()); } @@ -670,7 +663,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p println!( "{}", - "(dry run) package written to package.tar.gz".green().bold() + SUCCESS_STYLE.apply_to("(dry run) package written to package.tar.gz") ); return Ok(()); @@ -694,22 +687,19 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p .context("failed to get response text")?; match status { StatusCode::CONFLICT => { - println!("{}", "package version already exists".red().bold()); + anyhow::bail!("package version already exists"); } StatusCode::FORBIDDEN => { - println!( - "{}", - "unauthorized to publish under this scope".red().bold() - ); + anyhow::bail!("unauthorized to publish under this scope"); } StatusCode::BAD_REQUEST => { - println!("{}: {text}", "invalid package".red().bold()); + anyhow::bail!("invalid package: {text}"); } code if !code.is_success() => { anyhow::bail!("failed to publish package: {code} ({text})"); } _ => { - println!("{text}"); + println!("{}", SUCCESS_STYLE.apply_to(text)); } } diff --git a/src/cli/commands/self_install.rs b/src/cli/commands/self_install.rs index 84eb4a1..5e30f97 100644 --- a/src/cli/commands/self_install.rs +++ b/src/cli/commands/self_install.rs @@ -1,7 +1,11 @@ -use crate::cli::{version::replace_pesde_bin_exe, HOME_DIR}; +use crate::cli::{ + style::{ADDED_STYLE, CLI_STYLE}, + version::replace_pesde_bin_exe, + HOME_DIR, +}; use anyhow::Context; use clap::Args; -use colored::Colorize; +use console::style; use std::env::current_exe; #[derive(Debug, Args)] @@ -17,15 +21,14 @@ impl SelfInstallCommand { #[cfg(windows)] { if !self.skip_add_to_path { + use crate::cli::style::WARN_STYLE; use anyhow::Context; - use winreg::{enums::HKEY_CURRENT_USER, RegKey}; + use windows_registry::CURRENT_USER; - let current_user = RegKey::predef(HKEY_CURRENT_USER); - let env = current_user - .create_subkey("Environment") - .context("failed to open Environment key")? - .0; - let path: String = env.get_value("Path").context("failed to get Path value")?; + let env = CURRENT_USER + .create("Environment") + .context("failed to open Environment key")?; + let path = env.get_string("Path").context("failed to get Path value")?; let bin_dir = crate::cli::bin_dir().await?; let bin_dir = bin_dir.to_string_lossy(); @@ -34,23 +37,21 @@ impl SelfInstallCommand { if !exists { let new_path = format!("{path};{bin_dir}"); - env.set_value("Path", &new_path) + env.set_string("Path", &new_path) .context("failed to set Path value")?; println!( - "\nin order to allow binary exports as executables {}.\n\n{}", - format!("`~/{HOME_DIR}/bin` was added to PATH").green(), - "please restart your shell for this to take effect" - .yellow() - .bold() + "\nin order to allow proper functionality {} was added to PATH.\n\n{}", + style(format!("`~/{HOME_DIR}/bin`")).green(), + WARN_STYLE.apply_to("please restart your shell for this to take effect") ); } } println!( "installed {} {}!", - env!("CARGO_BIN_NAME").cyan(), - env!("CARGO_PKG_VERSION").yellow(), + CLI_STYLE.apply_to(env!("CARGO_BIN_NAME")), + ADDED_STYLE.apply_to(env!("CARGO_PKG_VERSION")), ); } @@ -63,11 +64,9 @@ impl SelfInstallCommand { and then restart your shell. "#, - env!("CARGO_BIN_NAME").cyan(), - env!("CARGO_PKG_VERSION").yellow(), - format!(r#"export PATH="$PATH:~/{HOME_DIR}/bin""#) - .bold() - .green() + CLI_STYLE.apply_to(env!("CARGO_BIN_NAME")), + ADDED_STYLE.apply_to(env!("CARGO_PKG_VERSION")), + style(format!(r#"export PATH="$PATH:$HOME/{HOME_DIR}/bin""#)).green(), ); } diff --git a/src/cli/commands/self_upgrade.rs b/src/cli/commands/self_upgrade.rs index 0ad5f6a..2578f8b 100644 --- a/src/cli/commands/self_upgrade.rs +++ b/src/cli/commands/self_upgrade.rs @@ -1,6 +1,7 @@ use crate::{ cli::{ config::read_config, + style::{ADDED_STYLE, CLI_STYLE, REMOVED_STYLE}, version::{ current_version, find_latest_version, get_or_download_engine, replace_pesde_bin_exe, }, @@ -9,7 +10,6 @@ use crate::{ }; use anyhow::Context; use clap::Args; -use colored::Colorize; use pesde::engine::EngineKind; use semver::VersionReq; @@ -39,13 +39,14 @@ impl SelfUpgradeCommand { return Ok(()); } - let display_latest_version = latest_version_no_metadata.to_string().yellow().bold(); + let display_latest_version = ADDED_STYLE.apply_to(latest_version_no_metadata); - if !inquire::prompt_confirmation(format!( + let confirmed = inquire::prompt_confirmation(format!( "are you sure you want to upgrade {} from {} to {display_latest_version}?", - env!("CARGO_BIN_NAME").cyan(), - env!("CARGO_PKG_VERSION").yellow().bold() - ))? { + CLI_STYLE.apply_to(env!("CARGO_BIN_NAME")), + REMOVED_STYLE.apply_to(env!("CARGO_PKG_VERSION")) + ))?; + if !confirmed { println!("cancelled upgrade"); return Ok(()); } diff --git a/src/cli/commands/yank.rs b/src/cli/commands/yank.rs index 4a4ad3b..562df80 100644 --- a/src/cli/commands/yank.rs +++ b/src/cli/commands/yank.rs @@ -1,7 +1,6 @@ -use crate::cli::get_index; +use crate::cli::{get_index, style::SUCCESS_STYLE}; use anyhow::Context; use clap::Args; -use colored::Colorize; use pesde::{ manifest::target::TargetKind, names::PackageName, @@ -131,24 +130,16 @@ impl YankCommand { let prefix = if self.undo { "un" } else { "" }; match status { StatusCode::CONFLICT => { - println!( - "{}", - format!("version is already {prefix}yanked").red().bold() - ); + anyhow::bail!("version is already {prefix}yanked"); } StatusCode::FORBIDDEN => { - println!( - "{}", - format!("unauthorized to {prefix}yank under this scope") - .red() - .bold() - ); + anyhow::bail!("unauthorized to {prefix}yank under this scope"); } code if !code.is_success() => { anyhow::bail!("failed to {prefix}yank package: {code} ({text})"); } _ => { - println!("{text}"); + println!("{}", SUCCESS_STYLE.apply_to(text)); } } diff --git a/src/cli/install.rs b/src/cli/install.rs index 5a4aeea..a1bdb49 100644 --- a/src/cli/install.rs +++ b/src/cli/install.rs @@ -2,10 +2,12 @@ use super::files::make_executable; use crate::cli::{ bin_dir, reporters::{self, CliReporter}, - resolve_overrides, run_on_workspace_members, up_to_date_lockfile, + resolve_overrides, run_on_workspace_members, + style::{ADDED_STYLE, REMOVED_STYLE, WARN_PREFIX}, + up_to_date_lockfile, }; use anyhow::Context; -use colored::Colorize; +use console::style; use fs_err::tokio as fs; use pesde::{ download_and_link::{DownloadAndLinkHooks, DownloadAndLinkOptions}, @@ -258,7 +260,7 @@ pub async fn install( }; multi.suspend(|| { - println!("{}: package {name} is deprecated: {reason}", "warn".yellow().bold()); + println!("{WARN_PREFIX}: package {name} is deprecated: {reason}"); }); } @@ -394,7 +396,7 @@ pub async fn install( if !version_matches(&req, version) { multi.suspend(|| { - println!("{}: package {id} requires {engine} {req}, but {version} is installed", "warn".yellow().bold()); + println!("{WARN_PREFIX}: package {id} requires {engine} {req}, but {version} is installed"); }); } } @@ -485,7 +487,7 @@ pub fn print_package_diff(prefix: &str, old_graph: DependencyGraph, new_graph: D .map(|(key, &node)| (key, node)) .collect::>(); - let prefix = prefix.bold(); + let prefix = style(prefix).bold(); let no_changes = added_pkgs.is_empty() && removed_pkgs.is_empty() @@ -496,9 +498,16 @@ pub fn print_package_diff(prefix: &str, old_graph: DependencyGraph, new_graph: D println!("{prefix} already up to date"); } else { let mut change_signs = [ - (!added_pkgs.is_empty()).then(|| format!("+{}", added_pkgs.len()).green().to_string()), - (!removed_pkgs.is_empty()) - .then(|| format!("-{}", removed_pkgs.len()).red().to_string()), + (!added_pkgs.is_empty()).then(|| { + ADDED_STYLE + .apply_to(format!("+{}", added_pkgs.len())) + .to_string() + }), + (!removed_pkgs.is_empty()).then(|| { + REMOVED_STYLE + .apply_to(format!("-{}", removed_pkgs.len())) + .to_string() + }), ] .into_iter() .flatten() @@ -507,7 +516,7 @@ pub fn print_package_diff(prefix: &str, old_graph: DependencyGraph, new_graph: D let changes_empty = change_signs.is_empty(); if changes_empty { - change_signs = "(no changes)".dimmed().to_string(); + change_signs = style("(no changes)").dim().to_string(); } println!("{prefix} {change_signs}"); @@ -515,8 +524,8 @@ pub fn print_package_diff(prefix: &str, old_graph: DependencyGraph, new_graph: D if !changes_empty { println!( "{}{}", - "+".repeat(added_pkgs.len()).green(), - "-".repeat(removed_pkgs.len()).red() + ADDED_STYLE.apply_to("+".repeat(added_pkgs.len())), + REMOVED_STYLE.apply_to("-".repeat(removed_pkgs.len())) ); } @@ -547,14 +556,18 @@ pub fn print_package_diff(prefix: &str, old_graph: DependencyGraph, new_graph: D DependencyType::Peer => "peer_dependencies", DependencyType::Dev => "dev_dependencies", }; - println!("{}", format!("{ty_name}:").yellow().bold()); + println!("{}", style(format!("{ty_name}:")).yellow().bold()); for (id, added) in set { println!( "{} {} {}", - if added { "+".green() } else { "-".red() }, + if added { + ADDED_STYLE.apply_to("+") + } else { + REMOVED_STYLE.apply_to("-") + }, id.name(), - id.version_id().to_string().dimmed() + style(id.version_id()).dim() ); } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 09fa730..d298bfb 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,6 +1,8 @@ -use crate::cli::config::read_config; +use crate::cli::{ + config::read_config, + style::{ERROR_STYLE, INFO_STYLE, WARN_STYLE}, +}; use anyhow::Context; -use colored::Colorize; use fs_err::tokio as fs; use futures::StreamExt; use pesde::{ @@ -33,6 +35,7 @@ pub mod config; pub mod files; pub mod install; pub mod reporters; +pub mod style; #[cfg(feature = "version-management")] pub mod version; @@ -284,14 +287,17 @@ pub async fn run_on_workspace_members>>( pub fn display_err(result: anyhow::Result<()>, prefix: &str) { if let Err(err) = result { - eprintln!("{}: {err}\n", format!("error{prefix}").red().bold()); + eprintln!( + "{}: {err}\n", + ERROR_STYLE.apply_to(format!("error{prefix}")) + ); let cause = err.chain().skip(1).collect::>(); if !cause.is_empty() { - eprintln!("{}:", "caused by".red().bold()); + eprintln!("{}:", ERROR_STYLE.apply_to("caused by")); for err in cause { - eprintln!(" - {err}"); + eprintln!("\t- {}", ERROR_STYLE.apply_to(err)); } } @@ -300,14 +306,14 @@ pub fn display_err(result: anyhow::Result<()>, prefix: &str) { std::backtrace::BacktraceStatus::Disabled => { eprintln!( "\n{}: set RUST_BACKTRACE=1 for a backtrace", - "help".yellow().bold() + INFO_STYLE.apply_to("help") ); } std::backtrace::BacktraceStatus::Captured => { - eprintln!("\n{}:\n{backtrace}", "backtrace".yellow().bold()); + eprintln!("\n{}:\n{backtrace}", WARN_STYLE.apply_to("backtrace")); } _ => { - eprintln!("\n{}: not captured", "backtrace".yellow().bold()); + eprintln!("\n{}: not captured", WARN_STYLE.apply_to("backtrace")); } } } diff --git a/src/cli/reporters.rs b/src/cli/reporters.rs index 8f88768..4f7bdf4 100644 --- a/src/cli/reporters.rs +++ b/src/cli/reporters.rs @@ -7,7 +7,6 @@ use std::{ time::Duration, }; -use colored::Colorize; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use pesde::reporters::{ DownloadProgressReporter, DownloadsReporter, PatchProgressReporter, PatchesReporter, @@ -77,6 +76,7 @@ pub struct CliReporter { } impl CliReporter { + #[allow(unknown_lints, clippy::literal_string_with_formatting_args)] pub fn with_writer( writer: W, multi_progress: MultiProgress, @@ -84,13 +84,13 @@ impl CliReporter { ) -> Self { Self { writer: Mutex::new(writer), - child_style: ProgressStyle::with_template(&"{msg}".dimmed().to_string()).unwrap(), + child_style: ProgressStyle::with_template("{msg:.dim}").unwrap(), child_style_with_bytes: ProgressStyle::with_template( - &"{msg} {bytes}/{total_bytes}".dimmed().to_string(), + "{msg:.dim} {bytes:.dim}/{total_bytes:.dim}", ) .unwrap(), child_style_with_bytes_without_total: ProgressStyle::with_template( - &"{msg} {bytes}".dimmed().to_string(), + "{msg:.dim} {bytes:.dim}", ) .unwrap(), multi_progress, diff --git a/src/cli/style.rs b/src/cli/style.rs new file mode 100644 index 0000000..ecb4dc7 --- /dev/null +++ b/src/cli/style.rs @@ -0,0 +1,54 @@ +use console::{Style, StyledObject}; +use paste::paste; +use std::{fmt::Display, sync::LazyLock}; + +#[derive(Debug)] +pub struct LazyStyle(LazyLock); + +impl LazyStyle