Skip to content

Add example manifests#2

Closed
leynos wants to merge 2 commits intomainfrom
codex/create-examples-directory-with-project-manifests
Closed

Add example manifests#2
leynos wants to merge 2 commits intomainfrom
codex/create-examples-directory-with-project-manifests

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Jul 12, 2025

Summary

  • provide five example Netsukefile templates
    • C compilation
    • SVG rasterising
    • photo workflow
    • book building
    • Python package

Testing

  • cargo fmt --all
  • mdformat-all
  • cargo clippy --all-targets --all-features -- -D warnings (fails: lint_groups_priority, print-stdout)
  • cargo test --all-targets --all-features

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

Summary by Sourcery

New Features:

  • Provide example Netsukefile templates for C compilation, SVG rasterising, photo workflow, book building, and Python packaging

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Jul 12, 2025

Reviewer's Guide

Adds five example Netsukefile YAML templates demonstrating common build and processing workflows by defining version, variables, templated rules, dynamic target generation, and default targets in standalone manifest files.

Class diagram for Netsukefile manifest structure

classDiagram
    class Manifest {
        +string netsuke_version
        +dict vars
        +list rules
        +list targets
        +list defaults
    }
    class Rule {
        +string name
        +string command
        +string description
    }
    class Target {
        +string name
        +string rule
        +list sources
        +list deps
    }
    Manifest "1" o-- "*" Rule : contains
    Manifest "1" o-- "*" Target : contains
    Rule <|-- CompileRule
    Rule <|-- LinkRule
    Rule <|-- DevelopRule
    Rule <|-- ThumbRule
    Rule <|-- RasteriseRule
    Rule <|-- BuildRule
    Rule <|-- SetupRule
    Rule <|-- InstallRule
    Rule <|-- TestRule
Loading

File-Level Changes

Change Details Files
Introduce example manifests showcasing five common workflows
  • Define Python package workflow with virtualenv setup, install, and test rules and targets
  • Define C application workflow with compile and link rules, dynamic object and executable targets
  • Define photo processing workflow with RAW development and thumbnail generation rules and dynamic targets
  • Define SVG to PNG rasterisation workflow with dynamic targets for each asset
  • Define book generation workflow via a Pandoc build rule and default PDF target
examples/python_package.yml
examples/c_app.yml
examples/photo_album.yml
examples/svg_to_png.yml
examples/book.yml

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 12, 2025

Summary by CodeRabbit

  • New Features
    • Added example configuration files for various build workflows, including document compilation, C application builds, photo processing, Python package management, and SVG to PNG conversion. These examples demonstrate automated build processes for different project types.

Summary by CodeRabbit

  • New Features
    • Added example build configurations for various workflows, including document compilation, C application builds, photo processing, Python package management, and SVG to PNG conversion. These examples demonstrate automated build processes for different project types.

Walkthrough

Introduce five new example YAML configuration files for the Netsuke build system. Each file demonstrates automated workflows for distinct domains: document compilation, C application builds, photo processing, Python package management, and SVG-to-PNG conversion. Define variables, build rules, dynamic targets, and default outputs for each scenario.

Changes

File(s) Change Summary
examples/book.yml Add YAML config for compiling a PDF manuscript from markdown chapters using Pandoc.
examples/c_app.yml Add YAML config for compiling and linking a C application, with dynamic object and executable targets.
examples/photo_album.yml Add YAML config for processing RAW photo files into JPEGs and thumbnails using darktable and convert.
examples/python_package.yml Add YAML config for Python package install and test workflow using pip and pytest.
examples/svg_to_png.yml Add YAML config for converting SVG files to PNGs using Inkscape, with dynamic target generation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Netsuke
    participant Shell

    User->>Netsuke: Invoke build (e.g., default target)
    Netsuke->>Shell: Execute defined build rules (e.g., pandoc, gcc, darktable-cli, pip, inkscape)
    Shell-->>Netsuke: Return command results
    Netsuke-->>User: Output build artefacts (PDF, executable, JPEGs, test results, PNGs)
Loading

Poem

Five new examples, crisp and neat,
YAML magic—builds complete!
Markdown to PDF, C code to run,
Photos processed, Python fun.
SVGs rasterised, all with flair—
Type netsuke, builds are there!
🛠️✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/create-examples-directory-with-project-manifests

🪧 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.
    • @coderabbitai modularize this function.
  • 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.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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 auto-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.

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.

  • Consider adding a directory-creation step (e.g. mkdir -p {{ outdir }}) in the rules that write to build/... so the target dirs exist before files are generated.
  • It’d be clearer to standardise on one templating helper (either basename+replace or just replace) across all examples for consistent path manipulation.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider adding a directory-creation step (e.g. `mkdir -p {{ outdir }}`) in the rules that write to `build/...` so the target dirs exist before files are generated.
