Skip to content

Comments

fix(task): prevent wildcard glob test:* from matching parent task test#8165

Merged
jdx merged 2 commits intomainfrom
fix/task-glob-self-match
Feb 16, 2026
Merged

fix(task): prevent wildcard glob test:* from matching parent task test#8165
jdx merged 2 commits intomainfrom
fix/task-glob-self-match

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Feb 15, 2026

Summary

  • When a task named test has run = [{ task = "test:*" }], the * wildcard incorrectly matched the task itself (because * matched the empty string for the task part after splitting on :), causing a circular dependency error
  • Fixed get_matching() to require that task:* patterns only match tasks that actually have a colon-separated suffix (e.g. test:foo, test:bar), not the parent task test
  • Added unit test and e2e test

Fixes #8138

Test plan

  • Unit test test_get_matching_wildcard_does_not_match_parent verifies the pattern matching logic
  • E2e test test_task_wildcard_no_self_match verifies the full flow with mise run test

🤖 Generated with Claude Code


Note

Low Risk
Small, targeted change to task-glob matching semantics plus additional tests; low risk aside from potentially impacting edge-case wildcard behavior.

Overview
Fixes GetMatchingExt::get_matching so patterns with an explicit : task glob (e.g. test:*) only match tasks that actually have a colon-separated suffix, preventing the parent task test from being selected and creating circular dependencies.

Adds a focused unit test for the matching behavior and a new e2e task test ensuring mise run test runs test:foo/test:bar without invoking itself.

Written by Cursor Bugbot for commit cfbeeeb. This will update automatically on new commits. Configure here.

Copilot AI review requested due to automatic review settings February 15, 2026 14:41
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jdx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug where wildcard task patterns, such as test:*, would inadvertently match their parent task (test), leading to circular dependencies and execution failures. The core change modifies the task matching logic to ensure that wildcard patterns only apply to tasks with a specific suffix, thereby preventing self-matching and ensuring correct task delegation.

Highlights

  • Prevented circular dependency in task execution: The test:* wildcard pattern no longer incorrectly matches the parent test task, resolving a circular dependency issue.
  • Refined get_matching() logic: The get_matching() function now requires task:* patterns to match tasks with a colon-separated suffix, excluding the parent task itself.
  • Added comprehensive testing: New unit and end-to-end tests were introduced to validate the corrected wildcard matching behavior.
Changelog
  • e2e/tasks/test_task_wildcard_no_self_match
    • Added a new e2e test to confirm that test:* does not match test.
  • src/task/mod.rs
    • Modified get_matching function to prevent * from matching empty key_task or stripped_task when a wildcard is used.
    • Added a unit test test_get_matching_wildcard_does_not_match_parent to verify the new matching logic.
Activity
  • A unit test test_get_matching_wildcard_does_not_match_parent was added to verify the pattern matching logic.
  • An e2e test test_task_wildcard_no_self_match was added to verify the full flow with mise run test.
  • The pull request was generated with Claude Code.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is ON, but a Cloud Agent failed to start.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly fixes a bug where a wildcard task dependency could match its parent task, causing a circular dependency. The fix is straightforward and effective, preventing the wildcard from matching an empty task suffix. The addition of both a unit test and an end-to-end test ensures the fix is well-covered. The changes are solid, and I have one minor suggestion to make the new unit test more concise.

src/task/mod.rs Outdated
Comment on lines 2361 to 2364
assert_eq!(matches.len(), 2);
assert!(matches.contains(&&"test:foo".to_string()));
assert!(matches.contains(&&"test:bar".to_string()));
assert!(!matches.contains(&&"test".to_string()));
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For improved clarity and robustness, you could consolidate these assertions into a single assert_eq! that checks the exact contents and order of the matched tasks. This makes the test more concise and ensures no other unexpected tasks are matched.

Since BTreeMap iterates over keys in sorted order, the order of matches is deterministic.

