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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jake"
version = "0.10.0"
version = "0.10.1"
edition = "2024"
license-file = "LICENSE"
readme = "README.md"
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,20 @@ echo 'hello back'
echo 'bye'
```

**Suppress command echo**

By default, `jake` prints each command before executing it (to `stderr`). Use `--no-print-command` to suppress this output:

```bash
jake say-hello --no-print-command
```

```text
hello
```

This only affects non-dry runs; `--dry-run` always prints commands.

## In GitHub CI/CD

You can use the [setup-jake](https://github.com/AstraBert/setup-jake) action to set up jake and use it in your GitHub Actions workflows.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cle-does-things/jake",
"version": "0.10.0",
"version": "0.10.1",
"description": "A Make-like task executor for Unix operating systems",
"main": "start.js",
"directories": {
Expand Down
4 changes: 2 additions & 2 deletions pre-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const features = process.env.npm_config_features
? `--features ${process.env.npm_config_features.replace(",", " ")}`
: "";

console.log(`Installing and compiling jake 0.10.0 ${features} ...`);
exec(`cargo install jake --vers 0.10.0 ${features}`, (error, stdout, stderr) => {
console.log(`Installing and compiling jake 0.10.1 ${features} ...`);
exec(`cargo install jake --vers 0.10.1 ${features}`, (error, stdout, stderr) => {
console.log(stdout);
if (error || stderr) {
console.log(error || stderr);
Expand Down
2 changes: 2 additions & 0 deletions reference/contents/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ additional options from the command line.
directly in `jakefile.toml` using the `script` key
- **Custom working directory**: with `--cwd`, you can point `jake` to any directory to use as the working directory for command execution, enabling workspace-wide task running
- **Dry-run**: `--dry-run` prints the commands that would be run without executing them
- **Suppress command echo**: `--no-print-command` hides the command before execution output

### Comparison

Expand All @@ -51,6 +52,7 @@ The table below compares `jake` against [`just`](https://github.com/casey/just)
| Execute scripts in `package.json` | ✅ | ❌ | ❌ |
| Custom working directory (`--cwd`) | ✅ | ❌ | ❌ |
| Dry-run (print commands only) | ✅ | ✅ | ✅ |
| Suppress command echo (`--no-print-command`) | ✅ | ❌ | ❌ |

⚠️ `make` supports passing variables from the command line but not named options in the same
ergonomic way.
14 changes: 14 additions & 0 deletions reference/contents/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ echo 'hello back'
echo 'bye'
```

**Suppress command echo**

By default, `jake` prints each command before executing it (to `stderr`). Use `--no-print-command` to suppress this output:

```bash
jake say-hello --no-print-command
```

```text
hello
```

This only affects non-dry runs; `--dry-run` always prints commands.

**Pass additional options to a task**