- It’d be clearer to standardise on one templating helper (either `basename`+`replace` or just `replace`) across all examples for consistent path manipulation.

## Individual Comments

### Comment 1
<location> `examples/photo_album.yml:4` </location>
<code_context>
+netsuke_version: "1.0"
+
+vars:
+  style: "{{ env('DT_STYLE') | default('natural') }}"
+  outdir: build/jpg
+
</code_context>

<issue_to_address>
Potential for inconsistent output if DT_STYLE changes between builds.

Incorporate the style value into the output path or dependency graph to ensure images are rebuilt when DT_STYLE changes.
</issue_to_address>

### Comment 2
<location> `examples/photo_album.yml:13` </location>
<code_context>
+    description: Develop RAW image
+
+  - name: thumb
+    command: "convert {ins} -resize 200x200 {outs}"
+    description: Create thumbnail
+
</code_context>

<issue_to_address>
Thumbnail resizing may not preserve aspect ratio.

Using '-resize 200x200' may stretch non-square images. To maintain aspect ratio, use '200x200^' or add '-gravity center -extent 200x200'.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
  - name: thumb
    command: "convert {ins} -resize 200x200 {outs}"
    description: Create thumbnail
=======
  - name: thumb
    command: "convert {ins} -resize 200x200^ -gravity center -extent 200x200 {outs}"
    description: Create thumbnail
>>>>>>> REPLACE

</suggested_fix>

### Comment 3
<location> `examples/python_package.yml:8` </location>
<code_context>
+
+rules:
+  - name: install
+    command: "{{ python }} -m pip install -e ."
+    description: Install package
+  - name: test
</code_context>

<issue_to_address>
No isolation of Python environment for install rule.

Consider running the install step within a virtual environment to prevent conflicts with the global Python environment.
</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 examples/photo_album.yml
Comment thread examples/photo_album.yml
Comment thread examples/python_package.yml Outdated
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: 8

♻️ Duplicate comments (2)
examples/photo_album.yml (1)

17-24: Same YAML-lint issue as in c_app.yml

Wrap the Jinja % for blocks in a literal scalar to silence CI linting while keeping the template logic.

examples/svg_to_png.yml (1)

12-16: YAML-lint complains about raw Jinja

As with the other templates, shield the % for block behind a scalar to keep the file YAML-valid during static analysis.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 76df052 and 5e773cc.

📒 Files selected for processing (5)
  • examples/book.yml (1 hunks)
  • examples/c_app.yml (1 hunks)
  • examples/photo_album.yml (1 hunks)
  • examples/python_package.yml (1 hunks)
  • examples/svg_to_png.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
examples/c_app.yml

[error] 18-18: syntax error: found character '%' that cannot start any token

(syntax)

examples/photo_album.yml

[error] 17-17: syntax error: found character '%' that cannot start any token

(syntax)

examples/svg_to_png.yml

[error] 12-12: syntax error: found character '%' that cannot start any token

(syntax)

Comment thread examples/python_package.yml
Comment thread examples/python_package.yml Outdated
Comment thread examples/python_package.yml Outdated
Comment thread examples/c_app.yml Outdated
Comment thread examples/c_app.yml
Comment thread examples/photo_album.yml Outdated
Comment thread examples/svg_to_png.yml Outdated
Comment thread examples/book.yml Outdated
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jul 12, 2025

@sourcery-ai resolve

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jul 12, 2025

@sourcery-ai review

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 they look great!

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

### Comment 1
<location> `examples/book.yml:14` </location>
<code_context>
+targets:
+  - name: "{{ outdir }}/manuscript.pdf"
+    rule: build
+    sources: "{{ glob('chapters/*.md') }}"
+
+defaults:
</code_context>

<issue_to_address>
Quoting the glob result may cause YAML to treat it as a string, not a list.

Remove the quotes around the glob expression to ensure YAML interprets it as a list, not a string.
</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 examples/book.yml
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: 4

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5e773cc and 1b9ea76.

📒 Files selected for processing (5)
  • examples/book.yml (1 hunks)
  • examples/c_app.yml (1 hunks)
  • examples/photo_album.yml (1 hunks)
  • examples/python_package.yml (1 hunks)
  • examples/svg_to_png.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
examples/photo_album.yml

[error] 17-17: syntax error: found character '%' that cannot start any token

(syntax)

examples/svg_to_png.yml

[error] 12-12: syntax error: found character '%' that cannot start any token

(syntax)

🔇 Additional comments (2)
examples/c_app.yml (1)

10-14: Link flags now match compile flags – good work
{{ cflags }} is propagated to the link rule, ensuring diagnostics and optimisation consistency across the entire build.

examples/photo_album.yml (1)

16-29: Fix YAML syntax error – Jinja control lines must sit inside a string
Raw {% ... %} lines at 17-24 and 27-29 break YAML parsing (yaml-lint error). Wrap the block with a multi-line string so the file stays valid before Jinja renders.

