Skip to content

fix(task): honor task_config.includes order so a local task can override a git::include#10191

Merged
jdx merged 1 commit into
jdx:mainfrom
vmaleze:fix/task-include-precedence-9147
Jun 2, 2026
Merged

fix(task): honor task_config.includes order so a local task can override a git::include#10191
jdx merged 1 commit into
jdx:mainfrom
vmaleze:fix/task-include-precedence-9147

Conversation

@vmaleze

@vmaleze vmaleze commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

PR #9147 introduced an early last-wins dedup in merge_file_and_config_tasks and, combined with load_tasks_in_dir loading all non-git includes before all git:: includes, made a git:: include always clobber a same-named local task regardless of its position in task_config.includes.

Load includes in their declared order via a single ordered pass (mirroring load_file_tasks) and keep the file-task dedup first-wins, so the earlier include in the list takes precedence uniformly for directory, toml-file, and git:: includes. The TOML [tasks.*] overlay behavior from #9147 is unchanged.

Document the include precedence and add an e2e test covering local-first, git-first, and two same-named local includes.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed task include precedence: when multiple includes define the same task name, the last include listed wins.
  • Documentation

    • Updated docs to clarify include evaluation order and show how to override git-hosted tasks by listing local includes after them.
  • Tests

    • Added an end-to-end test verifying include-order precedence across local and git-hosted includes.

@vmaleze vmaleze changed the title fix(task): honor task_config.includes order so a local task can override a git:: include fix(task): honor task_config.includes order so a local task can override a git::include Jun 1, 2026
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 772679c1-6144-4919-a815-7f72582d2f72

📥 Commits

Reviewing files that changed from the base of the PR and between bcbebfe and 472866a.

📒 Files selected for processing (3)
  • docs/tasks/task-configuration.md
  • e2e/tasks/test_task_local_overrides_git_include
  • src/config/mod.rs

📝 Walkthrough

Walkthrough

This PR changes task include precedence so when multiple includes define the same task name, the last matching include in task_config.includes wins. It refactors include resolution to derive a single includes/resolve_dir and resolve git:: entries inline, adds an E2E test validating ordering across scenarios, and updates the docs with the new precedence rule and example.

Changes

Task Include Precedence

Layer / File(s) Summary
Include resolution and merge behavior
src/config/mod.rs
Derives a single (includes, resolve_dir) from the highest-precedence config, iterates includes in order resolving git:: entries to local paths inline and expanding other patterns relative to resolve_dir, loads and appends file tasks while marking include-derived tasks as global when applicable, and documents that later includes override earlier ones (last-wins).
E2E regression test for include precedence
e2e/tasks/test_task_local_overrides_git_include
Adds a Bash E2E test that starts a temporary Git HTTP backend, creates a local .mise/tasks/ripgrep and other task fixtures, runs three mise.toml scenarios, and asserts that the task defined by the last include wins across git and local includes and between local includes.
Task include precedence documentation
docs/tasks/task-configuration.md
Updates wording to state task_config.includes are evaluated in order and that the last include that defines a task name takes precedence; adds a TOML example showing overriding a git::-provided task by listing a local include after the git:: include.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop through includes in tidy rows,
If two define a task, the last one shows.
Git, local, or toml — the final call wins,
I nap on the merge while the CI grins. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main fix: honoring task_config.includes order to allow local tasks to override git::includes, which aligns with the primary objective of the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@greptile-apps

greptile-apps Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the task-include precedence bug introduced in #9147: previously, git:: includes were always loaded after all local includes, meaning a git-hosted task could silently override a same-named local task regardless of where the local include appeared in task_config.includes. The fix collapses the two separate loading passes in load_tasks_in_dir into a single ordered loop — git URLs and filesystem paths are now resolved inline in declared order, and IndexMap insert (last-wins) makes the final include in the list take precedence uniformly.

  • src/config/mod.rs: Replaces the old two-pass approach (all local paths first, then all git:: paths) with a single in-order pass; task_includes_for_dir (used by diagnostics and tab-completion) is left unchanged and still skips git URLs.
  • e2e/tasks/test_task_local_overrides_git_include: Adds a regression test exercising local-last, git-last, and two-local-include scenarios via a loopback git HTTP server.
  • docs/tasks/task-configuration.md: Documents the last-entry-wins precedence rule with a TOML example.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to the include-loading loop in load_tasks_in_dir and validated by three concrete e2e scenarios.

