refactor: the style system has been changed and replaced functions (printc, colored) have been removed in src/utils/cli_styles.rs. Most files in src/cli have been heavily modified to migrate to the new system

This commit is contained in:
alex-xr555
2026-09-24 01:10:19 +03:00
parent e9d09eacaf
commit 3b6251ec33
15 changed files with 201 additions and 195 deletions

View File

@@ -18,8 +18,9 @@
use crate::prelude::*; use crate::prelude::*;
use crate::core::{build_config::Config, deps::register}; use crate::core::{build_config::Config, deps::register};
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::cli_styles::{Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST};
use crate::utils::fs::find_project_root; use crate::utils::fs::find_project_root;
use crate::utils::log::sprintln;
use toml::{Value, map::Map}; use toml::{Value, map::Map};
/// Parsed arguments for the `dcr add` command. /// Parsed arguments for the `dcr add` command.
@@ -58,16 +59,16 @@ pub struct AddArgs {
/// Process exit code: `0` on success, non-zero on usage or I/O errors. /// Process exit code: `0` on success, non-zero on usage or I/O errors.
pub fn add(args: &[String]) -> i32 { pub fn add(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc( sprintln!(
" dcr add <name> <source> [--branch <b>] [--tag <t>] [--rev <r>]", HELP_EXAMPLES_ST,
BOLD_CYAN, " dcr add <name> <source> [--branch <b>] [--tag <t>] [--rev <r>]"
); );
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Adds a dependency to the project."); println!(" Adds a dependency to the project.");
println!(); println!();
printc("SOURCES:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "SOURCES:");
println!(" github:user/repo GitHub repository"); println!(" github:user/repo GitHub repository");
println!(" gitlab:user/repo GitLab repository"); println!(" gitlab:user/repo GitLab repository");
println!(" git:host.com/user/repo Generic git repository"); println!(" git:host.com/user/repo Generic git repository");
@@ -75,7 +76,7 @@ pub fn add(args: &[String]) -> i32 {
println!(" pkg-config:fmt System pkg-config dependency"); println!(" pkg-config:fmt System pkg-config dependency");
println!(" <version> Version from registry"); println!(" <version> Version from registry");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --branch <b> Use a specific branch"); println!(" --branch <b> Use a specific branch");
println!(" --tag <t> Use a specific tag"); println!(" --tag <t> Use a specific tag");
println!(" --rev <r> Use a specific commit hash"); println!(" --rev <r> Use a specific commit hash");
@@ -165,7 +166,7 @@ pub fn add(args: &[String]) -> i32 {
println!( println!(
" {} dependency `{}` to dcr.toml", " {} dependency `{}` to dcr.toml",
colored("Added", BOLD_GREEN), "Added".style(SUCCESS_ST),
add_args.name add_args.name
); );
0 0

View File

@@ -28,8 +28,11 @@ use crate::utils::build::{
get_config_opt, get_config_str, get_language_with_profile_or_default, get_string_with_profile, get_config_opt, get_config_str, get_language_with_profile_or_default, get_string_with_profile,
normalize_kind, resolve_artifact_target_dir, resolve_compiler, normalize_kind, resolve_artifact_target_dir, resolve_compiler,
}; };
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, BOLD_YELLOW, colored, printc}; use crate::utils::cli_styles::{
BOLD_CYAN, BOLD_YELLOW, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST, Style,
};
use crate::utils::fs::{canonicalize_path, find_project_root}; use crate::utils::fs::{canonicalize_path, find_project_root};
use crate::utils::log::sprintln;
use std::io::IsTerminal; use std::io::IsTerminal;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, atomic::AtomicBool}; use std::sync::{Arc, atomic::AtomicBool};
@@ -37,8 +40,8 @@ use std::sync::{Arc, atomic::AtomicBool};
pub use crate::core::build::get_build_string_with_profile; pub use crate::core::build::get_build_string_with_profile;
/// Formats a left-aligned status verb with the given style for CLI output. /// Formats a left-aligned status verb with the given style for CLI output.
fn status(verb: &str, style: &str) -> String { fn status(verb: &str, style: Style) -> String {
colored(&format!("{verb:<9}"), style) format!("{verb:<9}").style(style).to_string()
} }
/// CLI build reporter that prints human-readable progress to stderr/stdout. /// CLI build reporter that prints human-readable progress to stderr/stdout.
@@ -51,7 +54,7 @@ impl CliReporter {
/// - `verb`: Short status label (e.g. `"target"`, `"dep"`). /// - `verb`: Short status label (e.g. `"target"`, `"dep"`).
/// - `style`: Color/style constant for the verb. /// - `style`: Color/style constant for the verb.
/// - `rest`: Remaining message text after the verb. /// - `rest`: Remaining message text after the verb.
fn line(&self, verb: &str, style: &str, rest: &str) { fn line(&self, verb: &str, style: Style, rest: &str) {
eprintln!(" {} {}", status(verb, style), rest); eprintln!(" {} {}", status(verb, style), rest);
} }
} }
@@ -95,12 +98,12 @@ impl BuildReporter for CliReporter {
common::finish_progress_line(); common::finish_progress_line();
// Only announce deps that were actually rebuilt this run. // Only announce deps that were actually rebuilt this run.
if rebuilt { if rebuilt {
self.line("ready", BOLD_GREEN, &format!("{name} v{version}")); self.line("ready", SUCCESS_ST, &format!("{name} v{version}"));
} }
} }
BuildEvent::Compiling { name, version } => { BuildEvent::Compiling { name, version } => {
common::finish_progress_line(); common::finish_progress_line();
let label = format!(" {} {} v{}", status("compile", BOLD_GREEN), name, version); let label = format!(" {} {} v{}", status("compile", SUCCESS_ST), name, version);
// Terminals use an in-place progress line; non-TTY gets a plain log line. // Terminals use an in-place progress line; non-TTY gets a plain log line.
common::set_progress_label(Some(label.clone())); common::set_progress_label(Some(label.clone()));
if !std::io::stderr().is_terminal() { if !std::io::stderr().is_terminal() {
@@ -113,7 +116,7 @@ impl BuildReporter for CliReporter {
} }
BuildEvent::Finished { secs } => { BuildEvent::Finished { secs } => {
common::finish_progress_line(); common::finish_progress_line();
self.line("done", BOLD_GREEN, &format!("in {secs}s")); self.line("done", SUCCESS_ST, &format!("in {secs}s"));
} }
BuildEvent::CompilerOutput { stream, text } => { BuildEvent::CompilerOutput { stream, text } => {
// Pause the progress spinner so compiler text is not overwritten. // Pause the progress spinner so compiler text is not overwritten.
@@ -141,16 +144,16 @@ impl BuildReporter for CliReporter {
/// Process exit code: `0` on success or help, non-zero on failure. /// Process exit code: `0` on success or help, non-zero on failure.
pub fn build(args: &[String]) -> i32 { pub fn build(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc( sprintln!(
" dcr build [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [--print-artifact-path]", HELP_EXAMPLES_ST,
BOLD_CYAN, " dcr build [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [--print-artifact-path]"
); );
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Compiles the project. Default profile is --debug."); println!(" Compiles the project. Default profile is --debug.");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --debug Build with debug profile (default)"); println!(" --debug Build with debug profile (default)");
println!(" --release Build with release profile"); println!(" --release Build with release profile");
println!(" --target <triple> Cross-compile for the given target"); println!(" --target <triple> Cross-compile for the given target");

View File

@@ -20,8 +20,11 @@ use crate::prelude::*;
use crate::core::build_config::Config; use crate::core::build_config::Config;
use crate::core::workspace::parse_workspace; use crate::core::workspace::parse_workspace;
use crate::utils::build::{default_profile_flags, default_target_triple, parse_version_info}; use crate::utils::build::{default_profile_flags, default_target_triple, parse_version_info};
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::cli_styles::{
BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
};
use crate::utils::fs::{check_dir, find_project_root, with_dir}; use crate::utils::fs::{check_dir, find_project_root, with_dir};
use crate::utils::log::sprintln;
use glob::glob; use glob::glob;
use std::{fs, path::Path}; use std::{fs, path::Path};
@@ -36,16 +39,16 @@ use std::{fs, path::Path};
/// Process exit code: `0` on success, `1` on failure. /// Process exit code: `0` on success, `1` on failure.
pub fn clean(args: &[String]) -> i32 { pub fn clean(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc( sprintln!(
" dcr clean [--debug | --release] [--target <triple>] [--all]", HELP_EXAMPLES_ST,
BOLD_CYAN, " dcr clean [--debug | --release] [--target <triple>] [--all]"
); );
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Removes build artifacts from the target directory."); println!(" Removes build artifacts from the target directory.");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --debug Clean debug artifacts (default)"); println!(" --debug Clean debug artifacts (default)");
println!(" --release Clean release artifacts"); println!(" --release Clean release artifacts");
println!(" --target <triple> Clean artifacts for a specific target"); println!(" --target <triple> Clean artifacts for a specific target");
@@ -210,10 +213,7 @@ fn clean_project_at(
if !items.contains(&"dcr.toml".to_string()) { if !items.contains(&"dcr.toml".to_string()) {
return Err("dcr.toml file not found".to_string()); return Err("dcr.toml file not found".to_string());
} }
println!( println!(" Cleaning project `{}`", project_name.style(BOLD_GREEN));
" Cleaning project `{}`",
colored(&project_name, BOLD_GREEN)
);
if let Some(profile) = profile { if let Some(profile) = profile {
let target_dir = if let Some(t) = target { let target_dir = if let Some(t) = target {
format!("target/{t}/{profile}") format!("target/{t}/{profile}")
@@ -231,14 +231,14 @@ fn clean_project_at(
if !dir_exists { if !dir_exists {
warn!("Directory target/{target_dir} not found"); warn!("Directory target/{target_dir} not found");
} else { } else {
println!(" Profile: {}", colored(profile, BOLD_GREEN)); println!(" Profile: {}", profile.style(BOLD_GREEN));
if let Some(t) = target { if let Some(t) = target {
println!(" Target: {}", colored(t, BOLD_GREEN)); println!(" Target: {}", t.style(BOLD_GREEN));
} }
let _ = fs::remove_dir_all(&target_dir); let _ = fs::remove_dir_all(&target_dir);
println!( println!(
"{} Removed directory {}", "{} Removed directory {}",
colored("\n ✔", BOLD_GREEN), "\n ✔".style(SUCCESS_ST),
target_dir target_dir
); );
} }
@@ -248,10 +248,7 @@ fn clean_project_at(
if items.contains(&"target".to_string()) { if items.contains(&"target".to_string()) {
let _ = fs::remove_dir_all("target"); let _ = fs::remove_dir_all("target");
println!( println!("{} Removed directory target", "\n ✔".style(SUCCESS_ST));
"{} Removed directory target",
colored("\n ✔", BOLD_GREEN)
);
} else { } else {
warn!("Directory target not found"); warn!("Directory target not found");
} }

View File

@@ -17,7 +17,8 @@
use crate::prelude::*; use crate::prelude::*;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, printc}; use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::log::sprintln;
use serde::Deserialize; use serde::Deserialize;
use std::fs; use std::fs;
use std::io::Read; use std::io::Read;
@@ -56,10 +57,10 @@ struct ReleaseAsset {
/// `0` on success / already up to date / pacman-managed refuse; `1` on error. /// `0` on success / already up to date / pacman-managed refuse; `1` on error.
pub fn flag_update(args: &[String]) -> i32 { pub fn flag_update(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr --update", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr --update");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Updates DCR to the latest version from GitHub Releases."); println!(" Updates DCR to the latest version from GitHub Releases.");
return 0; return 0;
} }

View File

@@ -17,7 +17,10 @@
use crate::prelude::*; use crate::prelude::*;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::cli_styles::{
BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
};
use crate::utils::log::sprintln;
use glob::glob; use glob::glob;
use std::process::Command; use std::process::Command;
@@ -29,10 +32,10 @@ use std::process::Command;
/// If the first argument is `--help`, prints usage information and returns 0. /// If the first argument is `--help`, prints usage information and returns 0.
pub fn fmt(args: &[String]) -> i32 { pub fn fmt(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr fmt", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr fmt");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Formats all C/C++ source files using clang-format."); println!(" Formats all C/C++ source files using clang-format.");
println!(" Scans src/ and tests/ directories recursively."); println!(" Scans src/ and tests/ directories recursively.");
return 0; return 0;
@@ -70,14 +73,14 @@ pub fn fmt(args: &[String]) -> i32 {
} }
if files.is_empty() { if files.is_empty() {
println!(" {} No files to format", colored("Format", BOLD_GREEN)); println!(" {} No files to format", "Format".style(BOLD_GREEN));
return 0; return 0;
} }
// Format the collected files // Format the collected files
println!( println!(
" {} {} files", " {} {} files",
colored("Formatting", BOLD_GREEN), "Formatting".style(BOLD_GREEN),
files.len() files.len()
); );
@@ -85,7 +88,7 @@ pub fn fmt(args: &[String]) -> i32 {
match status { match status {
Ok(s) if s.success() => { Ok(s) if s.success() => {
println!(" {} successful", colored("Format", BOLD_GREEN)); println!(" {} successful", "Format".style(SUCCESS_ST));
0 0
} }
Ok(s) => { Ok(s) => {

View File

@@ -28,10 +28,11 @@ use crate::utils::build::{
get_list_with_profile, get_string_with_profile, normalize_kind, normalize_platform, get_list_with_profile, get_string_with_profile, normalize_kind, normalize_platform,
resolve_artifact_target_dir, resolve_compiler, resolve_pkg_config_flags_lossy, resolve_artifact_target_dir, resolve_compiler, resolve_pkg_config_flags_lossy,
}; };
use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::fs::{ use crate::utils::fs::{
absolute_join, atomic_write, canonicalize_path, ensure_dcr_dir, find_project_root, absolute_join, atomic_write, canonicalize_path, ensure_dcr_dir, find_project_root,
}; };
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, printc}; use crate::utils::log::sprintln;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
@@ -252,29 +253,29 @@ pub struct ProjectInfo {
pub fn r#gen(args: &[String]) -> i32 { pub fn r#gen(args: &[String]) -> i32 {
let subcommand = match args.first() { let subcommand = match args.first() {
Some(s) if s == "--help" => { Some(s) if s == "--help" => {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr gen <subcommand>", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr gen <subcommand>");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Generates IDE and tooling integration files."); println!(" Generates IDE and tooling integration files.");
println!(); println!();
printc("SUBCOMMANDS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "SUBCOMMANDS:");
println!(" project-info Print project metadata as JSON"); println!(" project-info Print project metadata as JSON");
println!(" compile-commands Generate .dcr/compile_commands.json"); println!(" compile-commands Generate .dcr/compile_commands.json");
println!(" vscode Generate .vscode/ integration files"); println!(" vscode Generate .vscode/ integration files");
println!(" clion Generate .idea/ integration files"); println!(" clion Generate .idea/ integration files");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --debug | --release Profile (default: debug)"); println!(" --debug | --release Profile (default: debug)");
println!(" --quiet | -q Suppress success messages on stdout"); println!(" --quiet | -q Suppress success messages on stdout");
return 0; return 0;
} }
Some(s) => s.as_str(), Some(s) => s.as_str(),
None => { None => {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr gen <subcommand>", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr gen <subcommand>");
println!(); println!();
printc("SUBCOMMANDS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "SUBCOMMANDS:");
println!(" project-info Print project metadata as JSON"); println!(" project-info Print project metadata as JSON");
println!(" compile-commands Generate .dcr/compile_commands.json"); println!(" compile-commands Generate .dcr/compile_commands.json");
println!(" vscode Generate .vscode/ integration files"); println!(" vscode Generate .vscode/ integration files");

View File

@@ -15,7 +15,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, printc}; use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::log::sprintln;
/// Displays the help information for the DCR CLI tool. /// Displays the help information for the DCR CLI tool.
/// ///
@@ -27,10 +28,10 @@ pub fn help() -> i32 {
println!("DCR (Dexoron Cargo Realization)"); println!("DCR (Dexoron Cargo Realization)");
println!("C project manager inspired by Cargo."); println!("C project manager inspired by Cargo.");
println!(); println!();
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr <command> [options]", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr <command> [options]");
println!(); println!();
printc("COMMANDS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "COMMANDS:");
println!(" new <name> Create a new project"); println!(" new <name> Create a new project");
println!(" init Initialize the current directory as a project"); println!(" init Initialize the current directory as a project");
println!(" build [--profile] Build the project (default: --debug)"); println!(" build [--profile] Build the project (default: --debug)");
@@ -43,24 +44,24 @@ pub fn help() -> i32 {
println!(" setup Show configured package registries"); println!(" setup Show configured package registries");
println!(" clean Remove the target directory"); println!(" clean Remove the target directory");
println!(" gen <subcommand> Generate IDE integration files"); println!(" gen <subcommand> Generate IDE integration files");
printc("FLAGS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "FLAGS:");
println!(" --help Show command help"); println!(" --help Show command help");
println!(" --update Update dcr to the latest version"); println!(" --update Update dcr to the latest version");
println!(" --version Show dcr version"); println!(" --version Show dcr version");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --debug Use debug profile"); println!(" --debug Use debug profile");
println!(" --release Use release profile"); println!(" --release Use release profile");
println!(" --force Force rebuild (build/run)"); println!(" --force Force rebuild (build/run)");
println!(" --clean Clean before build (build/run)"); println!(" --clean Clean before build (build/run)");
println!(" --all Clean all workspace members (clean)"); println!(" --all Clean all workspace members (clean)");
println!(); println!();
printc("EXAMPLES:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "EXAMPLES:");
printc(" dcr new hello", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr new hello");
printc(" dcr build --release", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr build --release");
printc(" dcr run --debug", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr run --debug");
println!(); println!();
printc("TIP:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "TIP:");
println!(" Run 'dcr <command> --help' for command-specific help."); println!(" Run 'dcr <command> --help' for command-specific help.");
0 0
} }

View File

@@ -20,8 +20,11 @@ use crate::prelude::*;
use crate::config::FILE_MAIN_C; use crate::config::FILE_MAIN_C;
use crate::core::build_config::{Config, validate_package_name}; use crate::core::build_config::{Config, validate_package_name};
use crate::core::vcs::VcsKind; use crate::core::vcs::VcsKind;
use crate::utils::cli_styles::{
BOLD_CYAN, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
};
use crate::utils::fs::check_dir; use crate::utils::fs::check_dir;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::log::sprintln;
use std::{fs, io::Write}; use std::{fs, io::Write};
/// Initializes the current working directory as a new DCR project. /// Initializes the current working directory as a new DCR project.
@@ -30,10 +33,10 @@ use std::{fs, io::Write};
/// `dcr.toml` and `src/main.c`, and configures version control (Git) integration if applicable. /// `dcr.toml` and `src/main.c`, and configures version control (Git) integration if applicable.
pub fn init(args: &[String]) -> i32 { pub fn init(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr init [--vcs <git|none>]", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr init [--vcs <git|none>]");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Initializes the current directory as a DCR project."); println!(" Initializes the current directory as a DCR project.");
println!(" The directory must be empty."); println!(" The directory must be empty.");
return 0; return 0;
@@ -78,7 +81,7 @@ pub fn init(args: &[String]) -> i32 {
if let Err(e) = validate_package_name(&project_name) { if let Err(e) = validate_package_name(&project_name) {
error!( error!(
"Invalid project name `{}`: {e}", "Invalid project name `{}`: {e}",
colored(&project_name, BOLD_CYAN), project_name.style(BOLD_CYAN),
); );
return 1; return 1;
} }
@@ -95,8 +98,8 @@ pub fn init(args: &[String]) -> i32 {
} }
println!( println!(
" {} Created file {}", " {} Created file {}",
colored("✔", BOLD_GREEN), "✔".style(SUCCESS_ST),
colored("dcr.toml", BOLD_CYAN) "dcr.toml".style(BOLD_CYAN)
); );
// Create src directory and write template main.c file. // Create src directory and write template main.c file.
@@ -117,8 +120,8 @@ pub fn init(args: &[String]) -> i32 {
} }
println!( println!(
" {} Created file {}", " {} Created file {}",
colored("✔", BOLD_GREEN), "✔".style(SUCCESS_ST),
colored("src/main.c", BOLD_CYAN) "src/main.c".style(BOLD_CYAN)
); );
// Resolve target VCS provider or detect existing repositories. // Resolve target VCS provider or detect existing repositories.
@@ -143,10 +146,7 @@ pub fn init(args: &[String]) -> i32 {
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) { if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
warn!("Failed to initialize git repository: {e}"); warn!("Failed to initialize git repository: {e}");
} else { } else {
println!( println!(" {} Initialized git repository", "✔".style(SUCCESS_ST));
" {} Initialized git repository",
colored("✔", BOLD_GREEN)
);
} }
} else { } else {
warn!( warn!(
@@ -161,9 +161,9 @@ pub fn init(args: &[String]) -> i32 {
println!( println!(
"Project `{}` successfully created\n", "Project `{}` successfully created\n",
colored(project_name.as_str(), BOLD_GREEN) project_name.style(SUCCESS_ST)
); );
printc("Next step:", BOLD_GREEN); sprintln!(BOLD_GREEN, "Next step:");
printc(" dcr run", BOLD_CYAN); sprintln!(BOLD_CYAN, " dcr run");
0 0
} }

View File

@@ -20,8 +20,11 @@ use crate::prelude::*;
use crate::core::build::common; use crate::core::build::common;
use crate::core::build_config::Config; use crate::core::build_config::Config;
use crate::utils::build::{get_bool_with_profile, get_list_with_profile}; use crate::utils::build::{get_bool_with_profile, get_list_with_profile};
use crate::utils::cli_styles::{
ALERT_ST, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
};
use crate::utils::fs::find_project_root; use crate::utils::fs::find_project_root;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, BOLD_YELLOW, colored, printc}; use crate::utils::log::sprintln;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
@@ -30,14 +33,14 @@ use std::process::Command;
/// Scans source roots (configurable via build.roots) and tests/ directory. /// Scans source roots (configurable via build.roots) and tests/ directory.
pub fn lint(args: &[String]) -> i32 { pub fn lint(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr lint [--fix]", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr lint [--fix]");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Runs clang-tidy on all C/C++ source files."); println!(" Runs clang-tidy on all C/C++ source files.");
println!(" Scans source roots (configurable via build.roots) and tests/ directory."); println!(" Scans source roots (configurable via build.roots) and tests/ directory.");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --fix Apply clang-tidy suggestions automatically"); println!(" --fix Apply clang-tidy suggestions automatically");
return 0; return 0;
} }
@@ -117,13 +120,13 @@ pub fn lint(args: &[String]) -> i32 {
files.sort(); files.sort();
if files.is_empty() { if files.is_empty() {
println!(" {} No files to lint", colored("Lint", BOLD_GREEN)); println!(" {} No files to lint", "Lint".style(BOLD_GREEN));
return 0; return 0;
} }
println!( println!(
" {} {} files {}", " {} {} files {}",
colored("Linting", BOLD_GREEN), "Linting".style(BOLD_GREEN),
files.len(), files.len(),
if do_fix { "(with --fix)" } else { "" } if do_fix { "(with --fix)" } else { "" }
); );
@@ -161,13 +164,13 @@ pub fn lint(args: &[String]) -> i32 {
if issue_count > 0 { if issue_count > 0 {
total_issues += issue_count as u32; total_issues += issue_count as u32;
failed += 1; failed += 1;
print!(" {} ", colored("×", BOLD_YELLOW)); print!(" {} ", "×".style(ALERT_ST));
println!("{} ({} issues)", file, issue_count); println!("{} ({} issues)", file, issue_count);
for issue in &issues { for issue in &issues {
println!(" {}", issue); println!(" {}", issue);
} }
} else { } else {
print!(" {} ", colored("✓", BOLD_GREEN)); print!(" {} ", "✓".style(SUCCESS_ST));
println!("{}", file); println!("{}", file);
} }
} }
@@ -178,13 +181,13 @@ pub fn lint(args: &[String]) -> i32 {
if failed == 0 { if failed == 0 {
println!( println!(
" {} {} files, no issues", " {} {} files, no issues",
colored("Lint", BOLD_GREEN), "Lint".style(SUCCESS_ST),
total total
); );
} else { } else {
println!( println!(
" {} {}/{} files passed, {} issues found", " {} {}/{} files passed, {} issues found",
colored("Lint", BOLD_YELLOW), "Lint".style(ALERT_ST),
passed, passed,
total, total,
total_issues total_issues

View File

@@ -20,8 +20,11 @@ use crate::prelude::*;
use crate::config::FILE_MAIN_C; use crate::config::FILE_MAIN_C;
use crate::core::build_config::{Config, validate_package_name}; use crate::core::build_config::{Config, validate_package_name};
use crate::core::vcs::VcsKind; use crate::core::vcs::VcsKind;
use crate::utils::cli_styles::{
BOLD_CYAN, BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SUCCESS_ST,
};
use crate::utils::fs::check_dir; use crate::utils::fs::check_dir;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::log::sprintln;
use std::{fs, io::Write}; use std::{fs, io::Write};
/// Executes the `dcr new` command to scaffold a new C/C++ project directory structure. /// Executes the `dcr new` command to scaffold a new C/C++ project directory structure.
@@ -30,10 +33,10 @@ use std::{fs, io::Write};
/// template source file generation (`src/main.c`), and initial VCS setup. /// template source file generation (`src/main.c`), and initial VCS setup.
pub fn new(args: &[String]) -> i32 { pub fn new(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr new <name> [--vcs <git|none>]", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr new <name> [--vcs <git|none>]");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Creates a new C/C++ project with the given name."); println!(" Creates a new C/C++ project with the given name.");
println!(" The name may only contain ASCII letters, digits, '_' and '-'."); println!(" The name may only contain ASCII letters, digits, '_' and '-'.");
return 0; return 0;
@@ -70,15 +73,12 @@ pub fn new(args: &[String]) -> i32 {
} }
let project_name = &clean_args[0]; let project_name = &clean_args[0];
println!( println!("Creating a Project `{}`...", project_name.style(BOLD_CYAN));
"Creating a Project `{}`...",
colored(project_name, BOLD_CYAN)
);
if let Err(e) = validate_package_name(project_name) { if let Err(e) = validate_package_name(project_name) {
error!( error!(
"Invalid project name `{}`: {e}", "Invalid project name `{}`: {e}",
colored(project_name, BOLD_CYAN), project_name.style(BOLD_CYAN),
); );
return 1; return 1;
} }
@@ -86,12 +86,12 @@ pub fn new(args: &[String]) -> i32 {
if items.contains(project_name) { if items.contains(project_name) {
error!( error!(
"Directory `{}` already exists\n", "Directory `{}` already exists\n",
colored(project_name, BOLD_CYAN) project_name.style(BOLD_CYAN)
); );
printc("Hint:", BOLD_CYAN); sprintln!(BOLD_CYAN, "Hint:");
println!( println!(
" Use `{}` to initialize an existing project\n or specify a different project name", " Use `{}` to initialize an existing project\n or specify a different project name",
colored("dcr init", BOLD_CYAN) "dcr init".style(BOLD_CYAN)
); );
return 1; return 1;
} }
@@ -102,7 +102,7 @@ pub fn new(args: &[String]) -> i32 {
} }
println!( println!(
" {} Directory created {}", " {} Directory created {}",
colored("✔", BOLD_GREEN), "✔".style(SUCCESS_ST),
project_name project_name
); );
@@ -114,8 +114,8 @@ pub fn new(args: &[String]) -> i32 {
} }
println!( println!(
" {} Created file {}", " {} Created file {}",
colored("✔", BOLD_GREEN), "✔".style(SUCCESS_ST),
colored("dcr.toml", BOLD_CYAN) "dcr.toml".style(BOLD_CYAN)
); );
// Generate src directory and populate initial main.c file. // Generate src directory and populate initial main.c file.
@@ -137,8 +137,8 @@ pub fn new(args: &[String]) -> i32 {
} }
println!( println!(
" {} Created file {}", " {} Created file {}",
colored("✔", BOLD_GREEN), "✔".style(SUCCESS_ST),
colored("src/main.c", BOLD_CYAN) "src/main.c".style(BOLD_CYAN)
); );
// Resolve target VCS mode based on CLI flags or parent directory state. // Resolve target VCS mode based on CLI flags or parent directory state.
@@ -164,10 +164,7 @@ pub fn new(args: &[String]) -> i32 {
if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) { if let Err(e) = crate::core::vcs::init_vcs(vcs_kind, project_path) {
warn!("Failed to initialize git repository: {e}"); warn!("Failed to initialize git repository: {e}");
} else { } else {
println!( println!(" {} Initialized git repository", "✔".style(SUCCESS_ST));
" {} Initialized git repository",
colored("✔", BOLD_GREEN)
);
} }
} else { } else {
warn!( warn!(
@@ -183,9 +180,9 @@ pub fn new(args: &[String]) -> i32 {
println!( println!(
"Project `{}` successfully created\n", "Project `{}` successfully created\n",
colored(project_name, BOLD_GREEN) project_name.style(SUCCESS_ST)
); );
printc("Next step:", BOLD_GREEN); sprintln!(BOLD_GREEN, "Next step:");
printc(&format!(" cd {}\n dcr run", project_name), BOLD_CYAN); sprintln!(BOLD_CYAN, " cd {}\n dcr run", project_name);
0 0
} }

View File

@@ -22,8 +22,9 @@ use crate::cli::flags::parse_build_run_flags;
use crate::core::build_config::Config; use crate::core::build_config::Config;
use crate::core::runner::run_binary; use crate::core::runner::run_binary;
use crate::utils::build::{normalize_target_os, parse_version_info, substitute_vars}; use crate::utils::build::{normalize_target_os, parse_version_info, substitute_vars};
use crate::utils::cli_styles::{BOLD_GREEN, Colorize, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::fs::{find_project_root, with_dir}; use crate::utils::fs::{find_project_root, with_dir};
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, colored, printc}; use crate::utils::log::sprintln;
use std::{path::Path, process::Command}; use std::{path::Path, process::Command};
/// Retrieves the run command from the config, preferring target-specific, /// Retrieves the run command from the config, preferring target-specific,
@@ -66,17 +67,17 @@ fn get_run_cmd(
/// Process exit code from the built binary / `run.cmd`, or non-zero on build/setup failure. /// Process exit code from the built binary / `run.cmd`, or non-zero on build/setup failure.
pub fn run(args: &[String]) -> i32 { pub fn run(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc( sprintln!(
" dcr run [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [-- <args>...]", HELP_EXAMPLES_ST,
BOLD_CYAN, " dcr run [--debug | --release] [--target <triple>] [--force] [--clean] [--verbose] [-- <args>...]"
); );
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Builds and runs the project. Only available for kind = \"bin\"."); println!(" Builds and runs the project. Only available for kind = \"bin\".");
println!(" Arguments after `--` are passed to the built binary (cargo-style)."); println!(" Arguments after `--` are passed to the built binary (cargo-style).");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --debug Run with debug profile (default)"); println!(" --debug Run with debug profile (default)");
println!(" --release Run with release profile"); println!(" --release Run with release profile");
println!(" --target <triple> Cross-compile for the given target"); println!(" --target <triple> Cross-compile for the given target");
@@ -127,7 +128,7 @@ pub fn run(args: &[String]) -> i32 {
let display = display_run_cmd(&cmd, &flags.bin_args); let display = display_run_cmd(&cmd, &flags.bin_args);
println!( println!(
" {} {}", " {} {}",
colored(&format!("{:<9}", "run"), BOLD_GREEN), format!("{:<9}", "run").style(BOLD_GREEN),
display display
); );
return run_shell_with_args(&cmd, &flags.bin_args); return run_shell_with_args(&cmd, &flags.bin_args);
@@ -267,7 +268,7 @@ fn run_project(
let display = display_run_cmd(&cmd, &flags.bin_args); let display = display_run_cmd(&cmd, &flags.bin_args);
println!( println!(
" {} {}", " {} {}",
colored(&format!("{:<9}", "run"), BOLD_GREEN), format!("{:<9}", "run").style(BOLD_GREEN),
display display
); );
return Ok(run_shell_with_args(&cmd, &flags.bin_args)); return Ok(run_shell_with_args(&cmd, &flags.bin_args));
@@ -275,7 +276,7 @@ fn run_project(
let display = display_bin_run(&bin_path, &flags.bin_args); let display = display_bin_run(&bin_path, &flags.bin_args);
println!( println!(
" {} {}", " {} {}",
colored(&format!("{:<9}", "run"), BOLD_GREEN), format!("{:<9}", "run").style(BOLD_GREEN),
display display
); );
return Ok(run_binary( return Ok(run_binary(

View File

@@ -15,15 +15,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, printc}; use crate::utils::cli_styles::{HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::log::sprintln;
/// Sets up DCR registries by loading the registry manager and printing the list of registries. /// Sets up DCR registries by loading the registry manager and printing the list of registries.
pub fn setup(args: &[String]) -> i32 { pub fn setup(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr setup", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr setup");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Sets up DCR registries. Downloads and indexes"); println!(" Sets up DCR registries. Downloads and indexes");
println!(" package registries for dependency resolution."); println!(" package registries for dependency resolution.");
return 0; return 0;

View File

@@ -24,30 +24,35 @@ use crate::utils::build::{
get_config_opt, get_config_str, get_language_with_profile, get_list_with_profile, get_config_opt, get_config_str, get_language_with_profile, get_list_with_profile,
get_string_with_profile, resolve_compiler, resolve_pkg_config_flags, get_string_with_profile, resolve_compiler, resolve_pkg_config_flags,
}; };
use crate::utils::cli_styles::{
BOLD_GREEN, Colorize, ERROR_ST, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST, SKIP_ST, SUCCESS_ST,
Style,
};
use crate::utils::fs::{find_project_root, with_dir}; use crate::utils::fs::{find_project_root, with_dir};
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, BOLD_RED, RESET, colored, printc}; use crate::utils::log::sprintln;
use std::fs; use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
const BOLD_BLUE: &str = "\x1b[1m\x1b[94m";
/// Runs project tests and prints a unified testsuite report. /// Runs project tests and prints a unified testsuite report.
pub fn test(args: &[String]) -> i32 { pub fn test(args: &[String]) -> i32 {
let mut init_header = false; let mut init_header = false;
let mut profile = "debug"; let mut profile = "debug";
for arg in args { for arg in args {
if arg == "--help" { if arg == "--help" {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr test [--init] [--debug | --release]", BOLD_CYAN); sprintln!(
HELP_EXAMPLES_ST,
" dcr test [--init] [--debug | --release]"
);
println!(); println!();
printc("ALIASES:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "ALIASES:");
println!(" dcr tests"); println!(" dcr tests");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Runs project tests and prints a unified testsuite report."); println!(" Runs project tests and prints a unified testsuite report.");
println!(); println!();
printc("OPTIONS:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "OPTIONS:");
println!(" --init Create tests/dcr_test.h in current project"); println!(" --init Create tests/dcr_test.h in current project");
println!(" --debug Build and run tests with debug profile (default)"); println!(" --debug Build and run tests with debug profile (default)");
println!(" --release Build and run tests with release profile"); println!(" --release Build and run tests with release profile");
@@ -195,19 +200,19 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
for line in stdout.lines() { for line in stdout.lines() {
let line = line.trim(); let line = line.trim();
if let Some(name) = line.strip_prefix("[PASS] ") { if let Some(name) = line.strip_prefix("[PASS] ") {
println!("{} {}", colored("[PASS]", BOLD_GREEN), name); println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
pass += 1; pass += 1;
parsed_any = true; parsed_any = true;
continue; continue;
} }
if let Some(name) = line.strip_prefix("[SKIP] ") { if let Some(name) = line.strip_prefix("[SKIP] ") {
println!("{} {}", colored("[SKIP]", BOLD_BLUE), name); println!("{} {}", "[SKIP]".style(SKIP_ST), name);
skip += 1; skip += 1;
parsed_any = true; parsed_any = true;
continue; continue;
} }
if let Some(name) = line.strip_prefix("[FAIL] ") { if let Some(name) = line.strip_prefix("[FAIL] ") {
println!("{} {}", colored("[FAIL]", BOLD_RED), name); println!("{} {}", "[FAIL]".style(ERROR_ST), name);
fail += 1; fail += 1;
parsed_any = true; parsed_any = true;
continue; continue;
@@ -215,17 +220,17 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
if let Some((status, name)) = line.split_once('\t') { if let Some((status, name)) = line.split_once('\t') {
match status { match status {
"PASS" => { "PASS" => {
println!("{} {}", colored("[PASS]", BOLD_GREEN), name); println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
pass += 1; pass += 1;
parsed_any = true; parsed_any = true;
} }
"SKIP" => { "SKIP" => {
println!("{} {}", colored("[SKIP]", BOLD_BLUE), name); println!("{} {}", "[SKIP]".style(SKIP_ST), name);
skip += 1; skip += 1;
parsed_any = true; parsed_any = true;
} }
"FAIL" => { "FAIL" => {
println!("{} {}", colored("[FAIL]", BOLD_RED), name); println!("{} {}", "[FAIL]".style(ERROR_ST), name);
fail += 1; fail += 1;
parsed_any = true; parsed_any = true;
} }
@@ -237,11 +242,11 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
if !parsed_any { if !parsed_any {
if suite_success { if suite_success {
for name in &declared { for name in &declared {
println!("{} {}", colored("[PASS]", BOLD_GREEN), name); println!("{} {}", "[PASS]".style(SUCCESS_ST), name);
} }
pass = declared.len() as i32; pass = declared.len() as i32;
} else { } else {
println!("{} testsuite", colored("[FAIL]", BOLD_RED)); println!("{} testsuite", "[FAIL]".style(ERROR_ST));
fail = 1; fail = 1;
} }
} }
@@ -253,14 +258,15 @@ fn run_testsuite(profile: &str) -> Result<i32, String> {
}; };
println!(); println!();
println!("{}", colored("=====================", BOLD_GREEN)); sprintln!(BOLD_GREEN, "=====================");
println!("{}", colored(" Testsuite summary ", BOLD_GREEN)); sprintln!(BOLD_GREEN, " Testsuite summary ");
println!("{}", colored("=====================", BOLD_GREEN)); sprintln!(BOLD_GREEN, "=====================");
println!("TOTAL: {}", total); println!("TOTAL: {}", total);
print_field("PASS", pass, BOLD_GREEN); print_field("PASS", pass, SUCCESS_ST);
print_field("SKIP", skip, BOLD_BLUE); print_field("SKIP", skip, SKIP_ST);
print_field("FAIL", fail, BOLD_RED); print_field("FAIL", fail, ERROR_ST);
println!("{}", colored("=====================", BOLD_GREEN)); sprintln!(BOLD_GREEN, "=====================");
sprintln!(BOLD_GREEN, "=====================");
if fail > 0 || !suite_success { if fail > 0 || !suite_success {
return Ok(1); return Ok(1);
@@ -395,10 +401,10 @@ fn extract_test_names_path(path: &Path) -> Vec<String> {
} }
/// Prints a test result field with color coding. /// Prints a test result field with color coding.
fn print_field(label: &str, value: i32, color: &str) { fn print_field(label: &str, value: i32, style: Style) {
if value == 0 { if value == 0 {
println!("{}: {}", label, value); println!("{}: {}", label, value);
} else { } else {
println!("{}{}: {}{}", color, label, value, RESET); sprintln!(style, "{}: {}", label, value);
} }
} }

View File

@@ -18,7 +18,8 @@
use crate::prelude::*; use crate::prelude::*;
use crate::core::build_config::Config; use crate::core::build_config::Config;
use crate::utils::cli_styles::{BOLD_CYAN, BOLD_GREEN, printc}; use crate::utils::cli_styles::{BOLD_CYAN, HELP_EXAMPLES_ST, HELP_SECTION_TITLE_ST};
use crate::utils::log::sprintln;
use std::collections::HashSet; use std::collections::HashSet;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use toml::Value; use toml::Value;
@@ -29,10 +30,10 @@ use toml::Value;
/// Otherwise, it parses the dcr.toml configuration and prints the dependency tree. /// Otherwise, it parses the dcr.toml configuration and prints the dependency tree.
pub fn tree(args: &[String]) -> i32 { pub fn tree(args: &[String]) -> i32 {
if args.first().is_some_and(|a| a == "--help") { if args.first().is_some_and(|a| a == "--help") {
printc("USAGE:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "USAGE:");
printc(" dcr tree", BOLD_CYAN); sprintln!(HELP_EXAMPLES_ST, " dcr tree");
println!(); println!();
printc("DESCRIPTION:", BOLD_GREEN); sprintln!(HELP_SECTION_TITLE_ST, "DESCRIPTION:");
println!(" Displays the dependency tree of the current project."); println!(" Displays the dependency tree of the current project.");
return 0; return 0;
} }
@@ -55,7 +56,7 @@ pub fn tree(args: &[String]) -> i32 {
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.unwrap_or("0.0.0"); .unwrap_or("0.0.0");
printc(&format!("{} v{}", name, version), BOLD_CYAN); sprintln!(BOLD_CYAN, "{} v{}", name, version);
let mut seen = HashSet::new(); let mut seen = HashSet::new();
seen.insert(name.to_string()); seen.insert(name.to_string());

View File

@@ -15,43 +15,33 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#[allow(unused_imports)]
pub use owo_colors::{OwoColorize as Colorize, Style}; pub use owo_colors::{OwoColorize as Colorize, Style};
// Сli theme styles // Сli theme styles
// Main
#[allow(dead_code)] #[allow(dead_code)]
pub const RESET: &str = "\x1b[0m"; pub const BOLD_RED: Style = Style::new().bright_red().bold();
#[allow(dead_code)]
pub const BOLD_GREEN: Style = Style::new().bright_green().bold();
#[allow(dead_code)]
pub const BOLD_YELLOW: Style = Style::new().bright_yellow().bold();
#[allow(dead_code)]
pub const BOLD_CYAN: Style = Style::new().bright_cyan().bold();
#[allow(dead_code)]
pub const BOLD_BLUE: Style = Style::new().bright_blue().bold();
// Help
#[allow(dead_code)] #[allow(dead_code)]
pub const BOLD: &str = "\x1b[1m"; pub const HELP_SECTION_TITLE_ST: Style = BOLD_GREEN;
#[allow(dead_code)]
pub const HELP_EXAMPLES_ST: Style = BOLD_CYAN;
// Other
#[allow(dead_code)] #[allow(dead_code)]
pub const BRIGHT_RED: &str = "\x1b[91m"; pub const ERROR_ST: Style = BOLD_RED;
#[allow(dead_code)] #[allow(dead_code)]
pub const BRIGHT_GREEN: &str = "\x1b[92m"; pub const SUCCESS_ST: Style = BOLD_GREEN;
#[allow(dead_code)] #[allow(dead_code)]
pub const BRIGHT_YELLOW: &str = "\x1b[93m"; pub const ALERT_ST: Style = BOLD_YELLOW;
#[allow(dead_code)] #[allow(dead_code)]
pub const BRIGHT_CYAN: &str = "\x1b[96m"; pub const SKIP_ST: Style = BOLD_BLUE;
#[allow(dead_code)]
pub const BOLD_RED: &str = "\x1b[1m\x1b[91m";
#[allow(dead_code)]
pub const BOLD_GREEN: &str = "\x1b[1m\x1b[92m";
#[allow(dead_code)]
pub const BOLD_YELLOW: &str = "\x1b[1m\x1b[93m";
#[allow(dead_code)]
pub const BOLD_CYAN: &str = "\x1b[1m\x1b[96m";
/// Applies ANSI escape codes to format the message with the given style.
///
/// This is a utility for colored output in terminal applications.
#[allow(dead_code)]
pub fn colored(msg: &str, style: &str) -> String {
format!("{style}{msg}{RESET}")
}
/// Prints `msg` to stdout with the given ANSI `style`.
#[allow(dead_code)]
pub fn printc(msg: &str, style: &str) {
println!("{style}{msg}{RESET}");
}