You can forward extra flags to the underlying command using `--options`:
Expand Down
82 changes: 71 additions & 11 deletions src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ pub fn execute_command(
flags: &str,
executor: &dyn Executor,
load_env: bool,
print_command: bool,
) -> Result<()> {
if task.is_empty() {
return Ok(());
Expand All @@ -215,9 +216,15 @@ pub fn execute_command(
// the actual command to execute is the last one in the execution order
let cmd = &execution_order[execution_order.len() - 1];
if cmd_options.is_empty() {
if print_command {
eprintln!("\x1b[38;5;247m{}\x1b[0m\n", cmd)
}
executor.execute(cmd, load_env, cwd)?;
} else {
let full_command = cmd.to_owned() + " " + cmd_options.join(" ").as_str();
if print_command {
eprintln!("\x1b[38;5;247m{}\x1b[0m\n", full_command)
}
executor.execute(&full_command, load_env, cwd)?;
}
Ok(())
Expand All @@ -228,16 +235,31 @@ pub fn execute_default_command(
flags: &str,
executor: &dyn Executor,
load_env: bool,
print_command: bool,
) -> Result<()> {
let (available_tasks, _) = parse_jakefile(jakefile_path)?;
if available_tasks.contains_key("default") {
execute_command(jakefile_path, "default", flags, executor, load_env)?;
execute_command(
jakefile_path,
"default",
flags,
executor,
load_env,
print_command,
)?;
} else {
let first_key = available_tasks.keys().next();
match first_key {
None => return Err(anyhow!("could not find any task within jakefile")),
Some(task) => {
execute_command(jakefile_path, task, flags, executor, load_env)?;
execute_command(
jakefile_path,
task,
flags,
executor,
load_env,
print_command,
)?;
}
}
}
Expand Down Expand Up @@ -331,6 +353,7 @@ mod tests {
"-la /hello/something",
&mock_executor,
false,
false,
);
assert!(result.is_ok());
let mock_content =
Expand All @@ -342,13 +365,19 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result_1.is_ok());
let mock_content_1 =
std::fs::read_to_string("test.mock").expect("Should be able to read test.mock");
assert_eq!(mock_content_1.trim(), "ls");
let result_2 =
execute_default_command(Some("testfiles/jakefile.toml"), "", &mock_executor, false);
let result_2 = execute_default_command(
Some("testfiles/jakefile.toml"),
"",
&mock_executor,
false,
false,
);
assert!(result_2.is_ok());
let mock_content_2 =
std::fs::read_to_string("test.mock").expect("Should be able to read test.mock");
Expand All @@ -358,6 +387,7 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result_3.is_ok());
let mock_content_3 =
Expand All @@ -369,6 +399,7 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result_4.is_ok());
let mock_content_4 =
Expand All @@ -386,6 +417,7 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result.is_ok());
let mock_content =
Expand All @@ -397,6 +429,7 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result_1.is_ok());
let mock_content_1 =
Expand All @@ -408,6 +441,7 @@ mod tests {
"",
&mock_executor,
false,
false,
);
assert!(result_2.is_ok());
let mock_content_2 =
Expand All @@ -425,6 +459,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert!(result.is_err_and(|e| e.to_string() == "Script could not be parsed correctly".to_string()))
}
Expand All @@ -433,7 +468,14 @@ mod tests {
#[serial]
fn test_script_execution_unsupported_lang() {
let executor = CommandExecutor::new();
let result = execute_command(Some("testfiles/scripts.toml"), "rust", "", &executor, false);
let result = execute_command(
Some("testfiles/scripts.toml"),
"rust",
"",
&executor,
false,
false,
);
assert!(result.is_err_and(
|e| e.to_string() == "rs is not a supported language for jake scripts".to_string()
))
Expand All @@ -449,6 +491,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert!(result.is_ok());
}
Expand All @@ -463,6 +506,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| {
Expand All @@ -484,6 +528,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| e.to_string()
Expand All @@ -502,6 +547,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(result.is_err_and(
|e| e.to_string() == "`command` or `script` key not available for the requested task: ensure that there are no typos and the TOML syntax is correct before running again".to_string()
Expand All @@ -518,6 +564,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| e.to_string()
Expand All @@ -536,6 +583,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert!(result.is_ok());
}
Expand All @@ -550,6 +598,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert!(result.is_ok());
}
Expand All @@ -558,16 +607,22 @@ mod tests {
#[serial]
fn test_default_command_with_default() {
let executor = CommandExecutor::new();
let result =
execute_default_command(Some("testfiles/withdefault.toml"), "", &executor, false);
let result = execute_default_command(
Some("testfiles/withdefault.toml"),
"",
&executor,
false,
false,
);
assert!(result.is_ok());
}

#[test]
#[serial]
fn test_default_command_first_key() {
let executor = CommandExecutor::new();
let result = execute_default_command(Some("testfiles/jakefile.toml"), "", &executor, false);
let result =
execute_default_command(Some("testfiles/jakefile.toml"), "", &executor, false, false);
assert!(result.is_ok());
}

Expand All @@ -581,6 +636,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| e.to_string()
Expand All @@ -599,6 +655,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| e.to_string()
Expand All @@ -618,6 +675,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(|e| e.to_string()
Expand All @@ -636,6 +694,7 @@ mod tests {
"",
&executor,
false,
false,
);
assert_eq!(
result.is_err_and(
Expand All @@ -655,6 +714,7 @@ mod tests {
"",
&executor,
true,
false,
);
assert!(result.is_ok());
}
Expand Down Expand Up @@ -717,7 +777,7 @@ mod tests {
fn test_dry_run_executor_command() {
let path = Some("testfiles/jakefile.toml");
let executor = DryRunExecutor::new();
let result = execute_command(path, "say-hello", "", &executor, false);
let result = execute_command(path, "say-hello", "", &executor, false, false);
assert!(result.is_ok());
}

Expand All @@ -726,7 +786,7 @@ mod tests {
fn test_dry_run_executor_default_command() {
let path = Some("testfiles/withdefault.toml");
let executor = DryRunExecutor::new();
let result = execute_default_command(path, "", &executor, false);
let result = execute_default_command(path, "", &executor, false, false);
assert!(result.is_ok());
}

Expand All @@ -735,7 +795,7 @@ mod tests {
fn test_fails_on_non_zero_exit_code() {
let path = Some("testfiles/jakefile.toml");
let executor = CommandExecutor::new();
let result = execute_command(path, "fails", "", &executor, false);
let result = execute_command(path, "fails", "", &executor, false, false);
assert!(result.is_err_and(|e| {
e.to_string()
.starts_with("Command exited with a non-zero exit code:")
Expand Down
Loading
Loading