Skip to content

Simplify manifest syntax#50

Merged
leynos merged 2 commits intomainfrom
codex/fix-netsukefile-syntax-in-tests
Aug 5, 2025
Merged

Simplify manifest syntax#50
leynos merged 2 commits intomainfrom
codex/fix-netsukefile-syntax-in-tests

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Aug 5, 2025

Summary

  • allow top-level command/script/rule fields instead of nested recipe kind blocks
  • update documentation and tests to match the streamlined manifest syntax

Testing

  • make fmt
  • make markdownlint
  • make lint
  • make test
  • make nixie (fails: failed copying files from cache to destination for package @mermaid-js/mermaid-cli)

https://chatgpt.com/codex/tasks/task_e_6891af74508c8322a0aee165f115ab68

Summary by Sourcery

Simplify manifest syntax by flattening recipe fields so that command, script, or rule keys appear directly at the top level of targets, rules, and actions, and by implementing custom untagged deserialization for the Recipe enum to enforce mutual exclusivity.

New Features:

  • Allow top-level command, script, and rule fields instead of nested recipe blocks for targets, rules, and actions.

Enhancements:

  • Remove serde kind tagging on the Recipe enum and add #[serde(flatten)] to embed its fields directly into Rule and Target structs.
  • Implement custom untagged deserialization for Recipe to ensure exactly one of command, script, or rule is specified.

Documentation:

  • Update documentation and examples to reflect the simplified, untagged manifest syntax.

Tests:

  • Revise parsing tests and YAML fixtures to use the new top-level recipe fields across all test data.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • New Features

    • Manifest files now use a simplified, flatter structure—commands, scripts, or rules are specified directly under targets or rules, without a nested recipe block or kind field.
  • Bug Fixes

    • Improved error handling: the system now enforces that only one of command, script, or rule is specified for each entry, providing clearer error messages for invalid configurations.
  • Documentation

    • Updated documentation and examples to reflect the new manifest format and validation rules.
  • Tests

    • Test data and cases updated to match the new, flatter manifest structure and validation logic.

Walkthrough

Flatten the manifest schema by removing the recipe wrapper and the kind discriminator from the Recipe enum. Update deserialization logic to infer the correct Recipe variant based on the presence of command, script, or rule fields, enforcing that only one is specified. Adjust documentation, tests, and YAML fixtures accordingly.

Changes

