| Crates.io | eashy |
| lib.rs | eashy |
| version | 0.3.1 |
| created_at | 2025-08-17 22:30:46.816343+00 |
| updated_at | 2025-08-20 16:25:00.824053+00 |
| description | No more hassle writing shell functions! Easy subcommands and help documentation |
| homepage | https://github.com/jilchab/eashy |
| repository | https://github.com/jilchab/eashy |
| max_upload_size | |
| id | 1799750 |
| size | 229,544 |
No more hassle writing shell functions! Easy subcommands and help documentation
Eashy is a command-line tool that generates shell functions with subcommands and integrated help documentation from simple KDL configuration files. Say goodbye to manually writing complex shell functions and hello to declarative command definitions!
--help support for all commands and subcommandsFor Linux or MacOS:
curl -fsSL https://github.com/jilchab/eashy/raw/main/install.sh | sh
Or using Cargo:
cargo install eashy
default.kdl):("Python venv management") \
venv {
("Create a new virtual environment") \
init {
python -m venv ".venv"
source ".venv/bin/activate"
echo "Activated virtual environment, version: $(python --version)"
}
("Activate the virtual environment") \
activate {
source ".venv/bin/activate" && \
echo "Activated virtual environment, version: $(python --version)" || \
echo "Failed to activate virtual environment. Make sure .venv exists."
}
("Deactivate the virtual environment") \
deactivate {
deactivate && echo "Deactivated virtual environment"
}
("Delete the virtual environment") \
delete {
deactivate
rm -rf ".venv" && \
echo "Removed virtual environment"
}
}
Generate the shell script for every functions contained in the kdl file
eashy
Note: You can change the input/output files, try eashy --help for more info
source ~/.eashy/eashy.sh
Add this line to your ~/.bashrc or ~/.zshrc!
venv --help # Shows main command help
venv init --help # Shows subcommand help
venv init # Creates and activates virtual environment
What the help section looks like:
And cherry on top, you get autocompletion with all your commands on bash/zsh:
Every time you update your kdl file, dont forget to regenerated the shell file with the eashy command!
Here is a quick introduction, more examples in example.kdl
my_cmd {
shell_command arg1 arg2
another_command "with" "arguments"
}
Basically, each node without children are interpreted as s shell line to be executed, and parents node are commands/subcommands
Next to a command, you can ask for positional and optional arguments.
Arguments can be used in shell commands using $
new_sh_file filename shebang="#!/bin/sh" {
"filename=${filename%.*}.sh" // Make sure the name ends with .sh (Quotes for escaping '{' and '}' characters)
echo $shebang > $filename // Create the file and write the shebang
chmod +x $filename // Make the file executable
}
-- or - if its name is one characterExample:
create_file name="file.txt" v=#false verbose=#false {
touch $name
if $v || $verbose; then
echo "New file $name created"
fi
}
$ create_file --name hello.rs -v
New file hello.rs created
Some arguments can accept more than one string
You can prefix arguments with:
*arg: Zero or more arguments needed+arg: One or more arguments needed?arg: Zero or one argument neededFor example, a command that iterate each source and copy to a destination with a message.
mycopy +src dest {
for s in $src; do
echo "copy $s to $dest"
cp $s $dest
done
}
In this example, the for loop syntax is similar in bourne-like shell, as a node without children can be terminated by a semicolon
("Main command description") \
main_command {
("Subcommand description") \
sub_command ("Arg help section")arg {
echo "This is a subcommand with one arg: $arg"
}
("Another subcommand") \
another_sub find=("Help for optional args too, default empty")"" {
ls "-la" | grep "$find"
}
}
See the help section with:
main_command --help
main_command sub_command -h
...
Eashy supports special prefixes for flow control:
command_name - Execute All: Run all commands regardless of success/failure&command_name - Until Error: Stop execution if one command fails|command_name - Until Success: Stop execution if one command succeedsExample:
&stop_on_error {
echo "This command has a & prefix"
"false"
echo "This will not run as the previous command fails"
}
|stop_on_success {
"false"
echo "This command has a | prefix"
echo "This will not run as the previous command succeeds"
}
Perfect for creating project-specific command shortcuts:
("Development commands") \
dev {
("Start development server") \
start {
npm run dev
}
("Run tests") \
test {
npm run test
}
("Build for production") \
build {
npm run build
}
}
Simplify environment setup and management:
("Docker operations") \
dck {
("Start all services") \
up {
docker-compose up -d
}
("Stop all services") \
down {
docker-compose down
}
("View logs") \
logs {
docker-compose logs -f
}
}
Create custom git command combinations:
("Git workflow shortcuts") \
git-flow {
("Quick commit and push") \
qcp m=("Commit message")"Quick commit"{
git add "."
git commit -m $m
git push
}
("Create and switch to new branch") \
new-branch name {
git checkout -b $name
git push -u origin
}
}
Contributions are welcome! Please feel free to open an issue or submit a pull request.
This project is licensed under the Apache-2.0 License - see the LICENSE file for details.