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
9 changes: 8 additions & 1 deletion Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jake"
version = "0.8.0"
version = "0.9.0"
edition = "2024"
license-file = "LICENSE"
readme = "README.md"
Expand All @@ -15,6 +15,7 @@ dotenv = "0.15.0"
serde = "1.0.228"
serde_json = "1.0.149"
toml = { version = "1.0.1", features = ["preserve_order"] }
shlex = "2.0.1"

[dev-dependencies]
serial_test = "3.4.0"
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ It is based on TOML tasks definition (stored in a file called `jakefile.toml`) a
- You can list tasks, by passing the `--list` flag
- You can load `.env` file (in the same working directory or anywhere up in the directory tree), by passing the `--env` flag
- Execute scripts from a `package.json` file with the `--js` flag.
- Execute inline scripts in Python, JavaScript, TypeScript, Ruby, PHP, Lua, and Perl
- Dry-run mode: `jake --dry-run <task>` prints commands without executing them.

## Installation
Expand Down Expand Up @@ -168,6 +169,38 @@ Output:
hello
```

### Inline Scripts

You can also write inline scripts directly in your `jakefile.toml` using the `script` key instead of `command`. The first line of the script must specify the language:

```toml
[python]
script = """py
def sum_ints(x: int, y: int) -> int:
return x+y

print(sum_ints(1,2))
"""

[javascript]
script = """javascript
function main() {
console.log('hello world')
}

main()
"""

[typescript]
script = """ts
console.log('hey there, great to run TS!')
"""
```

Supported language identifiers: `py`/`python`, `js`/`javascript`, `ts`/`typescript`, `rb`/`ruby`, `php`, `lua`, `perl`.

### package.json Scripts

If you are in a JS/TS application using a `package.json` for its scripts, as in this example:

```json
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.8.0",
"version": "0.9.0",
"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.8.0 ${features} ...`);
exec(`cargo install jake --vers 0.8.0 ${features}`, (error, stdout, stderr) => {
console.log(`Installing and compiling jake 0.9.0 ${features} ...`);
exec(`cargo install jake --vers 0.9.0 ${features}`, (error, stdout, stderr) => {
console.log(stdout);
if (error || stderr) {
console.log(error || stderr);
Expand Down
5 changes: 4 additions & 1 deletion reference/contents/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ additional options from the command line.
- **Loading .env files**: `.env` files can be loaded for task execution with the `--env` flag
- **Executing package.json scripts**: in a JS/TS environment, scripts contained in a `package.json`
file can be executed by passing the `--js` flag
- **Inline scripts**: write scripts in Python, JavaScript, TypeScript, Ruby, PHP, Lua, and Perl
directly in `jakefile.toml` using the `script` key
- **Dry-run**: `--dry-run` prints the commands that would be run without executing them

### Comparison
Expand All @@ -42,8 +44,9 @@ The table below compares `jake` against [`just`](https://github.com/casey/just)
| No special spacing rules | ✅ | ✅ | ❌ |
| Read .env | ✅ | ✅ | ❌ |
| List available commands | ✅ | ✅ | ❌ |
| Recipes written in arbitrary languages | | ✅ | ❌ |
| Recipes written in arbitrary languages | | ✅ | ❌ |
| Initialize a boilerplate jake/just/makefile | ✅ | ❌ | ❌ |
| Execute inline scripts in `jakefile.toml` | ✅ | ❌ | ❌ |
| Execute scripts in `package.json` | ✅ | ❌ | ❌ |
| Dry-run (print commands only) | ✅ | ✅ | ✅ |

Expand Down
44 changes: 43 additions & 1 deletion reference/contents/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,49 @@ Task name Command to execute Array of tasks to be executed before
the task itself
```

`command` is required when using the object syntax. `depends_on` is optional: if omitted, the task runs with no prerequisites.
`command` is required when using the object syntax, unless you use `script` instead (see below). `depends_on` is optional: if omitted, the task runs with no prerequisites.

### Inline Scripts

Instead of `command`, you can use `script` to write code directly in `jakefile.toml`. The first line of the script must be the language identifier, followed by the code:

```toml
[python]
script = """py
def sum_ints(x: int, y: int) -> int:
return x + y

print(sum_ints(1, 2))
"""

[javascript]
script = """javascript
function main() {
console.log('hello world')
}

main()
"""

[typescript]
script = """ts
console.log('hey there, great to run TS!')
"""
```

Supported language identifiers:

| Language | Identifiers |
| ------------ | ----------------- |
| Python | `py`, `python` |
| JavaScript | `js`, `javascript`|
| TypeScript | `ts`, `typescript`|
| Ruby | `rb`, `ruby` |
| PHP | `php` |
| Lua | `lua` |
| Perl | `perl` |

Scripts are executed by invoking the appropriate interpreter (e.g. `python3 -c`, `node -e`, `npx tsx -e`).

### The Default Task

Expand Down
59 changes: 59 additions & 0 deletions src/code_blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::{fmt::Display, str::FromStr};

#[derive(Debug, Clone, Copy)]
pub enum ScriptLanguage {
Javascript,
Typescript,
Python,
Ruby,
Php,
Lua,
Perl,
}

#[derive(Debug)]
pub struct LanguageNotSupportedError {
message: String,
}

impl std::error::Error for LanguageNotSupportedError {}

impl Display for LanguageNotSupportedError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}

impl FromStr for ScriptLanguage {
type Err = LanguageNotSupportedError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"py" | "python" => Ok(Self::Python),
"ts" | "typescript" => Ok(Self::Typescript),
"js" | "javascript" => Ok(Self::Javascript),
"rb" | "ruby" => Ok(Self::Ruby),
"lua" => Ok(Self::Lua),
"perl" => Ok(Self::Perl),
"php" => Ok(Self::Php),
_ => Err(LanguageNotSupportedError {
message: format!("{} is not a supported language for jake scripts", s),
}),
}
}
}

impl ScriptLanguage {
pub fn command(&self, script: &str) -> anyhow::Result<String> {
let quoted_script = shlex::try_quote(script)?;
match self {
Self::Javascript => Ok(format!("node -e {}", quoted_script)),
Self::Lua => Ok(format!("lua -e {}", quoted_script)),
Self::Python => Ok(format!("python3 -c {}", quoted_script)),
Self::Perl => Ok(format!("perl -e {}", quoted_script)),
Self::Php => Ok(format!("php -r {}", quoted_script)),
Self::Ruby => Ok(format!("ruby -e {}", quoted_script)),
Self::Typescript => Ok(format!("npx tsx -e {}", quoted_script)),
}
}
}
Loading
Loading