Cohort / File(s) Change Summary
Manifest schema and deserialization logic
src/ast.rs
Replace tagged enum deserialization for Recipe with custom logic enforcing mutual exclusivity; flatten Recipe fields in Rule and Target using #[serde(flatten)].
Manifest loader documentation
src/manifest.rs
Update documentation example to remove recipe wrapper and kind field, placing command directly under target.
User documentation
docs/netsuke-design.md
Revise schema explanation, remove references to kind and recipe wrapper, update manifest examples.
Parser and manifest structure tests
tests/ast_tests.rs
Flatten test YAML manifests by removing recipe and kind, placing command/rule directly under targets/actions.
YAML fixtures (targets, rules, actions)
tests/data/*
Remove recipe and kind fields from all YAML files, promote command/rule to top level under targets/rules/actions.
Ninja snapshot tests
tests/ninja_snapshot_tests.rs
Flatten manifest structure in test YAML by removing recipe and kind, updating to new schema.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ManifestParser
    participant Recipe

    User->>ManifestParser: Provide manifest YAML (command/script/rule at top level)
    ManifestParser->>Recipe: Deserialize, check for command/script/rule fields
    Recipe-->>ManifestParser: Return variant based on present field (error if multiple/none)
    ManifestParser-->>User: Parsed manifest structure
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Poem

📝
Farewell to kind, the tag of old,
No more recipes nested, no stories retold.
Now commands stand proud, at the manifest’s crest,
Parsing is sharper, the schema’s at rest.
With YAML now flatter, and logic precise,
Reviewers rejoice—conciseness is nice!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4f4fc4 and 0d0451b.

📒 Files selected for processing (3)
  • docs/netsuke-design.md (5 hunks)
  • src/ast.rs (5 hunks)
  • tests/ast_tests.rs (17 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.

Files:

  • docs/netsuke-design.md
**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.md: Documentation must use en-GB-oxendict spelling and grammar, except for the naming of the "LICENSE" file.
Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Tables and headings in Markdown must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.

Files:

  • docs/netsuke-design.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
  • Code blocks should be wrapped to 120 columns.
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/netsuke-design.md
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums: Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary: Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library: Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • src/ast.rs
  • tests/ast_tests.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • src/ast.rs
  • tests/ast_tests.rs
🧠 Learnings (1)
📚 Learning: applies to docs/src/ast.rs : implement the yaml parsing logic to deserialize a static netsukefile in...
Learnt from: CR
PR: leynos/netsuke#0
File: docs/roadmap.md:0-0
Timestamp: 2025-08-03T23:02:56.706Z
Learning: Applies to docs/src/ast.rs : Implement the YAML parsing logic to deserialize a static Netsukefile into the NetsukeManifest AST.

Applied to files:

  • src/ast.rs
🧬 Code Graph Analysis (1)
tests/ast_tests.rs (1)
tests/steps/manifest_steps.rs (1)
  • parse_manifest (44-46)
🔇 Additional comments (8)
tests/ast_tests.rs (3)

17-17: Correctly updated to use flattened syntax.

The test properly validates the new manifest structure without the nested recipe block.


96-114: Excellent test coverage for mutual exclusivity validation.

The tests comprehensively verify that empty mappings for command, script, and rule fields produce parsing errors, ensuring the custom deserializer properly enforces the constraint.


206-207: Good test for rejecting mixed syntax.

The test properly verifies that the old kind field is rejected when used alongside the new flattened recipe fields.

src/ast.rs (3)

119-160: Well-implemented custom deserializer with clear error messages.

The deserializer correctly enforces mutual exclusivity of command, script, and rule fields. The error messages are informative and will help users debug manifest issues effectively.


95-95: Correct use of serde flatten annotation.

The #[serde(flatten)] attribute properly enables the simplified manifest syntax by inlining recipe fields.


106-108: Clear documentation of the flattened structure.

The updated documentation accurately explains how recipe fields are now specified directly in the manifest.

docs/netsuke-design.md (2)

301-302: Accurate documentation of mutual exclusivity enforcement.

The documentation correctly describes how the parser validates that only one recipe field is specified, matching the implementation.


505-505: Example correctly demonstrates flattened syntax.

The YAML example properly shows the command field directly under the target without the nested recipe block.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/fix-netsukefile-syntax-in-tests

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Aug 5, 2025

Reviewer's Guide

This PR streamlines the manifest syntax by flattening the recipe variants into top-level fields (command, script, rule), refactors the Recipe enum deserialization to enforce mutual exclusivity, and updates documentation, code comments, and tests to match the new syntax.

ER diagram for flattened manifest fields

erDiagram
    NETSUKE_MANIFEST ||--o{ TARGET : contains
    NETSUKE_MANIFEST ||--o{ RULE : contains
    TARGET {
        StringOrList name
        String command
        String script
        StringOrList rule
        String description
    }
    RULE {
        string name
        string command
        string script
        StringOrList rule
        string description
    }
Loading

Class diagram for updated Recipe deserialization and manifest structure

classDiagram
    class NetsukeManifest {
        +Vec<Target> targets
        +Vec<Rule> rules
    }
    class Target {
        +StringOrList name
        +Recipe recipe
        +Vec<StringOrList> sources
        +Option<String> description
    }
    class Rule {
        +String name
        +Recipe recipe
        +Option<String> description
        +Vec<String> tags
    }
    class Recipe {
        <<enum>>
        Command(command: String)
        Script(script: String)
        Rule(rule: StringOrList)
    }
    NetsukeManifest "1" o-- "*" Target
    NetsukeManifest "1" o-- "*" Rule
    Target "1" o-- "1" Recipe
    Rule "1" o-- "1" Recipe
Loading

File-Level Changes

Change Details Files
Refactor Recipe enum to use flattened fields and custom deserialization
  • Remove serde tag/aliases on Recipe variants
  • Implement a custom Deserialize impl that ensures exactly one of command, script, or rule is present
  • Add #[serde(flatten)] to recipe fields in Rule, Target, and NetsukeManifest structs
src/ast.rs
src/manifest.rs
Update documentation and test fixtures for streamlined syntax
  • Remove nested recipe: { kind: ..., ... } blocks in code examples and docs
  • Revise docs/netsuke-design.md to describe untagged recipe union based on field presence
  • Convert all test cases and data fixtures (ast_tests, ninja_snapshot_tests, tests/data) to use top-level command/rule fields
docs/netsuke-design.md
tests/ast_tests.rs
tests/ninja_snapshot_tests.rs
tests/data/*

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @leynos - I've reviewed your changes and found some issues that need to be addressed.

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `src/ast.rs:119` </location>
<code_context>
     Rule { rule: StringOrList },
 }

+impl<'de> Deserialize<'de> for Recipe {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        #[derive(Deserialize)]
+        struct RawRecipe {
+            command: Option<String>,
+            script: Option<String>,
+            rule: Option<StringOrList>,
+        }
+
+        let raw = RawRecipe::deserialize(deserializer)?;
</code_context>

<issue_to_address>
Manual deserialization logic for Recipe does not provide detailed error context.

Consider updating the error messages to specify which fields are present or missing to aid in debugging manifest issues.
</issue_to_address>

### Comment 2
<location> `tests/ast_tests.rs:96` </location>
<code_context>
         targets:
           - name: hello
-            recipe: {}
+            command: {}
     "#;
     assert!(manifest::from_str(yaml).is_err());
</code_context>

<issue_to_address>
Test for empty command/script/rule fields is present, but consider adding similar tests for 'script' and 'rule'.

Please add tests for empty 'script' and 'rule' fields to ensure all mutually exclusive fields are properly validated.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/ast.rs
Comment thread tests/ast_tests.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46d1a0b and a4f4fc4.

📒 Files selected for processing (20)
  • docs/netsuke-design.md (5 hunks)
  • src/ast.rs (5 hunks)
  • src/manifest.rs (1 hunks)
  • tests/ast_tests.rs (19 hunks)
  • tests/data/action_invalid.yml (1 hunks)
  • tests/data/actions.yml (1 hunks)
  • tests/data/circular.yml (1 hunks)
  • tests/data/duplicate_outputs.yml (1 hunks)
  • tests/data/duplicate_outputs_multi.yml (1 hunks)
  • tests/data/duplicate_rules.yml (1 hunks)
  • tests/data/empty_rule.yml (1 hunks)
  • tests/data/invalid_version.yml (1 hunks)
  • tests/data/minimal.yml (1 hunks)
  • tests/data/missing_rule.yml (1 hunks)
  • tests/data/multiple_rules_per_target.yml (1 hunks)
  • tests/data/phony.yml (1 hunks)
  • tests/data/rule_not_found.yml (1 hunks)
  • tests/data/rules.yml (1 hunks)
  • tests/data/unknown_field.yml (1 hunks)
  • tests/ninja_snapshot_tests.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums: Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary: Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library: Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • src/manifest.rs
  • tests/ast_tests.rs
  • tests/ninja_snapshot_tests.rs
  • src/ast.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • src/manifest.rs
  • tests/ast_tests.rs
  • tests/ninja_snapshot_tests.rs
  • src/ast.rs
docs/**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.

Files:

  • docs/netsuke-design.md
**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.md: Documentation must use en-GB-oxendict spelling and grammar, except for the naming of the "LICENSE" file.
Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Tables and headings in Markdown must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.

Files:

  • docs/netsuke-design.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
  • Code blocks should be wrapped to 120 columns.
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/netsuke-design.md
🧠 Learnings (1)
📚 Learning: applies to docs/src/ast.rs : implement the yaml parsing logic to deserialize a static netsukefile in...
Learnt from: CR
PR: leynos/netsuke#0
File: docs/roadmap.md:0-0
Timestamp: 2025-08-03T23:02:56.706Z
Learning: Applies to docs/src/ast.rs : Implement the YAML parsing logic to deserialize a static Netsukefile into the NetsukeManifest AST.

Applied to files:

  • src/ast.rs
🔇 Additional comments (23)
tests/data/action_invalid.yml (1)

1-8: Changes correctly reflect the new flattened manifest schema.

The test fixture properly demonstrates an invalid action case where neither command nor rule is specified, and the comment accurately describes the expected failure behaviour.

src/ast.rs (4)

13-13: Documentation example correctly updated.

The example YAML string properly demonstrates the flattened syntax with command directly under the target.


119-149: Well-implemented custom deserializer for Recipe enum.

The implementation correctly enforces mutual exclusivity of recipe fields with clear error messages. The use of iter().count() on Options is an elegant way to validate exactly one field is present.


95-96: Correct use of serde flatten attribute.

The #[serde(flatten)] attribute properly inlines Recipe fields into the Rule structure, achieving the desired flattened YAML format.


162-163: Consistent flattening approach for Target struct.

The #[serde(flatten)] attribute maintains consistency with the Rule struct implementation.

src/manifest.rs (1)

22-22: Documentation example properly updated.

The example correctly demonstrates the flattened syntax without the recipe wrapper.

tests/data/circular.yml (1)

5-8: Test fixture correctly updated to flattened syntax.

The circular dependency test case maintains its purpose while adopting the new manifest structure.

tests/data/minimal.yml (1)

4-4: Minimal test case properly updated.

The fixture correctly demonstrates the simplest valid manifest with the flattened syntax.

tests/data/empty_rule.yml (1)

5-5: Clarify handling of an empty rule array

The manifest now serialises an empty list for rule. Verify that the parser surfaces the intended validation error (or lack thereof) with the flattened schema, and update the negative-test assertion if the error message changed.

tests/data/phony.yml (1)

4-4: Flattening of command field is correct

Promotion of command to the target level aligns with the new schema. No further action required.

tests/data/missing_rule.yml (1)

5-5: Ensure missing-rule diagnostic still triggers

With the rule field flattened, confirm that the parser still produces the expected “rule not found” failure and that the test asserts against the new error text if it changed.

tests/data/rule_not_found.yml (1)

5-5: Validate unresolved-rule path

Maintain the negative-test assertion for an undefined rule after the schema change; update expected error wording if necessary.

tests/data/unknown_field.yml (1)

5-5: Flattened command field accepted

The target now directly declares command, which is in line with the new manifest design. The fixture keeps extra to exercise the unknown-field path; no additional changes needed.

tests/data/duplicate_outputs_multi.yml (1)

7-12: No issues – schema flattening looks correct
The command field is now placed at the target level, matching the new manifest format. The fixture continues to express the duplicate-output situation the test intends.

tests/data/invalid_version.yml (1)

4-4: Preserve the negative-case intent
The file now includes a top-level command, so the only remaining error driver is the invalid version string. That still covers the intended failure path, so the fixture remains valid for its purpose.

tests/data/duplicate_outputs.yml (1)

5-8: LGTM – fixture matches flattened manifest
Both entries expose the duplicate outputs scenario with the new syntax. No further action required.

tests/data/actions.yml (1)

4-7: Align actions and targets with flattened syntax
The direct command keys conform to the updated deserialiser. Test coverage is preserved.

tests/ninja_snapshot_tests.rs (2)

34-35: Escape $ to silence rustfmt lints
rustfmt sometimes flags $out/$in in raw strings as macro placeholders. Escape them ($$out) or annotate the string with #[expect(clippy::...)] narrowly to avoid future CI breakages.

Also applies to: 38-38


34-39: Keep raw-string indentation consistent
The embedded YAML keeps its indentation, but lines 34 and 38 were re-indented one space relative to their peers. Align them to column 9 to avoid spurious diff noise in future edits.

-          - name: touch
-            command: "python3 -c 'import os,sys; open(sys.argv[1],\"a\").close()' $out"
+          - name: touch
+            command: "python3 -c 'import os,sys; open(sys.argv[1],\"a\").close()' $out"

Likely an incorrect or invalid review comment.

tests/data/multiple_rules_per_target.yml (1)

10-12: Verify intended failure path for multiple rules per target

The fixture supplies a list under rule. The design doc (Section 5.4, line 1107) states that multiple rules are not yet supported and should trigger IrGenError::MultipleRules. Ensure a test exercises this fixture and still expects a parse/IR‐generation failure after the schema change.

tests/data/rules.yml (2)

4-4: Flatten recipe block correctly
command now sits at the top level, matching the new schema and keeping the YAML concise.


8-8: Reference rule directly on target
Directly assigning rule: compile aligns with the simplified manifest and remains clear.

tests/data/duplicate_rules.yml (1)

10-13: Targets correctly reference their rules
hello.o and world.o now use the flattened rule field and point to distinct rule names, satisfying the updated schema.

Comment thread docs/netsuke-design.md Outdated
Comment thread tests/ast_tests.rs Outdated
Comment thread tests/data/duplicate_rules.yml
@leynos leynos merged commit 87853a6 into main Aug 5, 2025
3 of 4 checks passed
@leynos leynos deleted the codex/fix-netsukefile-syntax-in-tests branch August 5, 2025 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant