Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
target/
**/*.rs.bk
**/*~
.crush
build.ninja
95 changes: 95 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ cucumber = "0.20.0"
tokio = { version = "1", features = ["macros", "rt-multi-thread"], default-features = false }
insta = { version = "1", features = ["yaml"] }
tempfile = "3"
serial_test = "3"

[[test]]
name = "cucumber"
Expand Down
18 changes: 10 additions & 8 deletions docs/netsuke-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -1138,12 +1138,14 @@ The command construction will follow this pattern:
`ninja` is available in the system's `PATH`.

1. Arguments passed to Netsuke's own CLI will be translated and forwarded to
Ninja. For example, a `Netsuke build -C build/ my_target` command would
result in `Command::new("ninja").arg("-C").arg("build/").arg("my_target")`.
Flags like `-j` for parallelism will also be passed through.[^8]
Ninja. For example, a `Netsuke build my_target` command would result in
`Command::new("ninja").arg("my_target")`. Flags like `-j` for parallelism
will also be passed through.[^8]

1. The working directory for the Ninja process will be set using
`.current_dir()` if the user provides a `-C` flag.
`.current_dir()`. When the user supplies a `-C` flag, Netsuke
canonicalises the path and applies it via `current_dir` rather than
forwarding the flag to Ninja.

1. Standard I/O streams (`stdin`, `stdout`, `stderr`) will be configured using
`.stdout(Stdio::piped())` and `.stderr(Stdio::piped())`.[^24] This allows
Expand Down Expand Up @@ -1418,10 +1420,10 @@ The CLI is implemented using clap's derive API in `src/cli.rs`. Clap's
`default_value_t` attribute marks `Build` as the default subcommand, so
invoking `netsuke` with no explicit command still triggers a build. CLI
execution and dispatch live in `src/runner.rs`, keeping `main.rs` focused on
parsing. The working directory flag uses `-C` to mirror Ninja's convention,
ensuring command line arguments map directly onto the underlying build tool.
Error scenarios are validated using clap's `ErrorKind` enumeration in unit
tests and via Cucumber steps for behavioural coverage.
parsing. The working directory flag mirrors Ninja's `-C` option but is resolved
internally; Netsuke changes directory before spawning Ninja rather than
forwarding the flag. Error scenarios are validated using clap's `ErrorKind`
enumeration in unit tests and via Cucumber steps for behavioural coverage.

## Section 9: Implementation Roadmap and Strategic Recommendations

Expand Down
2 changes: 1 addition & 1 deletion src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub struct Rule {
/// Exactly one variant must be provided for a rule or target. The fields are
/// flattened in the manifest, so the presence of `command`, `script`, or `rule`
/// determines the variant.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum Recipe {
/// A single shell command.
Command { command: String },
Expand Down
7 changes: 6 additions & 1 deletion src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,12 @@ fn redact_sensitive_args(args: &[String]) -> Vec<String> {
pub fn run_ninja(program: &Path, cli: &Cli, targets: &[String]) -> io::Result<()> {
let mut cmd = Command::new(program);
if let Some(dir) = &cli.directory {
cmd.current_dir(dir).arg("-C").arg(dir);
// Resolve and canonicalise the directory so Ninja receives a stable
// absolute path. Using only `current_dir` avoids combining it with
// Ninja's own `-C` flag which would otherwise double-apply the
// directory and break relative paths.
let dir = fs::canonicalize(dir)?;
cmd.current_dir(dir);
}
if let Some(jobs) = cli.jobs {
cmd.arg("-j").arg(jobs.to_string());
Expand Down
2 changes: 1 addition & 1 deletion tests/ninja_snapshot_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn touch_manifest_ninja_validation() {
let _ = ninja_cmd(&["-t", "targets", "all"]);
let _ = ninja_cmd(&["-t", "query", "out/a"]);

let _ = ninja_cmd(&["-w", "dupbuild=err", "-d", "stats"]);
let _ = ninja_cmd(&["-w", "phonycycle=err", "-d", "stats"]);
let second = ninja_cmd(&["-n", "-d", "explain", "-v"]);
assert!(
second.contains("no work to do"),
Expand Down
Loading
Loading