Skip to content

Commit 2f477f0

Browse files
authored
y test: improve verbose output formatting (#8)
* ./y Test: improve verbose output formatting * Build: improve verbose output in manifest * refactor: unify verbose flag handling - Refactor Log trait to handle command status and details consistently - Make verbose flag shared between main command and subcommands - Improve log output format for test and build commands This change ensures that `y -v test` produce verbose outputs. Signed-off-by: xizheyin <[email protected]>
1 parent 763d3eb commit 2f477f0

File tree

6 files changed

+275
-68
lines changed

6 files changed

+275
-68
lines changed

bootstrap/src/clean.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@ use crate::Run;
55

66
/// Clean the build directory
77
#[derive(Args, Debug)]
8-
pub struct CleanCommand {}
8+
pub struct CleanCommand {
9+
#[arg(short, long)]
10+
pub verbose: bool,
11+
}
912

1013
impl Run for CleanCommand {
14+
const STEP_DISPLAY_NAME: &'static str = "clean";
15+
1116
fn run(&self, manifest: &Manifest) {
17+
self.log_action_start("cleaning", "build directory");
1218
let _ = std::fs::remove_dir_all("crates/target");
19+
self.log_action_context("rm", "crates/target");
1320
let _ = std::fs::remove_dir_all(&manifest.out_dir);
21+
self.log_action_context("rm", &manifest.out_dir.display());
22+
}
23+
24+
fn verbose(&self) -> bool {
25+
self.verbose
1426
}
1527
}

bootstrap/src/fmt.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ use crate::Run;
1010
pub struct FmtCommand {
1111
#[arg(short, long)]
1212
pub check: bool,
13+
14+
#[arg(short, long)]
15+
pub verbose: bool,
1316
}
1417

1518
impl Run for FmtCommand {
19+
const STEP_DISPLAY_NAME: &'static str = "FMT";
20+
1621
fn run(&self, _manifest: &crate::manifest::Manifest) {
1722
self.perform(
1823
Command::new("cargo").arg("fmt").args(["--manifest-path", "bootstrap/Cargo.toml"]),
@@ -30,14 +35,18 @@ impl Run for FmtCommand {
3035
self.perform(Command::new("rustfmt").args(["--edition", "2021"]).arg(file.unwrap()));
3136
}
3237
}
38+
39+
fn verbose(&self) -> bool {
40+
self.verbose
41+
}
3342
}
3443

3544
impl FmtCommand {
3645
pub fn perform(&self, command: &mut Command) {
3746
if self.check {
3847
command.arg("--check");
3948
}
40-
log::debug!("running {:?}", command);
41-
assert!(command.status().unwrap().success(), "failed to run {:?}", command);
49+
50+
self.command_status("format code", command);
4251
}
4352
}

bootstrap/src/main.rs

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
use std::fmt::Display;
2+
use std::process::{self, ExitStatus};
3+
14
use clap::{Parser, Subcommand};
5+
use color_print::cprintln;
26

37
use crate::manifest::Manifest;
48

@@ -37,7 +41,65 @@ pub enum Command {
3741
}
3842

3943
trait Run {
44+
// The name like "BUILD" or "TEST" for logs.
45+
const STEP_DISPLAY_NAME: &'static str;
4046
fn run(&self, manifest: &Manifest);
47+
48+
/// True if verbose output should be enabled.
49+
fn verbose(&self) -> bool;
50+
51+
/// Record that the step has started a new action.
52+
fn log_action_start(&self, action: &str, item: impl Display) {
53+
let name = Self::STEP_DISPLAY_NAME;
54+
cprintln!("<b>[{name}]</b> {action} <cyan>{item}</cyan>");
55+
}
56+
57+
/// Record context associated with the current action. Only use if there has been a preceding
58+
/// call to `log_action_start`.
59+
fn log_action_context(&self, key: impl Display, value: impl Display) {
60+
if self.verbose() {
61+
cprintln!(" {key}: {value}");
62+
}
63+
}
64+
65+
/// Run a command and ensure it succeeds, capturing output.
66+
fn command_output(&self, action: &str, command: &mut process::Command) -> process::Output {
67+
if self.verbose() {
68+
cprintln!(" {action}: {command:?}");
69+
}
70+
71+
match command.output() {
72+
// Command ran and completed successfully
73+
Ok(output) if output.status.success() => {
74+
if self.verbose() {
75+
cprintln!(" <g>success</g>");
76+
}
77+
output
78+
}
79+
// Command ran but did not complete
80+
Ok(output) => panic!("command failed: {output:?}"),
81+
Err(e) => panic!("command failed: {e:?}"),
82+
}
83+
}
84+
85+
/// Run a command and ensure it succeeds.
86+
fn command_status(&self, action: &str, command: &mut process::Command) -> ExitStatus {
87+
if self.verbose() {
88+
cprintln!(" {}: {}", action, format!("{:?}", command).replace('"', ""));
89+
}
90+
match command.status() {
91+
// Command ran and completed successfully
92+
Ok(status) if status.success() => {
93+
if self.verbose() {
94+
cprintln!(" <g>success</g>");
95+
}
96+
status
97+
}
98+
// Command ran but did not complete
99+
Ok(status) => panic!("command failed: {status:?}"),
100+
Err(e) => panic!("command failed: {e:?}"),
101+
}
102+
}
41103
}
42104

43105
fn main() {
@@ -49,10 +111,23 @@ fn main() {
49111
release: cli.release,
50112
out_dir: cli.out_dir.unwrap_or("build".to_string()).into(),
51113
};
114+
52115
match cli.command {
53-
Command::Test(test) => test.run(&manifest),
54-
Command::Clean(clean) => clean.run(&manifest),
55-
Command::Rustc(rustc) => rustc.run(&manifest),
56-
Command::Fmt(fmt) => fmt.run(&manifest),
116+
Command::Test(mut test) => {
117+
test.verbose |= cli.verbose;
118+
test.run(&manifest)
119+
}
120+
Command::Clean(mut clean) => {
121+
clean.verbose |= cli.verbose;
122+
clean.run(&manifest)
123+
}
124+
Command::Rustc(mut rustc) => {
125+
rustc.verbose |= cli.verbose;
126+
rustc.run(&manifest)
127+
}
128+
Command::Fmt(mut fmt) => {
129+
fmt.verbose |= cli.verbose;
130+
fmt.run(&manifest)
131+
}
57132
}
58133
}

bootstrap/src/manifest.rs

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
use anstream::eprintln as println;
2-
use color_print::cprintln;
31
use std::path::{Path, PathBuf};
42
use std::process::Command;
53

4+
use anstream::eprintln as println;
5+
use color_print::cprintln;
6+
7+
use crate::Run;
8+
9+
#[derive(Debug)]
610
pub struct Manifest {
711
pub verbose: bool,
812
pub release: bool,
@@ -12,36 +16,8 @@ pub struct Manifest {
1216
impl Manifest {
1317
/// Builds the rustc codegen c library
1418
pub fn prepare(&self) {
15-
cprintln!("<b>[BUILD]</b> codegen backend");
16-
let mut command = Command::new("cargo");
17-
command.arg("build").args(["--manifest-path", "crates/Cargo.toml"]);
18-
if self.verbose {
19-
command.args(["-F", "debug"]);
20-
}
21-
if self.release {
22-
command.arg("--release");
23-
}
24-
log::debug!("running {:?}", command);
25-
command.status().unwrap();
26-
27-
cprintln!("<b>[BUILD]</b> librust_runtime");
28-
std::fs::create_dir_all(&self.out_dir).unwrap();
29-
let cc = std::env::var("CC").unwrap_or("clang".to_string());
30-
let mut command = Command::new(&cc);
31-
command
32-
.arg("rust_runtime/rust_runtime.c")
33-
.arg("-o")
34-
.arg(self.out_dir.join("rust_runtime.o"))
35-
.arg("-c");
36-
log::debug!("running {:?}", command);
37-
command.status().unwrap();
38-
let mut command = Command::new("ar");
39-
command
40-
.arg("rcs")
41-
.arg(self.out_dir.join("librust_runtime.a"))
42-
.arg(self.out_dir.join("rust_runtime.o"));
43-
log::debug!("running {:?}", command);
44-
command.status().unwrap();
19+
let prepare = PrepareAction { verbose: self.verbose };
20+
prepare.run(&self);
4521
}
4622

4723
/// The path to the rustc codegen c library
@@ -72,3 +48,60 @@ impl Manifest {
7248
command
7349
}
7450
}
51+
52+
struct PrepareAction {
53+
verbose: bool,
54+
}
55+
56+
impl Run for PrepareAction {
57+
const STEP_DISPLAY_NAME: &'static str = "prepare";
58+
59+
fn run(&self, manifest: &Manifest) {
60+
// action: Build codegen backend
61+
self.log_action_start("building", "codegen backend");
62+
self.log_action_context("target", manifest.codegen_backend().display());
63+
64+
let mut command = Command::new("cargo");
65+
command.arg("build").args(["--manifest-path", "crates/Cargo.toml"]);
66+
if manifest.verbose {
67+
command.args(["-v"]);
68+
}
69+
if manifest.release {
70+
command.arg("--release");
71+
}
72+
self.command_status("build", &mut command);
73+
74+
// action: Build runtime library
75+
self.log_action_start("building", "librust_runtime");
76+
self.log_action_context("output dir", &manifest.out_dir.to_path_buf().display());
77+
78+
// cmd: Create output directory
79+
if let Err(e) = std::fs::create_dir_all(&manifest.out_dir) {
80+
cprintln!(" <r>failed</r> to create output directory: {}", e);
81+
std::process::exit(1);
82+
}
83+
84+
let cc = std::env::var("CC").unwrap_or("clang".to_string());
85+
86+
// cmd: Compile runtime.c
87+
let mut command = Command::new(&cc);
88+
command
89+
.arg("rust_runtime/rust_runtime.c")
90+
.arg("-o")
91+
.arg(manifest.out_dir.join("rust_runtime.o"))
92+
.arg("-c");
93+
self.command_status("build", &mut command);
94+
95+
// cmd: Create static library
96+
let mut command = Command::new("ar");
97+
command
98+
.arg("rcs")
99+
.arg(manifest.out_dir.join("librust_runtime.a"))
100+
.arg(manifest.out_dir.join("rust_runtime.o"));
101+
self.command_status("archive", &mut command);
102+
}
103+
104+
fn verbose(&self) -> bool {
105+
self.verbose
106+
}
107+
}

bootstrap/src/rustc.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ pub struct RustcCommand {
1212

1313
#[arg(last = true)]
1414
slop: Vec<String>,
15+
16+
#[arg(short, long)]
17+
pub verbose: bool,
1518
}
1619

1720
impl Run for RustcCommand {
21+
const STEP_DISPLAY_NAME: &'static str = "RUSTC";
22+
1823
fn run(&self, manifest: &Manifest) {
1924
manifest.prepare();
2025

@@ -25,7 +30,14 @@ impl Run for RustcCommand {
2530
.arg("--out-dir")
2631
.arg(&manifest.out_dir)
2732
.args(&self.slop);
28-
log::debug!("running {:?}", command);
29-
command.status().unwrap();
33+
if self.verbose {
34+
command.env("RUST_BACKTRACE", "full");
35+
}
36+
37+
self.command_status("rustc", &mut command);
38+
}
39+
40+
fn verbose(&self) -> bool {
41+
self.verbose
3042
}
3143
}

0 commit comments

Comments
 (0)