Suggested change
assert_eq!(matches.len(), 2);
assert!(matches.contains(&&"test:foo".to_string()));
assert!(matches.contains(&&"test:bar".to_string()));
assert!(!matches.contains(&&"test".to_string()));
assert_eq!(
matches,
vec![&"test:bar".to_string(), &"test:foo".to_string()]
);

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where wildcard glob patterns like test:* incorrectly matched parent tasks without suffixes (e.g., test), causing circular dependency errors. The fix ensures that * wildcards only match tasks with actual colon-separated suffixes.

Changes:

  • Modified pattern matching logic to require non-empty task parts when using * wildcards
  • Added unit test to verify the corrected pattern matching behavior
  • Added e2e test to validate the fix in a real-world scenario

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/task/mod.rs Updated wildcard matching logic to prevent self-matches and added unit test
e2e/tasks/test_task_wildcard_no_self_match Added e2e test verifying wildcard patterns don't match parent tasks

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Feb 15, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.13 x -- echo 24.1 ± 0.5 23.3 29.5 1.00
mise x -- echo 24.1 ± 0.5 23.3 29.4 1.00 ± 0.03

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.13 env 23.8 ± 0.8 22.9 31.3 1.01 ± 0.04
mise env 23.6 ± 0.3 23.0 25.4 1.00

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.13 hook-env 24.2 ± 0.5 23.4 26.2 1.00
mise hook-env 24.4 ± 0.4 23.7 26.3 1.01 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.13 ls 22.6 ± 0.7 21.8 31.4 1.00
mise ls 22.9 ± 0.5 22.1 27.2 1.01 ± 0.04

xtasks/test/perf

Command mise-2026.2.13 mise Variance
install (cached) 128ms 127ms +0%
ls (cached) 80ms 79ms +1%
bin-paths (cached) 84ms 83ms +1%
task-ls (cached) 812ms 821ms -1%

