Skip to content

Commit

Permalink
fix: improve task loading (#2664)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Sep 27, 2024
1 parent e91bab4 commit 2281145
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 25 deletions.
1 change: 1 addition & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jq = "latest"
"npm:prettier" = "3"
direnv = "latest"
actionlint = "latest"
ripgrep = "latest"
"pipx:toml-sort" = "latest"
#python = { version = "latest", virtualenv = "{{env.HOME}}/.cache/venv" }
#ruby = "3.1"
Expand Down
10 changes: 10 additions & 0 deletions .mise/tasks/lint/ripgrep
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail

found=0
rg "dbg!" src && found=1

if [[ $found == 1 ]]; then
echo "dbg! macro found"
exit 1
fi
4 changes: 4 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ version files since they're version files not specific to asdf/mise and can be u

See [Settings](/settings) for the full list of settings.

## Tasks

See [Tasks](/tasks/) for the full list of configuration options.

## Environment variables

mise can also be configured via environment variables. The following options are available:
Expand Down
2 changes: 1 addition & 1 deletion docs/tasks/file-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ test:integration .../.mise/tasks/test/integration
test:units .../.mise/tasks/test/units
```

### Argument parsing with usage
## Argument parsing with usage

[usage](https://usage.jdx.dev) spec can be used within these files to provide argument parsing, autocompletion,
documentation when running mise and can be exported to markdown. Essentially this turns tasks into
Expand Down
32 changes: 29 additions & 3 deletions docs/tasks/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Tasks <Badge type="warning" text="experimental" />

You can define tasks in `.mise.toml` files or as standalone shell scripts. These are useful for things like
You can define tasks in `mise.toml` files or as standalone shell scripts. These are useful for things like
running linters, tests, builders, servers, and other tasks that are specific to a project. Of course,
tasks launched with mise will include the mise environment—your tools and env vars defined in `.mise.toml`.
tasks launched with mise will include the mise environment—your tools and env vars defined in `mise.toml`.

Here's my favorite features about mise's task runner:

Expand All @@ -19,4 +19,30 @@ Please give feedback early since while it's experimental it's much easier to cha

## Task Environment Variables

- `root` - the root of the project, defaults to the directory of the `.mise.toml` file
- `root` - the root of the project, defaults to the directory of the `mise.toml` file

## Task Configuration

You can configure how tasks are used in mise with the `[task_config]` section of `mise.toml`:

```toml
[task_config]

# add toml files containing toml tasks, or file tasks to include when looking for tasks
includes = [
"tasks.toml", # a task toml file
"mytasks" # a directory containing file tasks
]
```

If using a toml file for tasks, the file should be the same format as the `[tasks]` section of `mise.toml`
but without the `[task]` prefix:

```toml
task1 = "echo task1"
task2 = "echo task2"
task3 = "echo task3"

[task4]
run = "echo task4"
```
7 changes: 6 additions & 1 deletion docs/tasks/toml-tasks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TOML-based Tasks

Tasks can also be defined in `.mise.toml` files in different ways. This is a more "traditional" method of defining tasks:
Tasks can be defined in `mise.toml` files in different ways:

```toml
[tasks.cleancache]
Expand Down Expand Up @@ -64,6 +64,11 @@ run = [
```

Then running `mise run test foo bar` will pass `foo bar` to `cargo test`. `mise run test --e2e-args baz` will pass `baz` to `./scripts/test-e2e.sh`.
If any arguments are defined with templates then mise will not pass the arguments to the last script in the `run` array.

:::tip
Using templates to define arguments will make them work with completion and help messages.
:::

### Positional Arguments

Expand Down
35 changes: 35 additions & 0 deletions e2e/tasks/test_task_ls
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

cat <<EOF >mise.toml
[task_config]
includes = [
"tasks.toml",
"mytasks",
]
[tasks.lint]
run = 'echo "linting!"'
EOF

cat <<EOF >tasks.toml
[test]
run = 'echo "testing!"'
[test-with-args]
run = 'echo "{{arg()}} {{flag(name="force")}} {{option(name="user")}}"'
EOF

mkdir -p .mise/tasks
cat <<'EOF' >.mise/tasks/do-not-show
#!/usr/bin/env bash
EOF
chmod +x .mise/tasks/do-not-show

mkdir -p mytasks
cat <<'EOF' >mytasks/filetask2
#!/usr/bin/env bash
EOF
chmod +x mytasks/filetask2

assert "mise task ls" "filetask2 ~/workdir/mytasks/filetask2
lint ~/workdir/mise.toml
test ~/workdir/tasks.toml
test-with-args ~/workdir/tasks.toml"
File renamed without changes.
15 changes: 15 additions & 0 deletions schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,21 @@
}
]
},
"task_config": {
"description": "configration for task execution/management",
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"description": "files/directories to include searching for tasks",
"items": {
"description": "file/directory root to include in task execution",
"type": "string"
},
"type": "array"
}
}
},
"tool": {
"oneOf": [
{
Expand Down
15 changes: 15 additions & 0 deletions schema/mise.json.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,21 @@
}
]
},
"task_config": {
"description": "configration for task execution/management",
"type": "object",
"additionalProperties": false,
"properties": {
"includes": {
"description": "files/directories to include searching for tasks",
"items": {
"description": "file/directory root to include in task execution",
"type": "string"
},
"type": "array"
}
}
},
"tool": {
"oneOf": [
{
Expand Down
14 changes: 8 additions & 6 deletions src/cli/tasks/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use tabled::Tabled;
use crate::config::{Config, Settings};
use crate::file::display_path;
use crate::task::Task;
use crate::ui::info::trim_line_end_whitespace;
use crate::ui::{style, table};

/// [experimental] List available tasks to execute
Expand Down Expand Up @@ -91,7 +92,8 @@ impl TasksLs {
if !self.extended {
table::disable_columns(&mut table, vec![1]);
}
miseprintln!("{table}");
let table = format!("{table}");
miseprintln!("{}", trim_line_end_whitespace(&table));
Ok(())
}

Expand Down Expand Up @@ -191,12 +193,12 @@ mod tests {
#[test]
fn test_task_ls() {
reset();
assert_cli_snapshot!("t", "--no-headers", @r###"
configtask ~/config/config.toml
filetask This is a test build script ~/cwd/.mise/tasks/filetask
lint ~/config/config.toml
assert_cli_snapshot!("t", "--no-headers", @r#"
configtask ~/config/config.toml
filetask This is a test build script ~/cwd/.mise/tasks/filetask
lint ~/config/config.toml
test ~/config/config.toml
"###);
"#);
}

#[test]
Expand Down
14 changes: 11 additions & 3 deletions src/cli/toml/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::config::{load_config_paths, DEFAULT_CONFIG_FILENAMES};
use crate::file;
use clap::Subcommand;
use eyre::Result;
use eyre::{bail, Result};
use once_cell::sync::Lazy;
use std::path::PathBuf;

Expand Down Expand Up @@ -47,8 +48,15 @@ impl Commands {

impl Toml {
pub fn run(self) -> Result<()> {
let cmd = self.command.unwrap();
if let Some(cmd) = self.command {
return cmd.run();
}
if let Some(toml_config) = top_toml_config() {
miseprintln!("{}", file::read_to_string(&toml_config)?);
} else {
bail!("No mise.toml file found");
}

cmd.run()
Ok(())
}
}
42 changes: 32 additions & 10 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,40 @@ impl Config {
let includes = configs
.iter()
.find_map(|cf| cf.task_config().includes.clone())
.unwrap_or_else(default_task_includes);
.unwrap_or_else(default_task_includes)
.into_iter()
.map(|p| if p.is_absolute() { p } else { dir.join(p) })
.collect_vec();
let extra_tasks = includes
.iter()
.filter(|p| {
p.is_file() && p.extension().unwrap_or_default().to_string_lossy() == "toml"
})
.map(|p| self.load_task_file(p))
.flatten_ok()
.collect::<Result<Vec<Task>>>()?;
let file_tasks = includes.into_iter().flat_map(|p| {
let p = match p.is_absolute() {
true => p,
false => dir.join(p),
};
self.load_tasks_includes(&p).unwrap_or_else(|err| {
warn!("loading tasks in {}: {err}", display_path(&p));
vec![]
})
});
Ok(file_tasks.into_iter().chain(config_tasks).collect())
Ok(file_tasks
.into_iter()
.chain(config_tasks)
.chain(extra_tasks)
.collect())
}

fn load_task_file(&self, path: &Path) -> Result<Vec<Task>> {
let raw = file::read_to_string(path)?;
let mut tasks = toml::from_str::<HashMap<String, Task>>(&raw)
.map_err(|e| eyre!("Error parsing task file: {} {e}", display_path(path)))?;
for (name, task) in &mut tasks {
task.name = name.clone();
task.config_source = path.to_path_buf();
}
Ok(tasks.into_values().collect())
}

fn load_global_tasks(&self) -> Result<Vec<Task>> {
Expand Down Expand Up @@ -313,14 +335,14 @@ impl Config {
if !root.is_dir() {
return Ok(vec![]);
}
let files: Vec<PathBuf> = WalkDir::new(root)
WalkDir::new(root)
.follow_links(true)
.into_iter()
.filter_entry(|e| !e.file_name().to_string_lossy().starts_with('.'))
// skip hidden directories (if the root is hidden that's ok)
.filter_entry(|e| e.path() == root || !e.file_name().to_string_lossy().starts_with('.'))
.filter_ok(|e| e.file_type().is_file())
.map_ok(|e| e.path().to_path_buf())
.try_collect()?;
files
.try_collect::<_, Vec<PathBuf>, _>()?
.into_par_iter()
.filter(|p| file::is_executable(p))
.map(|path| Task::from_path(&path))
Expand Down
2 changes: 1 addition & 1 deletion src/ui/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ pub fn indent_by<S: Display>(s: S, ind: &'static str) -> String {
out
}

fn trim_line_end_whitespace(s: &str) -> String {
pub fn trim_line_end_whitespace(s: &str) -> String {
s.lines().map(str::trim_end).collect::<Vec<_>>().join("\n")
}
1 change: 1 addition & 0 deletions tasks

0 comments on commit 2281145

Please sign in to comment.