mirror of https://github.com/passcod/cargo-watch
wip
This commit is contained in:
parent
2dfdd4768c
commit
edd920cde1
|
@ -13,6 +13,9 @@ use tempfile::TempDir;
|
|||
|
||||
#[derive(Debug, Parser)]
|
||||
struct Args {
|
||||
#[clap(long)]
|
||||
no_cargo: bool,
|
||||
|
||||
#[clap(long)]
|
||||
vcs: Option<String>,
|
||||
|
||||
|
@ -43,18 +46,20 @@ fn main() -> Result<()> {
|
|||
|
||||
let tmp_dir = TempDir::new_in(".").into_diagnostic()?;
|
||||
|
||||
let mut init_args = vec!["init", "--quiet", "--name", "cw-test", "--offline"];
|
||||
if args.bin {
|
||||
init_args.push("--bin");
|
||||
if !args.no_cargo {
|
||||
let mut init_args = vec!["init", "--quiet", "--name", "cw-test", "--offline"];
|
||||
if args.bin {
|
||||
init_args.push("--bin");
|
||||
}
|
||||
if let Some(vcs) = &args.vcs {
|
||||
init_args.push("--vcs");
|
||||
init_args.push(vcs);
|
||||
}
|
||||
cmd("cargo", init_args)
|
||||
.dir(tmp_dir.path())
|
||||
.run()
|
||||
.into_diagnostic()?;
|
||||
}
|
||||
if let Some(vcs) = &args.vcs {
|
||||
init_args.push("--vcs");
|
||||
init_args.push(vcs);
|
||||
}
|
||||
cmd("cargo", init_args)
|
||||
.dir(tmp_dir.path())
|
||||
.run()
|
||||
.into_diagnostic()?;
|
||||
|
||||
let before = Duration::from_millis(args.before);
|
||||
let between = Duration::from_millis(args.between);
|
||||
|
|
|
@ -7,6 +7,7 @@ pub use init::init;
|
|||
pub use runtime::runtime;
|
||||
|
||||
mod init;
|
||||
//mod origin;
|
||||
mod runtime;
|
||||
|
||||
pub fn get_args() -> (Args, Vec<&'static str>) {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
use std::{path::PathBuf, env};
|
||||
|
||||
use dunce::canonicalize;
|
||||
use miette::{Result, IntoDiagnostic};
|
||||
use project_origins::ProjectType;
|
||||
use tracing::debug;
|
||||
use watchexec::paths::common_prefix;
|
||||
|
||||
use crate::args::Args;
|
||||
|
||||
pub async fn dirs(args: &Args) -> Result<(PathBuf, PathBuf)> {
|
||||
let curdir = env::current_dir()
|
||||
.and_then(canonicalize)
|
||||
.into_diagnostic()?;
|
||||
debug!(?curdir, "current directory");
|
||||
|
||||
let project_origin = if let Some(origin) = args.project_origin {
|
||||
debug!(?origin, "project origin override");
|
||||
canonicalize(origin).into_diagnostic()?
|
||||
} else {
|
||||
let homedir = dirs::home_dir()
|
||||
.map(canonicalize)
|
||||
.transpose()
|
||||
.into_diagnostic()?;
|
||||
debug!(?homedir, "home directory");
|
||||
|
||||
let mut paths = HashSet::new();
|
||||
for path in args.values_of_os("paths").unwrap_or_default() {
|
||||
paths.insert(canonicalize(path).into_diagnostic()?);
|
||||
}
|
||||
|
||||
let homedir_requested = homedir.as_ref().map_or(false, |home| paths.contains(home));
|
||||
debug!(
|
||||
?homedir_requested,
|
||||
"resolved whether the homedir is explicitly requested"
|
||||
);
|
||||
|
||||
if paths.is_empty() {
|
||||
debug!("no paths, using current directory");
|
||||
paths.insert(curdir.clone());
|
||||
}
|
||||
|
||||
debug!(?paths, "resolved all watched paths");
|
||||
|
||||
let mut origins = HashSet::new();
|
||||
for path in paths {
|
||||
origins.extend(project_origins::origins(&path).await);
|
||||
}
|
||||
|
||||
match (homedir, homedir_requested) {
|
||||
(Some(ref dir), false) if origins.contains(dir) => {
|
||||
debug!("removing homedir from origins");
|
||||
origins.remove(dir);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if origins.is_empty() {
|
||||
debug!("no origins, using current directory");
|
||||
origins.insert(curdir.clone());
|
||||
}
|
||||
|
||||
debug!(?origins, "resolved all project origins");
|
||||
|
||||
// This canonicalize is probably redundant
|
||||
canonicalize(
|
||||
common_prefix(&origins)
|
||||
.ok_or_else(|| miette!("no common prefix, but this should never fail"))?,
|
||||
)
|
||||
.into_diagnostic()?
|
||||
};
|
||||
info!(?project_origin, "resolved common/project origin");
|
||||
|
||||
let workdir = curdir;
|
||||
info!(?workdir, "resolved working directory");
|
||||
|
||||
Ok((project_origin, workdir))
|
||||
}
|
|
@ -9,7 +9,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use miette::{miette, IntoDiagnostic, Report, Result};
|
||||
use miette::{miette, IntoDiagnostic, Report, Result, bail};
|
||||
use tracing::{debug, info};
|
||||
use watchexec::{
|
||||
action::{Action, Outcome, PostSpawn, PreSpawn},
|
||||
|
@ -103,6 +103,7 @@ pub fn runtime(args: &Args, command_order: Vec<&'static str>) -> Result<RuntimeC
|
|||
}
|
||||
|
||||
if let Some(delay) = &args.delay {
|
||||
// TODO: implement with FromStr and hook directly into Clap
|
||||
let delay = if delay.ends_with("ms") {
|
||||
let d: u64 = delay.trim_end_matches("ms").parse().into_diagnostic()?;
|
||||
Duration::from_millis(d)
|
||||
|
@ -110,10 +111,10 @@ pub fn runtime(args: &Args, command_order: Vec<&'static str>) -> Result<RuntimeC
|
|||
let d: f64 = delay.parse().into_diagnostic()?;
|
||||
let delay = (d * 1000.0).round();
|
||||
if delay.is_infinite() || delay.is_nan() || delay.is_sign_negative() {
|
||||
return Err(Report::msg("delay must be finite and non-negative"));
|
||||
bail!("delay must be finite and non-negative");
|
||||
}
|
||||
if delay >= 1000.0 {
|
||||
return Err(Report::msg("delay must be less than 1000 seconds"));
|
||||
bail!("delay must be less than 1000 seconds");
|
||||
}
|
||||
|
||||
// SAFETY: delay is finite, not nan, non-negative, and less than 1000
|
||||
|
@ -129,24 +130,7 @@ pub fn runtime(args: &Args, command_order: Vec<&'static str>) -> Result<RuntimeC
|
|||
|
||||
// config.command_grouped(args.process_group);
|
||||
|
||||
let quiet = args.quiet;
|
||||
let clear = args.clear;
|
||||
let notif = args.notif;
|
||||
let on_busy = if args.restart {
|
||||
"restart"
|
||||
} else {
|
||||
"do-nothing"
|
||||
};
|
||||
|
||||
// TODO: add using SubSignal in Args directly
|
||||
// let mut signal = args
|
||||
// .signal
|
||||
// .map(SubSignal::from_str)
|
||||
// .transpose()
|
||||
// .into_diagnostic()?
|
||||
// .unwrap_or(SubSignal::Terminate);
|
||||
|
||||
let print_events = args.why;
|
||||
let Args { quiet, clear, notif, restart, print_events, .. } = *args;
|
||||
let quit_after_n = args.quit_after_n.map(|n| Arc::new(AtomicU8::new(n)));
|
||||
let delay_run = args.delay_run.map(Duration::from_secs);
|
||||
|
||||
|
@ -258,11 +242,10 @@ pub fn runtime(args: &Args, command_order: Vec<&'static str>) -> Result<RuntimeC
|
|||
};
|
||||
|
||||
let when_idle = start.clone();
|
||||
let when_running = match on_busy {
|
||||
"do-nothing" => Outcome::DoNothing,
|
||||
"restart" => Outcome::both(Outcome::Stop, start),
|
||||
// "signal" => Outcome::Signal(signal),
|
||||
_ => Outcome::DoNothing,
|
||||
let when_running = if restart {
|
||||
Outcome::both(Outcome::Stop, start)
|
||||
} else {
|
||||
Outcome::DoNothing
|
||||
};
|
||||
|
||||
if let Some(runs) = quit_after_n.clone() {
|
||||
|
@ -354,12 +337,8 @@ fn cargo_command(arg: &str, features: &Option<String>) -> Result<Command> {
|
|||
.clone();
|
||||
|
||||
if let Some(features) = features.as_ref() {
|
||||
if subc.starts_with('b')
|
||||
|| subc == "check"
|
||||
|| subc == "doc"
|
||||
|| subc.starts_with('r')
|
||||
|| subc == "test"
|
||||
|| subc == "install"
|
||||
if let "build" | "b" | "check" | "c" | "doc" | "d" | "run" | "r" | "test" | "t"
|
||||
| "install" | "publish" = subc.as_str()
|
||||
{
|
||||
lexed.insert(1, "--features".into());
|
||||
lexed.insert(2, features.into());
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Starting outside a cargo project isn't supported, but we want to make sure to error nicely:
|
||||
```
|
||||
$ test-cw --no-cargo
|
||||
```
|
Loading…
Reference in New Issue