jdx and others added 2 commits February 16, 2026 22:33
…test`

When a task named "test" has `run = [{ task = "test:*" }]`, the glob
pattern incorrectly matched the task itself because `*` was matching
an empty string for the task part. This caused a circular dependency
error. Now `test:*` requires the matched task to actually have a
colon-separated suffix (e.g. `test:foo`, `test:bar`).

Fixes #8138

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous fix for test:* matching parent task test broke bare task
name lookups. Track whether the * glob was explicit (test:*) vs
implicit (test) and only require non-empty task suffix for explicit
wildcards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jdx jdx force-pushed the fix/task-glob-self-match branch from 4965f15 to cfbeeeb Compare February 16, 2026 22:33
@jdx jdx merged commit 201be6c into main Feb 16, 2026
35 checks passed
@jdx jdx deleted the fix/task-glob-self-match branch February 16, 2026 23:03
mise-en-dev added a commit that referenced this pull request Feb 17, 2026
### 🚀 Features

- **(task)** stream keep-order output in real-time per task by @jdx in
[#8164](#8164)

### 🐛 Bug Fixes

- **(aqua)** resolve lockfile artifacts for target platform (fix
discussion #7479) by @mackwic in
[#8183](#8183)
- **(exec)** strip shims from PATH to prevent recursive shim execution
by @jdx in [#8189](#8189)
- **(hook-env)** preserve PATH reordering done after activation by @jdx
in [#8190](#8190)
- **(lockfile)** resolve version aliases before lockfile lookup by @jdx
in [#8194](#8194)
- **(registry)** set helm-diff archive bin name to diff by @jean-humann
in [#8173](#8173)
- **(task)** improve source freshness checks with dynamic task dirs by
@rooperuu in [#8169](#8169)
- **(task)** resolve global tasks when running from monorepo root by
@jdx in [#8192](#8192)
- **(task)** prevent wildcard glob `test:*` from matching parent task
`test` by @jdx in [#8165](#8165)
- **(task)** resolve task_config.includes relative to config root by
@jdx in [#8193](#8193)
- **(upgrade)** skip untrusted tracked configs during upgrade by @jdx in
[#8195](#8195)

### 🚜 Refactor

- use enum for npm.pacakge_manager by @risu729 in
[#8180](#8180)

### 📚 Documentation

- **(plugins)** replace node/asdf-nodejs examples with vfox plugins by
@jdx in [#8191](#8191)

### ⚡ Performance

- call npm view only once by @risu729 in
[#8181](#8181)

### New Contributors

- @jean-humann made their first contribution in
[#8173](#8173)
- @mackwic made their first contribution in
[#8183](#8183)
- @rooperuu made their first contribution in
[#8169](#8169)

## 📦 Aqua Registry Updates

#### New Packages (2)

- [`BetterDiscord/cli`](https://github.com/BetterDiscord/cli)
- [`glossia.ai/cli`](https://github.com/glossia.ai/cli)
lucasew pushed a commit to lucasew/CONTRIB-mise that referenced this pull request Feb 18, 2026
…test` (jdx#8165)

## Summary
- When a task named `test` has `run = [{ task = "test:*" }]`, the `*`
wildcard incorrectly matched the task itself (because `*` matched the
empty string for the task part after splitting on `:`), causing a
circular dependency error
- Fixed `get_matching()` to require that `task:*` patterns only match
tasks that actually have a colon-separated suffix (e.g. `test:foo`,
`test:bar`), not the parent task `test`
- Added unit test and e2e test

Fixes jdx#8138

## Test plan
- [x] Unit test `test_get_matching_wildcard_does_not_match_parent`
verifies the pattern matching logic
- [x] E2e test `test_task_wildcard_no_self_match` verifies the full flow
with `mise run test`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, targeted change to task-glob matching semantics plus additional
tests; low risk aside from potentially impacting edge-case wildcard
behavior.
> 
> **Overview**
> Fixes `GetMatchingExt::get_matching` so patterns with an explicit `:`
task glob (e.g. `test:*`) only match tasks that actually have a
colon-separated suffix, preventing the parent task `test` from being
selected and creating circular dependencies.
> 
> Adds a focused unit test for the matching behavior and a new e2e task
test ensuring `mise run test` runs `test:foo`/`test:bar` without
invoking itself.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cfbeeeb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
lucasew pushed a commit to lucasew/CONTRIB-mise that referenced this pull request Feb 18, 2026
### 🚀 Features

- **(task)** stream keep-order output in real-time per task by @jdx in
[jdx#8164](jdx#8164)

### 🐛 Bug Fixes

- **(aqua)** resolve lockfile artifacts for target platform (fix
discussion jdx#7479) by @mackwic in
[jdx#8183](jdx#8183)
- **(exec)** strip shims from PATH to prevent recursive shim execution
by @jdx in [jdx#8189](jdx#8189)
- **(hook-env)** preserve PATH reordering done after activation by @jdx
in [jdx#8190](jdx#8190)
- **(lockfile)** resolve version aliases before lockfile lookup by @jdx
in [jdx#8194](jdx#8194)
- **(registry)** set helm-diff archive bin name to diff by @jean-humann
in [jdx#8173](jdx#8173)
- **(task)** improve source freshness checks with dynamic task dirs by
@rooperuu in [jdx#8169](jdx#8169)
- **(task)** resolve global tasks when running from monorepo root by
@jdx in [jdx#8192](jdx#8192)
- **(task)** prevent wildcard glob `test:*` from matching parent task
`test` by @jdx in [jdx#8165](jdx#8165)
- **(task)** resolve task_config.includes relative to config root by
@jdx in [jdx#8193](jdx#8193)
- **(upgrade)** skip untrusted tracked configs during upgrade by @jdx in
[jdx#8195](jdx#8195)

### 🚜 Refactor

- use enum for npm.pacakge_manager by @risu729 in
[jdx#8180](jdx#8180)

### 📚 Documentation

- **(plugins)** replace node/asdf-nodejs examples with vfox plugins by
@jdx in [jdx#8191](jdx#8191)

### ⚡ Performance

- call npm view only once by @risu729 in
[jdx#8181](jdx#8181)

### New Contributors

- @jean-humann made their first contribution in
[jdx#8173](jdx#8173)
- @mackwic made their first contribution in
[jdx#8183](jdx#8183)
- @rooperuu made their first contribution in
[jdx#8169](jdx#8169)

## 📦 Aqua Registry Updates

#### New Packages (2)

- [`BetterDiscord/cli`](https://github.com/BetterDiscord/cli)
- [`glossia.ai/cli`](https://github.com/glossia.ai/cli)
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.

1 participant