mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 11:18:36 +00:00
feat(build): archive feature, progress UI, and workspace path fixes
This commit is contained in:
@@ -17,18 +17,29 @@
|
||||
|
||||
use crate::cli::clean::clean;
|
||||
use crate::cli::flags::parse_build_run_flags;
|
||||
use crate::core::build::common;
|
||||
use crate::core::build::{BuildEvent, BuildReporter, BuildRequest, run_build};
|
||||
use crate::core::build_config::Config;
|
||||
use crate::utils::build::default_target_triple;
|
||||
use crate::utils::fs::find_project_root;
|
||||
use crate::utils::log::error;
|
||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, BOLD_YELLOW, colored, printc};
|
||||
use std::io::IsTerminal;
|
||||
use std::sync::{Arc, atomic::AtomicBool};
|
||||
|
||||
pub use crate::core::build::get_build_string_with_profile;
|
||||
|
||||
fn status(verb: &str, style: &str) -> String {
|
||||
colored(&format!("{verb:<9}"), style)
|
||||
}
|
||||
|
||||
struct CliReporter;
|
||||
|
||||
impl CliReporter {
|
||||
fn line(&self, verb: &str, style: &str, rest: &str) {
|
||||
eprintln!(" {} {}", status(verb, style), rest);
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildReporter for CliReporter {
|
||||
fn on_event(&mut self, event: BuildEvent<'_>) {
|
||||
match event {
|
||||
@@ -37,73 +48,57 @@ impl BuildReporter for CliReporter {
|
||||
total,
|
||||
target,
|
||||
} => {
|
||||
println!(" Building target {} of {}: {}", index, total, target);
|
||||
common::finish_progress_line();
|
||||
self.line("target", BOLD_CYAN, &format!("{index}/{total} {target}"));
|
||||
}
|
||||
BuildEvent::ProjectStart {
|
||||
name,
|
||||
profile,
|
||||
target,
|
||||
} => {
|
||||
println!(
|
||||
" Building project `{}`\n Profile: {}\n Target: {}",
|
||||
colored(name, BOLD_GREEN),
|
||||
colored(profile, BOLD_GREEN),
|
||||
colored(target, BOLD_GREEN)
|
||||
common::finish_progress_line();
|
||||
self.line(
|
||||
"project",
|
||||
BOLD_CYAN,
|
||||
&format!("{name} ({profile}, {target})"),
|
||||
);
|
||||
}
|
||||
BuildEvent::DepBuilding { name, version } => {
|
||||
print!(
|
||||
"\r{:100}\r {} {} v{}",
|
||||
"",
|
||||
colored("Building", BOLD_GREEN),
|
||||
name,
|
||||
version
|
||||
);
|
||||
std::io::Write::flush(&mut std::io::stdout()).unwrap();
|
||||
common::finish_progress_line();
|
||||
self.line("dep", BOLD_YELLOW, &format!("{name} v{version}"));
|
||||
}
|
||||
BuildEvent::DepReady {
|
||||
name,
|
||||
version,
|
||||
rebuilt,
|
||||
} => {
|
||||
common::finish_progress_line();
|
||||
if rebuilt {
|
||||
print!(
|
||||
"\r{:100}\r {} {} v{}",
|
||||
"",
|
||||
colored("Ready", BOLD_GREEN),
|
||||
name,
|
||||
version
|
||||
);
|
||||
println!();
|
||||
} else {
|
||||
println!(
|
||||
" {} {} v{}",
|
||||
colored("Ready", BOLD_GREEN),
|
||||
name,
|
||||
version
|
||||
);
|
||||
self.line("ready", BOLD_GREEN, &format!("{name} v{version}"));
|
||||
}
|
||||
}
|
||||
BuildEvent::Compiling { name, version } => {
|
||||
println!(
|
||||
" {} {} v{}",
|
||||
colored("Compiling", BOLD_GREEN),
|
||||
name,
|
||||
version
|
||||
);
|
||||
common::finish_progress_line();
|
||||
let label = format!(" {} {} v{}", status("compile", BOLD_GREEN), name, version);
|
||||
common::set_progress_label(Some(label.clone()));
|
||||
if !std::io::stderr().is_terminal() {
|
||||
eprintln!("{label}");
|
||||
}
|
||||
}
|
||||
BuildEvent::Packing { path } => {
|
||||
common::finish_progress_line();
|
||||
self.line("pack", BOLD_CYAN, path);
|
||||
}
|
||||
BuildEvent::Finished { secs } => {
|
||||
println!(
|
||||
" {} Build completed successfully in {} seconds",
|
||||
colored("✔", BOLD_GREEN),
|
||||
colored(&secs.to_string(), BOLD_GREEN)
|
||||
);
|
||||
common::finish_progress_line();
|
||||
self.line("done", BOLD_GREEN, &format!("in {secs}s"));
|
||||
}
|
||||
BuildEvent::CompilerOutput { stream, text } => {
|
||||
common::interrupt_progress_for_output();
|
||||
if stream == "stderr" {
|
||||
eprintln!("{}", text);
|
||||
eprint!("{text}");
|
||||
} else {
|
||||
println!("{}", text);
|
||||
print!("{text}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,15 +161,12 @@ pub fn build(args: &[String]) -> i32 {
|
||||
if let Ok(config) = Config::open(config_path.to_str().unwrap())
|
||||
&& !config.is_workspace_only()
|
||||
{
|
||||
let bt = get_build_string_with_profile(&config, "target", "debug");
|
||||
let bt = get_build_string_with_profile(&config, "target", &flags.profile);
|
||||
if !bt.is_empty() {
|
||||
flags.target = Some(bt);
|
||||
}
|
||||
}
|
||||
}
|
||||
if flags.target.is_none() {
|
||||
flags.target = Some(default_target_triple());
|
||||
}
|
||||
if flags.clean {
|
||||
let mut clean_args = Vec::new();
|
||||
clean_args.push(format!("--{}", flags.profile));
|
||||
@@ -193,6 +185,7 @@ pub fn build(args: &[String]) -> i32 {
|
||||
match run_build(&root, &req, &mut reporter) {
|
||||
Ok(_) => 0,
|
||||
Err(err) => {
|
||||
common::finish_progress_line();
|
||||
error(&err.message);
|
||||
1
|
||||
}
|
||||
|
||||
@@ -146,7 +146,10 @@ fn clean_from_root(root: &Path, flags: &CleanFlags) -> Result<(), String> {
|
||||
)?
|
||||
{
|
||||
for member in &workspace.members {
|
||||
clean_project_at(&member.path, flags.profile.as_deref(), target.as_deref())?;
|
||||
let member_target = member.path.join("target");
|
||||
if member_target.is_dir() {
|
||||
clean_project_at(&member.path, flags.profile.as_deref(), target.as_deref())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
clean_project_at(root, flags.profile.as_deref(), target.as_deref())
|
||||
|
||||
@@ -29,9 +29,12 @@ pub fn help() -> i32 {
|
||||
println!(" init Initialize the current directory as a project");
|
||||
println!(" build [--profile] Build the project (default: --debug)");
|
||||
println!(" run [--profile] Build and run the project (default: --debug)");
|
||||
println!(" add <name> ... Add a dependency to dcr.toml");
|
||||
println!(" tree Display the dependency tree");
|
||||
println!(" test Run project tests (alias: tests)");
|
||||
println!(" fmt Format all C/C++ source files using clang-format");
|
||||
println!(" lint Run clang-tidy on C/C++ sources");
|
||||
println!(" setup Show configured package registries");
|
||||
println!(" clean Remove the target directory");
|
||||
println!(" gen <subcommand> Generate IDE integration files");
|
||||
printc("FLAGS:", BOLD_GREEN);
|
||||
|
||||
@@ -85,7 +85,7 @@ pub fn new(args: &[String]) -> i32 {
|
||||
"Directory `{}` already exists\n",
|
||||
colored(project_name, BOLD_CYAN)
|
||||
));
|
||||
printc("Подсказка:", BOLD_CYAN);
|
||||
printc("Hint:", BOLD_CYAN);
|
||||
println!(
|
||||
" Use `{}` to initialize an existing project\n or specify a different project name",
|
||||
colored("dcr init", BOLD_CYAN)
|
||||
|
||||
@@ -19,9 +19,7 @@ use crate::cli::build::build;
|
||||
use crate::cli::flags::parse_build_run_flags;
|
||||
use crate::core::build_config::Config;
|
||||
use crate::core::runner::run_binary;
|
||||
use crate::utils::build::{
|
||||
default_target_triple, normalize_target_os, parse_version_info, substitute_vars,
|
||||
};
|
||||
use crate::utils::build::{normalize_target_os, parse_version_info, substitute_vars};
|
||||
use crate::utils::fs::find_project_root;
|
||||
use crate::utils::fs::with_dir;
|
||||
use crate::utils::log::error;
|
||||
@@ -114,8 +112,11 @@ pub fn run(args: &[String]) -> i32 {
|
||||
if let Some(cmd) = get_run_cmd(&config, &flags.profile, flags.target.as_deref(), "") {
|
||||
let build_status = build(&args_for_build(&flags));
|
||||
if build_status == 0 {
|
||||
println!("\n {} {}", colored("Running", BOLD_GREEN), cmd);
|
||||
println!("--------------------------------");
|
||||
println!(
|
||||
" {} {}",
|
||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
||||
cmd
|
||||
);
|
||||
return run_shell(&cmd);
|
||||
}
|
||||
return build_status;
|
||||
@@ -186,10 +187,13 @@ fn run_project(
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
|
||||
// If no target specified, use default host target for target-specific config
|
||||
let mut target = flags.target.clone();
|
||||
if target.is_none() {
|
||||
target = Some(default_target_triple());
|
||||
let bt =
|
||||
crate::cli::build::get_build_string_with_profile(&config, "target", &flags.profile);
|
||||
if !bt.is_empty() {
|
||||
target = Some(bt);
|
||||
}
|
||||
}
|
||||
|
||||
let build_kind = config
|
||||
@@ -246,12 +250,18 @@ fn run_project(
|
||||
);
|
||||
if build_status == 0 {
|
||||
if let Some(cmd) = run_cmd {
|
||||
println!("\n {} {}", colored("Running", BOLD_GREEN), cmd);
|
||||
println!("--------------------------------");
|
||||
println!(
|
||||
" {} {}",
|
||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
||||
cmd
|
||||
);
|
||||
return Ok(run_shell(&cmd));
|
||||
}
|
||||
println!("\n {} {}", colored("Running", BOLD_GREEN), bin_path);
|
||||
println!("--------------------------------");
|
||||
println!(
|
||||
" {} {}",
|
||||
colored(&format!("{:<9}", "run"), BOLD_GREEN),
|
||||
bin_path
|
||||
);
|
||||
return Ok(run_binary(
|
||||
project_name,
|
||||
&flags.profile,
|
||||
|
||||
Reference in New Issue
Block a user