Task Runner
Simple task/script runner with auto-discovery of scripts from a directory and with arrows+enter launcher UX.
Example Usage
It's common in a project to have a lot of development tasks that you execute with the CLI in your local machine.
This Task Runner will help you to automate those tasks.
Features:
- Auto-Discovery of scripts from
task/scriptsdirectory to populate the launcher - Easy Launcher UX: Select script with Arrow up/down and press Enter to execute
- Support all script languages: Script are simple scripts files, they can be anything that can be launched in the machine
Imagine that your project has this file tree structure:
. your-project
├── docker
│ ├── docker-compose.yml
├── next-js
│ ├── ...
├── task
│ ├── run.sh
│ └── scripts
│ ├── 0--MISC--make-scripts-executable.sh
│ ├── 2--DEV--LAUNCH-docker-container--DB.sh
│ ├── 2--DEV--LAUNCH-docker-container--OTHER-SERVICE.sh
│ ├── 2--DEV--STOP--docker-container--ALL.sh
│ └── 2--DEV--STOP+DESTROY-VOLUME--docker-container--ALL.shWhen you need to run a task:
- You first go to the root of the project directory with the CLI
- Then run
task/run.shin the CLI to launch the script launcher - Select the script with arrows and press enter to run
- Done!
This Task Runner is not a complex solution, but it's a good starting point to automate the CLI.
When you need cross-platform support or more features, reach these:
- Taskfile – https://taskfile.dev/
- Make – https://www.gnu.org/software/make/
- Just – https://just.systems/
- Run – https://github.com/adonovan/run
- Mage – https://magefile.org/
- Invoke (Python) – https://www.pyinvoke.org/
- Rake (Ruby) – https://ruby.github.io/rake/
- pypyr – https://pypyr.io/
- Goke – https://github.com/nathanxurui/goke
- Whiz – https://github.com/whiz-dev/whiz
- Maki – https://github.com/grillazz/maki
First Time Install
- Follow
Auto InstallorManual Installinstructions to get the files in your project - Make
task/run.shexecutable
Runchmod +x task/run.sh - Make
task/scripts/*executable
Runchmod +x task/scripts/*
Run a script
- Go to the root of the project directory.
- Run the script launcher
./task/run.sh - Select the script with arrows and press enter.
Add new script
-
Create a script file in the
task/scriptsdirectory (or duplicate an existing one)TipBy default the Launcher search for script files in the
task/scriptsdirectory.
If you want to change thescriptsdirectory name, do it, but then update the constantSCRIPTS_DIRintask/run.sh. -
Rename the file as you'd like it to be called in the launcher UI
-
Code it
TipBecause you launch the script launcher from the root of the project, it's recommended that the code inside the script assumes that the current working directory is the root of the project.
-
Make it executable
Runchmod +x SCRIPT_FILE_PATHTipTo simplify the process, we provide a pre-made script that will make all the scripts in the
task/scriptsdirectory executable.
Just run./task/run.shand select the0--MISC--make-scripts-executable.shscript.NOTE: if you updated the scripts directory name, you must update the
0--MISC--make-scripts-executable.shscript too. -
Now if you run
./task/run.shyou will see the new script in the launcher
Dependencies
No dependencies
Auto Install
npx shadcn@latest add https://shadcn-registry-ts.vercel.app/r/util-dev-task-runner.json
Manual Install
#!/bin/bash
readonly THIS_FILE_PATH="${BASH_SOURCE[0]}"
readonly THIS_FILE_DIR="$(dirname "${THIS_FILE_PATH}")"
readonly SCRIPTS_DIR="$THIS_FILE_DIR/scripts"
SCRIPTS_FILES=()
SCRIPT_NAMES=()
getScripts() {
if [ ! -d "$SCRIPTS_DIR" ]; then
echo "[ERROR:SCRIPTS_DIR_NOT_FOUND] Directory $SCRIPTS_DIR not found."
exit 1
fi
for file in "$SCRIPTS_DIR"/*; do
if [ -f "$file" ] && [ -x "$file" ]; then
SCRIPTS_FILES+=("$file")
SCRIPT_NAMES+=("$(basename "$file")")
fi
done
if [ ${#SCRIPTS_FILES[@]} -eq 0 ]; then
echo "[ERROR:EMPTY_SCRIPTS_DIR] No executable script found in $SCRIPTS_DIR"
exit 1
fi
}
runScript() {
# get props
local SCRIPT_TO_RUN_NAME="$1"
# get script file path
local SCRIPT_TO_RUN_FILE=""
for i in "${!SCRIPT_NAMES[@]}"; do
if [[ "${SCRIPT_NAMES[$i]}" == "$SCRIPT_TO_RUN_NAME" ]]; then
SCRIPT_TO_RUN_FILE="${SCRIPTS_FILES[$i]}"
break
fi
done
# ensure file exists
if [ ! -f "$SCRIPT_TO_RUN_FILE" ]; then
echo "[ERROR:SCRIPT_FILE_NOT_FOUND] Script file: $SCRIPT_TO_RUN_FILE not found."
exit 1
fi
# run script
echo ""
echo "=========================================="
echo "Executing Script..."
echo "Script: ${SCRIPT_TO_RUN_FILE}"
echo "=========================================="
echo ""
"$SCRIPT_TO_RUN_FILE"
}
# Menu interattivo robusto con frecce
showMenu() {
# local state
local index=0
local total=${#SCRIPT_NAMES[@]}
goPrev() {
((index--))
if [ $index -lt 0 ]; then
index=$((total-1));
fi
}
goNext() {
((index++))
if [ $index -ge $total ]; then
index=0;
fi
}
# draw console
drawMenu() {
clear
echo "Use arrows ↑↓ and press Enter to run a script:"
for i in "${!SCRIPT_NAMES[@]}"; do
if [ $i -eq $index ]; then
echo "> ${SCRIPT_NAMES[$i]}"
else
echo " ${SCRIPT_NAMES[$i]}"
fi
done
}
# run
local KEY_CODE_ESCAPE=$'\x1b'
local KEY_CODE_UP=$'\x1b[A'
local KEY_CODE_DOWN=$'\x1b[B'
local KEY_CODE_ENTER=""
while true; do
# re-render
drawMenu
# on user key press -> do stuff
local key1=""
IFS= read -rsn1 key1 # primo carattere
if [[ $key1 == $KEY_CODE_ESCAPE ]]; then
local key2=""
IFS= read -rsn2 key2 # leggi sequenza escape
local key="$key1$key2"
if [[ $key == $KEY_CODE_UP ]]; then # freccia su
goPrev
elif [[ $key == $KEY_CODE_DOWN ]]; then # freccia giù
goNext
fi
elif [[ $key1 == $KEY_CODE_ENTER ]]; then # invio
local SCRIPT_NAME="${SCRIPT_NAMES[$index]}"
runScript "$SCRIPT_NAME"
break
fi
done
}
# ================================
# MAIN
# ================================
getScripts
showMenu
# Task Runner
A simple task runner.
Features:
- **Auto-Discovery of scripts** from `task/scripts` directory to populate the launcher
- **Easy Launcher UX**: Select script with Arrow up/down and press Enter to execute
- **All script languages support**: Script are simple scripts files, they can be anything that can be launched in the machine
## Run a script
1. Run the script launcher
```bash
./task/run.sh
```
2. Select the script with arrows and press enter
## Add new script
1. Duplicate an existing script and rename it, then write the script.
2. Assumes that the current working directory is the root of the project inside the code
3. Make it executable
```bash
./task/run.sh
# select
0--MISC--make-scripts-executable.sh
```#!/bin/bash
echo "Running with CWD: $(pwd)"
echo "MAKE SCRIPTS EXECUTABLE"
chmod +x ./task/scripts/*#!/bin/bash
echo "Running with CWD: $(pwd)"
echo ""
echo "ciao"#!/usr/bin/env node
console.log(`Running with CWD: ${process.cwd()}`);
console.log("");
console.log("ciao");Test
No test
Command Palette
Search for a command to run...