The core Rust change is a clean refactor with no new state, no unsafe code, and no changes to the public API. The merge_file_and_config_tasks logic is untouched. The only callers of task_includes_for_dir not touched by this PR use it solely for diagnostics, so their continued exclusion of git:: URLs is harmless.

No files require special attention; the test file's potential slow-run time is the only item worth a second glance before merge.

Important Files Changed

Filename Overview
src/config/mod.rs Refactors load_tasks_in_dir to process includes in declared order (both local dirs and git:: URLs), fixing the precedence bug; merge logic is unchanged (last-wins via IndexMap insert).
e2e/tasks/test_task_local_overrides_git_include New e2e regression test covering local-first, git-first, and two-local-include precedence scenarios; uses a background git HTTP server that may push the test past the 20 s threshold.
docs/tasks/task-configuration.md Adds a paragraph documenting the last-entry-wins include precedence rule; the inline TOML comment uses a continuation style that is slightly ambiguous.

Reviews (2): Last reviewed commit: "fix(task): honor task_config.includes or..." | 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.

Actionable comments posted: 1

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

Inline comments:
In `@e2e/tasks/test_task_local_overrides_git_include`:
- Around line 14-53: The script starts the git HTTP server and assigns
SERVER_PID before registering the cleanup trap and assumes $TMPDIR exists; move
the trap registration so it runs immediately after SERVER_PID is set (i.e.,
place trap cleanup EXIT right after SERVER_PID=$!), and change
PORT_FILE/READY_FILE/INFO_FILE initialization to use a TMPDIR fallback (e.g.,
${TMPDIR:-/tmp}) when constructing MISE_GIT_HTTP_* file paths so the files and
cleanup work even if TMPDIR is unset; keep the existing cleanup() and
wait_for_server() logic unchanged but ensure trap is registered before calling
wait_for_server.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d7c7b626-7412-4cba-93a9-cd5dd1b26c76

📥 Commits

Reviewing files that changed from the base of the PR and between 310e325 and bcbebfe.

📒 Files selected for processing (3)
  • docs/tasks/task-configuration.md
  • e2e/tasks/test_task_local_overrides_git_include
  • src/config/mod.rs

Comment thread e2e/tasks/test_task_local_overrides_git_include Outdated
@risu729

risu729 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

I feel last win is more intuitive as other config like tools or env are last win. I'm just curious but are there any reasons for the first win?

@vmaleze

vmaleze commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

I feel last win is more intuitive as other config like tools or env are last win. I'm just curious but are there any reasons for the first win?

There is no real reason for first to win. I just wanted to fix the issue that was introduced were remote tasks would always take precedence over local ones. I will update the PR to have last define wins :)

@risu729

risu729 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

I see, thanks!

…des an earlier one

PR jdx#9147 introduced an early dedup in merge_file_and_config_tasks and, combined
with load_tasks_in_dir loading all non-git includes before all git:: includes,
ignored the declared task_config.includes order: a git:: include could no longer
be overridden by a later local include (and vice versa), regardless of list
position.

Load includes in a single ordered pass (mirroring load_file_tasks) and keep the
file-task dedup last-wins, so the later include in the list takes precedence,
uniformly for directory, toml-file, and git:: includes. To override a remote
git:: task with a local one, list the local directory after the git:: entry.
The TOML [tasks.*] overlay behavior from jdx#9147 is unchanged.

Document the include precedence and add an e2e test covering local-last,
git-last, and two same-named local includes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vmaleze vmaleze force-pushed the fix/task-include-precedence-9147 branch from bcbebfe to 472866a Compare June 1, 2026 11:54
@jdx jdx merged commit 9ecd682 into jdx:main Jun 2, 2026
34 checks passed
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.

4 participants