-targets:
-{% for raw in glob('photos/*.nef') %}
+targets: |
+  {% for raw in glob('photos/*.nef') %}
   - name: "{{ outdir }}/{{ raw | basename | replace('.nef', '.jpg') }}"
     rule: develop
     sources: "{{ raw }}"
   - name: "{{ outdir }}/thumbs/{{ raw | basename | replace('.nef', '.jpg') }}"
     rule: thumb
     sources: "{{ outdir }}/{{ raw | basename | replace('.nef', '.jpg') }}"
-{% endfor %}
+  {% endfor %}

-defaults:
-{% for raw in glob('photos/*.nef') %}
-  - "{{ outdir }}/thumbs/{{ raw | basename | replace('.nef', '.jpg') }}"
-{% endfor %}
+defaults: |
+  {% for raw in glob('photos/*.nef') %}
+  - "{{ outdir }}/thumbs/{{ raw | basename | replace('.nef', '.jpg') }}"
+  {% endfor %}

Likely an incorrect or invalid review comment.

Comment thread examples/c_app.yml
Comment on lines +18 to +24
targets: |
{% for src in glob('src/*.c') %}
- name: "{{ objdir }}/{{ src | basename | replace('.c', '.o') }}"
rule: compile
sources: "{{ src }}"
{% endfor %}
- name: app
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify that Netsuke re-parses the templated target list
Wrapping the Jinja loop inside a literal block (|) removes YAML-lint errors, but it also turns targets into a scalar string. Netsuke must post-process that string into real YAML; otherwise the build graph will be empty.

Run:

Ensure the runtime Jinja pass writes a second-stage YAML that Netsuke loads.


🏁 Script executed:

#!/bin/bash
# Expect: 'targets' key in the rendered YAML is an array, not a string.
grep -nA2 -B2 '^targets:' examples/c_app.yml

Length of output: 218


Run a Jinja render simulation to verify the targets type:


🏁 Script executed:

#!/bin/bash
set -e
pip install jinja2 pyyaml
python3 - << 'EOF'
import jinja2, yaml, glob
env = jinja2.Environment()
template = open('examples/c_app.yml').read()
rendered = env.from_string(template).render(objdir='build', glob=glob)
loaded = yaml.safe_load(rendered)
print(type(loaded['targets']).__name__)
EOF

Length of output: 1103


Register missing Jinja filters and re-run the YAML load simulation:


🏁 Script executed:

#!/bin/bash
set -e
pip install jinja2 pyyaml
python3 - << 'EOF'
import jinja2, yaml, glob, os
env = jinja2.Environment()
env.filters['basename'] = os.path.basename
env.filters['replace'] = lambda s, a, b: s.replace(a, b)
template = open('examples/c_app.yml').read()
rendered = env.from_string(template).render(objdir='build', glob=glob)
loaded = yaml.safe_load(rendered)
print(type(loaded.get('targets')).__name__)
EOF

Length of output: 873


Register glob.glob correctly and re-run the YAML load test:


🏁 Script executed:

#!/bin/bash
set -e
pip install jinja2 pyyaml
python3 - << 'EOF'
import jinja2, yaml, glob, os

# Load template from examples/
env = jinja2.Environment(loader=jinja2.FileSystemLoader('examples'))
env.globals['glob'] = glob.glob
env.filters['basename'] = os.path.basename
env.filters['replace'] = lambda s, a, b: s.replace(a, b)

# Render and parse
template = env.get_template('c_app.yml').render(objdir='build')
data = yaml.safe_load(template)

# Output type of targets
print(type(data.get('targets')).__name__)
EOF

Length of output: 420


Ensure targets renders as a YAML sequence, not a string
The Jinja literal block (|) makes targets a single string (yaml.safe_load yields str). Netsuke must re-parse that block as YAML to build a graph. Remove the scalar indicator so Jinja emits a real sequence:

File: examples/c_app.yml
Lines: 18–24

- targets: |
-  {% for src in glob('src/*.c') %}
-  - name: "{{ objdir }}/{{ src | basename | replace('.c', '.o') }}"
-    rule: compile
-    sources: "{{ src }}"
-  {% endfor %}
-  - name: app
+ targets:
+ {% for src in glob('src/*.c') %}
+   - name: "{{ objdir }}/{{ src | basename | replace('.c', '.o') }}"
+     rule: compile
+     sources: "{{ src }}"
+ {% endfor %}
+   - name: app
  • Drop the | after targets:
  • Unindent the loop so each - is part of the sequence

Run yaml.safe_load on the rendered output to confirm targets is a list, not a string.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
targets: |
{% for src in glob('src/*.c') %}
- name: "{{ objdir }}/{{ src | basename | replace('.c', '.o') }}"
rule: compile
sources: "{{ src }}"
{% endfor %}
- name: app
targets:
{% for src in glob('src/*.c') %}
- name: "{{ objdir }}/{{ src | basename | replace('.c', '.o') }}"
rule: compile
sources: "{{ src }}"
{% endfor %}
- name: app
🤖 Prompt for AI Agents
In examples/c_app.yml around lines 18 to 24, the `targets` key is followed by a
literal block indicator `|` causing the entire block to be parsed as a single
string instead of a YAML sequence. To fix this, remove the `|` after `targets:`
and unindent the Jinja for-loop so that each `-` is aligned as a list item under
`targets`. After making these changes, verify by running `yaml.safe_load` on the
rendered output to ensure `targets` is parsed as a list, not a string.

Comment on lines +9 to +10
command: "{{ python }} -m venv {{ venv }}"
description: Create virtual environment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Upgrade venv tooling during creation
Add --upgrade-deps to python -m venv so the virtual environment ships with the latest pip and setuptools, avoiding old-toolchain surprises.

-    command: "{{ python }} -m venv {{ venv }}"
+    command: "{{ python }} -m venv --upgrade-deps {{ venv }}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
command: "{{ python }} -m venv {{ venv }}"
description: Create virtual environment
command: "{{ python }} -m venv --upgrade-deps {{ venv }}"
description: Create virtual environment
🤖 Prompt for AI Agents
In examples/python_package.yml at lines 9 to 10, the command creating the
virtual environment should include the --upgrade-deps flag to ensure the latest
pip and setuptools are installed. Modify the command to add --upgrade-deps after
python -m venv so the environment uses up-to-date tooling and avoids issues with
outdated packages.

Comment thread examples/svg_to_png.yml
Comment on lines +11 to +21
targets:
{% for svg in glob('assets/svg/*.svg') %}
- name: "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
rule: rasterise
sources: "{{ svg }}"
{% endfor %}

defaults:
{% for svg in glob('assets/svg/*.svg') %}
- "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
{% endfor %}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Wrap Jinja loop to restore YAML validity
{% for svg … %} lines at 12-16 and 19-21 cause the same % token error. Encapsulate the loop in a literal block.

-targets:
-{% for svg in glob('assets/svg/*.svg') %}
+targets: |
+  {% for svg in glob('assets/svg/*.svg') %}
   - name: "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
     rule: rasterise
     sources: "{{ svg }}"
-{% endfor %}
+  {% endfor %}

-defaults:
-{% for svg in glob('assets/svg/*.svg') %}
-  - "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
-{% endfor %}
+defaults: |
+  {% for svg in glob('assets/svg/*.svg') %}
+  - "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
+  {% endfor %}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
targets:
{% for svg in glob('assets/svg/*.svg') %}
- name: "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
rule: rasterise
sources: "{{ svg }}"
{% endfor %}
defaults:
{% for svg in glob('assets/svg/*.svg') %}
- "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
{% endfor %}
targets: |
{% for svg in glob('assets/svg/*.svg') %}
- name: "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
rule: rasterise
sources: "{{ svg }}"
{% endfor %}
defaults: |
{% for svg in glob('assets/svg/*.svg') %}
- "{{ outdir }}/{{ svg | basename | replace('.svg', '.png') }}"
{% endfor %}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 12-12: syntax error: found character '%' that cannot start any token

(syntax)

🤖 Prompt for AI Agents
In examples/svg_to_png.yml around lines 11 to 21, the Jinja for loops are
causing YAML parsing errors due to the unescaped % tokens. To fix this, wrap
each Jinja for loop block inside a YAML literal block (using | or >) to preserve
the Jinja syntax as a literal string and restore YAML validity. This will
prevent the YAML parser from misinterpreting the Jinja syntax.

Comment thread examples/book.yml
Comment on lines +7 to +10
- name: build
command: "mkdir -p $(dirname {outs}) && pandoc {ins} -o {outs}"
description: Compile document

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Expose PDF engine selection
Permit authors to tweak the output engine without editing the rule. Pipe an optional pdf_engine var through to pandoc.

-    command: "mkdir -p $(dirname {outs}) && pandoc {ins} -o {outs}"
+    command: "mkdir -p $(dirname {outs}) && pandoc {ins} -o {outs} {{ pdf_engine | default('') }}"

Add to vars:

  pdf_engine: "--pdf-engine=xelatex"
🤖 Prompt for AI Agents
In examples/book.yml around lines 7 to 10, the pandoc command does not allow
selecting the PDF engine dynamically. Modify the command to include an optional
pdf_engine variable by adding it to the vars section as pdf_engine:
"--pdf-engine=xelatex" and update the command to append {pdf_engine} so authors
can specify the PDF engine without editing the rule directly.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jul 14, 2025

Stale

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