Skip to content

feat(task): skip dependencies with empty templated names - #11057

Merged
jdx merged 2 commits into
jdx:mainfrom
risu729:codex-20260717-012910-764871
Jul 16, 2026
Merged

jdx merged 2 commits into
jdx:mainfrom
risu729:codex-20260717-012910-764871

Conversation

@risu729

@risu729 risu729 commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • skip depends, depends_post, and wait_for entries when a templated task name renders empty or whitespace-only
  • apply the behavior during both initial rendering and deferred usage.* rendering
  • preserve the existing error for literal empty task names

Root cause

TaskDep::render rendered dependency task names in place, but callers always retained the dependency. A conditional name that rendered to an empty string therefore reached task matching and failed with task not found:.

The renderer now reports whether the dependency should be retained, and the shared list helper filters only names that contained template syntax and rendered empty. Literal empty names remain in the list and continue through the existing validation path.

Real-world example

Biwa previously needed a hidden no-op task to make schema generation conditional in CI:

["util:noop"]
run = ":"
hide = true

["schema:tombi"]
depends = [
  "{% if env.CI is defined %}util:noop{% else %}render:schema{% endif %}",
]

With this change, the dependency itself can be omitted:

["schema:tombi"]
depends = [
  "{% if env.CI is defined %}{% else %}render:schema{% endif %}",
]

When CI is defined, the rendered task name is empty and skipped. Outside CI, render:schema still runs first. risu729/biwa#868 removes the workaround using this behavior.

User impact

Tasks can use Tera conditions to make complete dependency entries optional, matching the conditional structured-argument behavior added in #11055.

Validation

  • mise run format
  • cargo test task_dep::tests
  • mise run test:e2e test_task_dep_args

Summary by CodeRabbit

  • Bug Fixes
    • Dependency entries in depends, depends_post, and wait_for that resolve to an empty task name from templates are now omitted.
    • Usage-conditional dependency templates are now evaluated according to the selected mode.
    • A literal empty dependency name is still treated as invalid and fails with a clear “task not found” message.
  • Tests
    • Added end-to-end coverage for optional/usage-gated empty templated dependencies and wait_for execution order.
    • Expanded unit tests for templated TaskDep rendering, including empty/whitespace-only behavior.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Dependency rendering now omits templated task names that render empty, defers usage-dependent templates until usage values exist, and preserves literal empty names as invalid. Unit and end-to-end tests cover both behaviors.

Changes

Dependency rendering behavior

Layer / File(s) Summary
TaskDep render result contract
src/task/task_dep.rs
TaskDep::render returns whether the dependency remains valid, skipping templated task names rendered empty while retaining literal empty names as invalid.
Task dependency orchestration
src/task/mod.rs, e2e/tasks/test_task_dep_args
Initial and usage-time dependency rendering share a helper that defers usage templates and removes empty rendered entries; end-to-end tests cover optional and invalid dependency scenarios.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • jdx/mise#10817: Updates TaskDep::render integration in the same dependency-rendering code.
  • jdx/mise#10963: Changes usage-derived inputs that drive usage-dependent dependency rendering.
  • jdx/mise#11055: Handles empty Tera-templated dependency content in related rendering logic.

Suggested reviewers: jdx

Poem

A rabbit hops through templated fare,
Empty deps vanish into air.
Usage waits, then joins the run,
Literal blanks trip alarms begun.
Clean task paths by moonlight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: skipping task dependencies whose templated names render empty.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds filtering of dependency entries (depends, depends_post, wait_for) whose task name template renders to an empty or whitespace-only string, while preserving the existing error for literal empty names. The change covers both the initial render pass and the deferred usage-value render pass.

  • TaskDep::render now returns Result<bool> instead of Result<&mut Self>; it short-circuits with Ok(false) when a templated task renders empty, leaving literal empty strings to proceed to the existing "task not found" validation path.
  • A new shared render_task_deps helper replaces six nearly-identical loops in mod.rs, using std::mem::take to filter the dep list in-place; the defer_usage flag preserves the two-phase rendering contract (initial + usage-value re-render from raw).
  • Unit and e2e tests are thorough: whitespace-only, true/false conditions, all three dep list types, wait_for ordering, and the literal-empty error case are all covered.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to filtering empty-rendering templated deps and does not alter any task execution or scheduling logic beyond what is explicitly tested.

