Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions e2e/tasks/test_task_validate
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,52 @@ assert_contains "mise tasks validate multiple-alias 2>&1 || true" "Cannot define
# Clean up
rm -rf mise-tasks

# Test monorepo config_root dependency validation matches runtime resolution
rm -f mise.toml
mkdir -p monorepo-validate/pkg
cat <<'EOF' >monorepo-validate/mise.toml
experimental_monorepo_root = true

[settings]
experimental = true

[monorepo]
config_roots = ["pkg"]
EOF

cat <<'EOF' >monorepo-validate/pkg/mise.toml
[tasks._dep]
hide = true
alias = "dep-alias"
usage = 'arg "<name>"'
run = 'echo "arg=$usage_name"'

[tasks.w_bare]
depends = ["_dep bare"]

[tasks.w_colon]
depends = [":_dep colon"]

[tasks.w_full]
depends = ["//pkg:_dep full"]

[tasks.w_alias]
depends = ["dep-alias alias"]
EOF

(
cd monorepo-validate/pkg
assert_contains "mise tasks validate" "✓ All 5 task(s) validated successfully"
)

assert_contains "mise -C monorepo-validate run //pkg:w_bare" "arg=bare"
assert_contains "mise -C monorepo-validate run //pkg:w_colon" "arg=colon"
assert_contains "mise -C monorepo-validate run //pkg:w_full" "arg=full"
assert_contains "mise -C monorepo-validate run //pkg:w_alias" "arg=alias"

# Clean up
rm -rf monorepo-validate

# Test that run.tasks entries with inline arguments are accepted
Comment thread
greptile-apps[bot] marked this conversation as resolved.
mkdir -p mise-tasks
cat <<'SCRIPT' >mise-tasks/test
Expand Down
24 changes: 13 additions & 11 deletions src/cli/tasks/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::sync::Arc;
use crate::config::Config;
use crate::duration;
use crate::file;
use crate::task::Task;
use crate::task::task_fetcher::TaskFetcher;
use crate::task::{GetMatchingExt, Task, build_task_ref_map, resolve_task_pattern};
use crate::tera::contains_template_syntax;
use crate::ui::style;
use console::style as console_style;
Expand Down Expand Up @@ -226,13 +226,15 @@ impl TasksValidate {
issues
}

/// Check if a task exists by name, display_name, or alias
fn task_exists(all_tasks: &BTreeMap<String, Task>, task_name: &str) -> bool {
all_tasks.contains_key(task_name)
|| all_tasks.values().any(|t| t.display_name == task_name)
|| all_tasks
.values()
.any(|t| t.aliases.contains(&task_name.to_string()))
/// Check if a task exists by name, display_name, or alias.
/// Monorepo-relative references are resolved the same way runtime task matching resolves them.
fn task_exists(all_tasks: &BTreeMap<String, Task>, task_name: &str, parent: &Task) -> bool {
let resolved_name = resolve_task_pattern(task_name, Some(parent));
let task_refs = build_task_ref_map(all_tasks.iter());
task_refs
.get_matching(&resolved_name)
.is_ok_and(|matches| !matches.is_empty())
|| all_tasks.values().any(|t| t.display_name == resolved_name)
}

fn validate_missing_references(
Expand All @@ -257,7 +259,7 @@ impl TasksValidate {
}

// Check if task exists
if !Self::task_exists(all_tasks, dep_name) {
if !Self::task_exists(all_tasks, dep_name, task) {
issues.push(ValidationIssue {
task: task.name.clone(),
severity: Severity::Error,
Expand Down Expand Up @@ -561,7 +563,7 @@ impl TasksValidate {
} => {
// Strip inline arguments before checking existence, matching runtime behavior
let (name, _) = crate::task::task_list::split_task_spec(task_name);
if !Self::task_exists(all_tasks, name) {
if !Self::task_exists(all_tasks, name, task) {
issues.push(ValidationIssue {
task: task.name.clone(),
severity: Severity::Error,
Expand All @@ -575,7 +577,7 @@ impl TasksValidate {
// Strip inline arguments before checking existence, matching runtime behavior
for task_name in tasks {
let (name, _) = crate::task::task_list::split_task_spec(task_name);
if !Self::task_exists(all_tasks, name) {
if !Self::task_exists(all_tasks, name, task) {
issues.push(ValidationIssue {
task: task.name.clone(),
severity: Severity::Error,
Expand Down
Loading