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
6 changes: 3 additions & 3 deletions docs/behavioural-testing-in-rust-with-cucumber.md
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ aligned with what is needed.
Stack Overflow, accessed on 14 July 2025,
<https://stackoverflow.com/questions/30505639/how-to-do-error-handling-in-rust-and-what-are-the-common-pitfalls>

[^23]: Data tables - Cucumber Rust Book, accessed on 14 July 2025,
[^23]: Data tables Cucumber Rust Bookaccessed on 14 July 2025
<https://cucumber-rs.github.io/cucumber/main/writing/data_tables.html>

[^24]: Cucumber Data Tables — Tutorialspoint, accessed on 14 July 2025,
Expand Down Expand Up @@ -1164,8 +1164,8 @@ aligned with what is needed.
accessed on July 14, 2025,
<https://medium.com/@realtalkdev/common-challenges-in-cucumber-testing-and-how-to-overcome-them-dc95fffb43c8>

[^31]: Cucumber in cucumber - Rust - [Docs.rs](http://Docs.rs), accessed on
14 July 2025,
[^31]: Cucumber in cucumber Rust [Docs.rs](http://Docs.rs)accessed on 14
July 2025
<https://docs.rs/cucumber/latest/cucumber/struct.Cucumber.html>

[^32]: CLI (command-line interface) - Cucumber Rust Book, accessed on
Expand Down
51 changes: 51 additions & 0 deletions docs/netsuke-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,49 @@ pub enum StringOrList {
flexibility for users to specify single sources, dependencies, and rule names
as a simple string and multiple as a list, enhancing user-friendliness.*

#### Example Manifest and AST

The following minimal Netsukefile shows how the derived structures behave when
unknown fields are denied.

YAML

```yaml
netsuke_version: "1.0.0"
targets:
- name: hello
recipe:
kind: command
command: echo hi
```

Rust

```rust
use std::collections::HashMap;
use netsuke::ast::*;

let ast = NetsukeManifest {
netsuke_version: Version::parse("1.0.0").unwrap(),
vars: HashMap::new(),
rules: vec![],
steps: vec![],
targets: vec![Target {
name: StringOrList::String("hello".into()),
recipe: Recipe::Command {
command: "echo hi".into(),
},
sources: StringOrList::Empty,
deps: StringOrList::Empty,
order_only_deps: StringOrList::Empty,
vars: HashMap::new(),
phony: false,
always: false,
}],
defaults: vec![],
};
```

### 3.3 The Two-Pass Parsing Requirement

The integration of a templating engine like Jinja fundamentally shapes the
Expand Down Expand Up @@ -549,6 +592,14 @@ follows semantic versioning rules. Global and target variable maps now share
the `HashMap<String, String>` type for consistency. This keeps YAML manifests
concise while ensuring forward compatibility.

### 3.5 Testing

Unit tests in `tests/ast_tests.rs` and behavioural scenarios in
`tests/features/manifest.feature` exercise the deserialization logic. They
assert that manifests fail to parse when unknown fields are present, and that a
minimal manifest round-trips correctly. This suite guards against regressions
as the schema evolves.

## Section 4: Dynamic Builds with the Jinja Templating Engine

To provide the dynamic capabilities and logical expressiveness that make a
Expand Down
4 changes: 2 additions & 2 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ compilation pipeline from parsing to execution.
(NetsukeManifest, Rule, Target, StringOrList, Recipe) in `src/ast.rs`.
*(done)*

- [ ] Annotate AST structs with #[derive(Deserialize)] and
- [x] Annotate AST structs with #[derive(Deserialize)] and
#[serde(deny_unknown_fields)]
to enable serde_yml parsing.
to enable serde_yml parsing. *(done)*

- [ ] Implement parsing for the netsuke_version field and validate it using
the semver crate.
Expand Down
2 changes: 1 addition & 1 deletion tests/steps/manifest_steps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::fs;

#[expect(
clippy::needless_pass_by_value,
reason = "Cucumber requires owned String arguments",
reason = "Cucumber requires owned String arguments"
)]
#[when(expr = "the manifest file {string} is parsed")]
fn parse_manifest(world: &mut CliWorld, path: String) {
Expand Down