The two-phase rendering contract (initial non-usage pass → deferred usage-value pass from raw) is preserved correctly. Literal empty names still flow through to the existing 'task not found' validation. The std::mem::take refactor eliminates all six former loops without changing observable behavior for non-empty deps. Unit tests cover all four branching outcomes of render(), and the e2e test exercises depends, depends_post, wait_for, ordering, and the error path.

No files require special attention.

Important Files Changed

Filename Overview
src/task/task_dep.rs Changes render() return type from Result<&mut Self> to Result and adds early-return false when a templated task name trims to empty; four new unit tests cover the empty/whitespace/non-empty/literal-empty cases cleanly.
src/task/mod.rs Extracts six identical rendering loops into render_task_deps, which uses std::mem::take + bool return from dep.render() to filter empty-rendering deps while correctly deferring usage-ref deps for the second rendering phase.
e2e/tasks/test_task_dep_args Adds e2e tests covering the empty-template skip for all three dep lists (depends/depends_post/wait_for) across both rendering phases, and confirms literal empty names still fail with 'task not found'.

Reviews (6): Last reviewed commit: "fix(task): satisfy clippy in dependency ..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

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 comments (1)
src/task/task_dep.rs (1)

23-29: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider trimming the rendered task string before checking if it's empty.

If a templated task includes accidental whitespace (e.g., " {% if usage.enabled %}dependency{% endif %} "), it will evaluate to a string containing only spaces when the condition evaluates to false. Checking self.task.trim().is_empty() ensures these are still properly skipped instead of causing a task not found: error down the line.

♻️ Proposed fix
     ) -> crate::Result<bool> {
         let task_is_templated = contains_template_syntax(&self.task);
         if task_is_templated {
             self.task = render_str(tera, &self.task, tera_ctx)?;
-            if self.task.is_empty() {
+            if self.task.trim().is_empty() {
                 return Ok(false);
             }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/task/task_dep.rs` around lines 23 - 29, Update the rendered-task
emptiness check in the templated-task branch of the task dependency method to
use trimmed content, so whitespace-only results return Ok(false) and do not
proceed to task lookup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/task/task_dep.rs`:
- Around line 23-29: Update the rendered-task emptiness check in the
templated-task branch of the task dependency method to use trimmed content, so
whitespace-only results return Ok(false) and do not proceed to task lookup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8037ccb6-850a-4bed-bdbd-402ff3b0b8fe

📥 Commits

Reviewing files that changed from the base of the PR and between e4178d6 and d331957.

📒 Files selected for processing (3)
  • e2e/tasks/test_task_dep_args
  • src/task/mod.rs
  • src/task/task_dep.rs

@risu729
risu729 force-pushed the codex-20260717-012910-764871 branch from d331957 to e9d3541 Compare July 16, 2026 15:48
@risu729 risu729 changed the title fix(task): skip dependencies with empty templated names feat(task): skip dependencies with empty templated names Jul 16, 2026
@risu729
risu729 force-pushed the codex-20260717-012910-764871 branch from e9d3541 to c59f54b Compare July 16, 2026 15:53
@risu729
risu729 force-pushed the codex-20260717-012910-764871 branch from c59f54b to 59cd0b6 Compare July 16, 2026 16:26
@risu729
risu729 force-pushed the codex-20260717-012910-764871 branch from 59cd0b6 to 30246f4 Compare July 16, 2026 16:37
@risu729

risu729 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 3 minutes.

@risu729

risu729 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@risu729
risu729 marked this pull request as ready for review July 16, 2026 19:36
@jdx
jdx enabled auto-merge (squash) July 16, 2026 19:49
@jdx
jdx merged commit f78653f into jdx:main Jul 16, 2026
33 checks passed
@risu729
risu729 deleted the codex-20260717-012910-764871 branch July 16, 2026 19:53
This was referenced Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants