Refactored do to be a cargo alias.
This commit is contained in:
parent
2d7df342e6
commit
71676b6fe2
|
@ -0,0 +1,5 @@
|
|||
[env]
|
||||
DO_CMD = "cargo do"
|
||||
|
||||
[alias]
|
||||
do = ["run", "--manifest-path", "tools/do-tasks/Cargo.toml", "--release", "--quiet", "--"]
|
|
@ -4,10 +4,6 @@
|
|||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
|
|
|
@ -1,25 +1,8 @@
|
|||
{
|
||||
"spellright.language": [
|
||||
"en"
|
||||
],
|
||||
"spellright.documentTypes": [
|
||||
"markdown",
|
||||
"latex",
|
||||
"plaintext",
|
||||
"rust",
|
||||
"toml",
|
||||
"json"
|
||||
],
|
||||
"rust-analyzer.files.excludeDirs": [
|
||||
"tests/build",
|
||||
],
|
||||
"errorLens.exclude": [
|
||||
"file not included in module tree",
|
||||
"code is inactive due to #\\[cfg\\] directives: debug_assertions is enabled"
|
||||
],
|
||||
"rust-analyzer.linkedProjects.disabled": [
|
||||
"Cargo.toml",
|
||||
"tools/do-tasks/Cargo.toml"
|
||||
],
|
||||
"rust-analyzer.runnables.overrideCargo": "cargo do rust_analyzer_run",
|
||||
"rust-analyzer.checkOnSave.overrideCommand": ["cargo", "do", "rust_analyzer_check"],
|
||||
"files.eol": "\n",
|
||||
}
|
|
@ -2,13 +2,84 @@
|
|||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cargo",
|
||||
"command": "fmt",
|
||||
"label": "do build",
|
||||
"type": "shell",
|
||||
"command": "cargo do build",
|
||||
"group": "build",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do build --examples",
|
||||
"type": "shell",
|
||||
"command": "cargo do build --examples",
|
||||
"group": "build",
|
||||
"label": "rust: cargo fmt"
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do check",
|
||||
"type": "shell",
|
||||
"command": "cargo do check",
|
||||
"group": "build",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do prebuild",
|
||||
"type": "shell",
|
||||
"command": "cargo do prebuild",
|
||||
"group": "build",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do test",
|
||||
"type": "shell",
|
||||
"command": "cargo do test ${input:testGroupID}",
|
||||
"group": "test",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do run",
|
||||
"type": "shell",
|
||||
"command": "cargo do run ${input:exampleNameID}",
|
||||
"group": "build",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": "do fmt",
|
||||
"type": "shell",
|
||||
"command": "cargo do fmt",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
},
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "exampleNameID",
|
||||
"description": "example name",
|
||||
"type": "promptString",
|
||||
},
|
||||
{
|
||||
"id": "testGroupID",
|
||||
"description": "test group",
|
||||
"type": "pickString",
|
||||
"options": [
|
||||
"--workspace",
|
||||
"--doc",
|
||||
"--test-crates",
|
||||
"--build *"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
18
README.md
18
README.md
|
@ -81,11 +81,23 @@ You also need the nightly toolchain for building the documentation (`do doc`), a
|
|||
build the documentation in stable using `cargo doc`, but custom pages like widget items may not
|
||||
render properly because of changes in the `cargo-doc` HTML templates.
|
||||
|
||||
## `do`
|
||||
## `cargo do`
|
||||
|
||||
There is a built-in task runner for managing this project, run `do help` or `./do help` for details.
|
||||
There is a built-in task runner for managing this project, run `cargo do help` or `./do help` for details.
|
||||
|
||||
The task runner is implemented as a Rust crate in `tools/do-tasks`, the shell script builds it in the first run.
|
||||
The task runner is implemented as a Rust crate in `tools/do-tasks` and an alias in `.cargo/config.toml`,
|
||||
it builds the tool silently in the first run, after it should run without noticeable delay.
|
||||
|
||||
Shell script to run `do` are also provided:
|
||||
|
||||
* cmd.exe: `do help`.
|
||||
* PowerShell: `./do.ps1 help`.
|
||||
* Bash: `/.do help`.
|
||||
|
||||
## VSCode & Rust Analyzer
|
||||
|
||||
Some workspace settings are included in the repository, in particular, `rust-analyzer` "checkOnSave"
|
||||
and runnables are redirected to the `do` tool.
|
||||
|
||||
[`API docs`]: https://docs.rs/zero-ui
|
||||
[`cargo-expand`]: https://github.com/dtolnay/cargo-expand
|
||||
|
|
5
do
5
do
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
export DO_NAME="do"
|
||||
export DO_MANIFEST_PATH="tools/do-tasks/Cargo.toml"
|
||||
cargo run --manifest-path $DO_MANIFEST_PATH --release --quiet -- $*
|
||||
export DO_CMD=".\do"
|
||||
cargo do $*
|
5
do.bat
5
do.bat
|
@ -19,6 +19,5 @@ goto next
|
|||
:done
|
||||
|
||||
:: Run Task
|
||||
set DO_NAME=do
|
||||
set DO_MANIFEST_PATH=tools/do-tasks/Cargo.toml
|
||||
cargo run --manifest-path %DO_MANIFEST_PATH% --release --quiet -- %ARGS%
|
||||
set DO_CMD=do
|
||||
cargo do %ARGS%
|
5
do.ps1
5
do.ps1
|
@ -1,3 +1,2 @@
|
|||
$env:DO_NAME = "do"
|
||||
$env:DO_MANIFEST_PATH = "tools/do-tasks/Cargo.toml"
|
||||
cargo run --manifest-path $env:DO_MANIFEST_PATH --release --quiet -- $args
|
||||
$env:DO_CMD = ".\do.ps1"
|
||||
cargo do $args
|
|
@ -20,17 +20,17 @@ use v_jsonescape::escape;
|
|||
/// Call [`Recording::finish`] to stop recording and wait flush.
|
||||
///
|
||||
/// Profiles can be viewed using the `chrome://tracing` app. Log events from the `log` crate are not recorded.
|
||||
///
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
///
|
||||
/// The `path` is a JSON file that will be written too as the profiler records. Returns a
|
||||
/// [`Recording`] struct, you must call [`Recording::finish`] to stop recording and correctly
|
||||
/// terminate the JSON file. If `finish` is not called the output file will not be valid JSON,
|
||||
/// you can probably fix it manually in this case by removing the last incomplete event entry and adding
|
||||
/// `]}`.
|
||||
///
|
||||
///
|
||||
/// # About
|
||||
///
|
||||
///
|
||||
/// The `about` array is a list of any key-value metadata to be included in the output.
|
||||
///
|
||||
/// # Special Attributes
|
||||
|
@ -40,16 +40,16 @@ use v_jsonescape::escape;
|
|||
///
|
||||
/// If a span has an attribute `"thread"` the span will be recorded as the *virtual thread* named.
|
||||
pub fn record_profile(path: impl AsRef<Path>, about: &[(&str, &str)]) -> Recording {
|
||||
let mut file = BufWriter::new(File::create(path).unwrap());
|
||||
let mut file = BufWriter::new(File::create(path).unwrap());
|
||||
|
||||
// specs: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.lpfof2aylapb
|
||||
// specs: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.lpfof2aylapb
|
||||
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{{"recorder":"{}-{}","about":{{"#,
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
)
|
||||
)
|
||||
.unwrap();
|
||||
let mut comma = "";
|
||||
for (key, value) in about {
|
||||
|
@ -60,133 +60,136 @@ pub fn record_profile(path: impl AsRef<Path>, about: &[(&str, &str)]) -> Recordi
|
|||
|
||||
let (sender, recv) = flume::unbounded();
|
||||
|
||||
let worker = thread::Builder::new().name("profiler".to_owned()).spawn(move || {
|
||||
let mut spans = FxHashMap::<span::Id, Span>::default();
|
||||
let worker = thread::Builder::new()
|
||||
.name("profiler".to_owned())
|
||||
.spawn(move || {
|
||||
let mut spans = FxHashMap::<span::Id, Span>::default();
|
||||
|
||||
struct Span {
|
||||
name: &'static str,
|
||||
level: Level,
|
||||
target: &'static str,
|
||||
file: Option<&'static str>,
|
||||
line: Option<u32>,
|
||||
args: FxHashMap<&'static str, String>,
|
||||
}
|
||||
|
||||
let pid = std::process::id();
|
||||
|
||||
let mut comma = "";
|
||||
loop {
|
||||
match recv.recv().unwrap() {
|
||||
Msg::Event {
|
||||
tid,
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file: c_file,
|
||||
line,
|
||||
args,
|
||||
ts,
|
||||
} => {
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"ts":{},"ph":"i","name":"{}","cat":"{}","args":{{"target":"{}""#,
|
||||
comma,
|
||||
pid,
|
||||
tid,
|
||||
ts,
|
||||
NameDisplay(name, &args),
|
||||
level,
|
||||
escape(target)
|
||||
)
|
||||
.unwrap();
|
||||
if let Some(f) = c_file {
|
||||
write!(&mut file, r#","file":"{}""#, escape(f)).unwrap();
|
||||
}
|
||||
if let Some(l) = line {
|
||||
write!(&mut file, r#","line":{}"#, l).unwrap();
|
||||
}
|
||||
for (arg_name, arg_value) in args {
|
||||
write!(&mut file, r#","{}":{}"#, escape(arg_name), arg_value).unwrap();
|
||||
}
|
||||
write!(&mut file, "}}}}").unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Enter { id, tid, ts } => {
|
||||
let span = spans.get(&id).unwrap();
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"name":"{}","cat":"{}","ph":"B","ts":{},"args":{{"target":"{}""#,
|
||||
comma,
|
||||
pid,
|
||||
ThreadIdDisplay(tid, &span.args),
|
||||
NameDisplay(span.name, &span.args),
|
||||
span.level,
|
||||
ts,
|
||||
escape(span.target)
|
||||
)
|
||||
.unwrap();
|
||||
if let Some(f) = span.file {
|
||||
write!(&mut file, r#","file":"{}""#, escape(f)).unwrap();
|
||||
}
|
||||
if let Some(l) = span.line {
|
||||
write!(&mut file, r#","line":{}"#, l).unwrap();
|
||||
}
|
||||
for (arg_name, arg_value) in &span.args {
|
||||
write!(&mut file, r#","{}":{}"#, escape(arg_name), arg_value).unwrap();
|
||||
}
|
||||
write!(&mut file, "}}}}").unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Exit { id, tid, ts } => {
|
||||
let span = spans.get(&id).unwrap();
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"ph":"E","ts":{}}}"#,
|
||||
comma,
|
||||
pid,
|
||||
ThreadIdDisplay(tid, &span.args),
|
||||
ts
|
||||
)
|
||||
.unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::NewSpan {
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file,
|
||||
line,
|
||||
args,
|
||||
} => {
|
||||
spans.insert(
|
||||
id,
|
||||
Span {
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file,
|
||||
line,
|
||||
args,
|
||||
},
|
||||
);
|
||||
}
|
||||
Msg::ThreadInfo { id, name } => {
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"name":"thread_name","ph":"M","pid":{},"tid":{},"args":{{"name":"{}"}}}}"#,
|
||||
comma, pid, id, name
|
||||
)
|
||||
.unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Finish => break,
|
||||
struct Span {
|
||||
name: &'static str,
|
||||
level: Level,
|
||||
target: &'static str,
|
||||
file: Option<&'static str>,
|
||||
line: Option<u32>,
|
||||
args: FxHashMap<&'static str, String>,
|
||||
}
|
||||
}
|
||||
write!(&mut file, "]}}").unwrap();
|
||||
|
||||
file.flush().unwrap();
|
||||
}).unwrap();
|
||||
let pid = std::process::id();
|
||||
|
||||
let mut comma = "";
|
||||
loop {
|
||||
match recv.recv().unwrap() {
|
||||
Msg::Event {
|
||||
tid,
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file: c_file,
|
||||
line,
|
||||
args,
|
||||
ts,
|
||||
} => {
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"ts":{},"ph":"i","name":"{}","cat":"{}","args":{{"target":"{}""#,
|
||||
comma,
|
||||
pid,
|
||||
tid,
|
||||
ts,
|
||||
NameDisplay(name, &args),
|
||||
level,
|
||||
escape(target)
|
||||
)
|
||||
.unwrap();
|
||||
if let Some(f) = c_file {
|
||||
write!(&mut file, r#","file":"{}""#, escape(f)).unwrap();
|
||||
}
|
||||
if let Some(l) = line {
|
||||
write!(&mut file, r#","line":{}"#, l).unwrap();
|
||||
}
|
||||
for (arg_name, arg_value) in args {
|
||||
write!(&mut file, r#","{}":{}"#, escape(arg_name), arg_value).unwrap();
|
||||
}
|
||||
write!(&mut file, "}}}}").unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Enter { id, tid, ts } => {
|
||||
let span = spans.get(&id).unwrap();
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"name":"{}","cat":"{}","ph":"B","ts":{},"args":{{"target":"{}""#,
|
||||
comma,
|
||||
pid,
|
||||
ThreadIdDisplay(tid, &span.args),
|
||||
NameDisplay(span.name, &span.args),
|
||||
span.level,
|
||||
ts,
|
||||
escape(span.target)
|
||||
)
|
||||
.unwrap();
|
||||
if let Some(f) = span.file {
|
||||
write!(&mut file, r#","file":"{}""#, escape(f)).unwrap();
|
||||
}
|
||||
if let Some(l) = span.line {
|
||||
write!(&mut file, r#","line":{}"#, l).unwrap();
|
||||
}
|
||||
for (arg_name, arg_value) in &span.args {
|
||||
write!(&mut file, r#","{}":{}"#, escape(arg_name), arg_value).unwrap();
|
||||
}
|
||||
write!(&mut file, "}}}}").unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Exit { id, tid, ts } => {
|
||||
let span = spans.get(&id).unwrap();
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"pid":{},"tid":{},"ph":"E","ts":{}}}"#,
|
||||
comma,
|
||||
pid,
|
||||
ThreadIdDisplay(tid, &span.args),
|
||||
ts
|
||||
)
|
||||
.unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::NewSpan {
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file,
|
||||
line,
|
||||
args,
|
||||
} => {
|
||||
spans.insert(
|
||||
id,
|
||||
Span {
|
||||
level,
|
||||
name,
|
||||
target,
|
||||
file,
|
||||
line,
|
||||
args,
|
||||
},
|
||||
);
|
||||
}
|
||||
Msg::ThreadInfo { id, name } => {
|
||||
write!(
|
||||
&mut file,
|
||||
r#"{}{{"name":"thread_name","ph":"M","pid":{},"tid":{},"args":{{"name":"{}"}}}}"#,
|
||||
comma, pid, id, name
|
||||
)
|
||||
.unwrap();
|
||||
comma = ",";
|
||||
}
|
||||
Msg::Finish => break,
|
||||
}
|
||||
}
|
||||
write!(&mut file, "]}}").unwrap();
|
||||
|
||||
file.flush().unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
tracing::dispatcher::set_global_default(tracing::Dispatch::new(Profiler::new(sender.clone()))).unwrap();
|
||||
|
||||
|
|
|
@ -12,12 +12,15 @@ fn main() {
|
|||
"run" | "r" => run(args),
|
||||
"doc" => doc(args),
|
||||
"expand" => expand(args),
|
||||
"check" | "c" => check(args),
|
||||
"build" | "b" => build(args),
|
||||
"prebuild" => prebuild(args),
|
||||
"clean" => clean(args),
|
||||
"asm" => asm(args),
|
||||
"rust_analyzer_run" => rust_analyzer_run(args),
|
||||
"rust_analyzer_check" => rust_analyzer_check(args),
|
||||
"help" | "--help" => help(args),
|
||||
_ => fatal(f!("unknown task {:?}, `{} help` to list tasks", task, DO)),
|
||||
_ => fatal(f!("unknown task {:?}, `{} help` to list tasks", task, do_cmd())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +321,12 @@ fn fmt(args: Vec<&str>) {
|
|||
println("done");
|
||||
}
|
||||
|
||||
// do check, c
|
||||
// Runs clippy on the workspace.
|
||||
fn check(args: Vec<&str>) {
|
||||
cmd("cargo", &["clippy", "--no-deps", "--workspace"], &args);
|
||||
}
|
||||
|
||||
// do build, b [-e, --example] [--all] [-t, --timing] [<cargo-build-args>]
|
||||
// Compile the main crate and its dependencies.
|
||||
// USAGE:
|
||||
|
@ -435,8 +444,10 @@ fn clean(mut args: Vec<&str>) {
|
|||
}
|
||||
cmd("cargo", &["clean", "--manifest-path", &tool_], &args);
|
||||
}
|
||||
|
||||
// external because it will delete self.
|
||||
cmd_external("cargo", &["clean", "--manifest-path", env!("DO_MANIFEST_PATH")], &args);
|
||||
let manifest_path = format!("{}/Cargo.toml", file!().strip_prefix("/src/main.rs").unwrap());
|
||||
cmd_external("cargo", &["clean", "--manifest-path", &manifest_path], &args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,6 +501,18 @@ fn asm(mut args: Vec<&str>) {
|
|||
cmd("cargo", &asm_args, &args);
|
||||
}
|
||||
|
||||
fn rust_analyzer_run(args: Vec<&str>) {
|
||||
if let Some(&"check") = args.first() {
|
||||
cmd("cargo", &["clippy", "--no-deps"], &args[1..]);
|
||||
} else {
|
||||
cmd("cargo", &args, &[]);
|
||||
}
|
||||
}
|
||||
|
||||
fn rust_analyzer_check(args: Vec<&str>) {
|
||||
cmd("cargo", &["clippy", "--no-deps", "--workspace", "--message-format=json"], &args)
|
||||
}
|
||||
|
||||
// do help, --help [task]
|
||||
// Prints help for all tasks.
|
||||
// USAGE:
|
||||
|
@ -499,7 +522,7 @@ fn help(mut args: Vec<&str>) {
|
|||
println(f!(
|
||||
"\n{}{}{} ({} {})",
|
||||
c_wb(),
|
||||
DO,
|
||||
do_cmd(),
|
||||
c_w(),
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_VERSION")
|
||||
|
@ -510,7 +533,7 @@ fn help(mut args: Vec<&str>) {
|
|||
if !specific_task {
|
||||
println(f!(" {}", env!("CARGO_PKG_DESCRIPTION")));
|
||||
println("\nUSAGE:");
|
||||
println(f!(" {} TASK [<TASK-ARGS>]", DO));
|
||||
println(f!(" {} TASK [<TASK-ARGS>]", do_cmd()));
|
||||
println("\nFLAGS:");
|
||||
println(r#" --dump Redirect output to "dump.log" or other file specified by task."#);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ use std::format_args as f;
|
|||
use std::io::Write;
|
||||
use std::process::{self, Command, Stdio};
|
||||
|
||||
// shell script that builds and runs do-tasks.
|
||||
pub static DO: &str = env!("DO_NAME");
|
||||
// Command line to run `do`
|
||||
pub fn do_cmd() -> String {
|
||||
env::var("DO_CMD").ok().unwrap_or_else(|| "cargo do".to_owned())
|
||||
}
|
||||
|
||||
// Run a command, args are chained, empty ("") arg strings are filtered, command streams are inherited.
|
||||
pub fn cmd(cmd: &str, default_args: &[&str], user_args: &[&str]) {
|
||||
|
@ -157,7 +159,7 @@ pub fn args() -> (&'static str, Vec<&'static str>) {
|
|||
info.dump = take_flag(&mut args, &["--dump"]);
|
||||
|
||||
// prints header
|
||||
println(f!("{}Running{}: {}{} {:?} {:?}", c_green(), c_wb(), DO, c_w(), task, args));
|
||||
println(f!("{}Running{}: {}{} {:?} {:?}", c_green(), c_wb(), do_cmd(), c_w(), task, args));
|
||||
|
||||
(task, args)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue