Skip to content

Latest commit

 

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

run — script and task manager

Go Reference License: Apache 2.0 Release

# run installation
go install github.com/pt-main/run/cmd/run@latest
# tal installation
go install github.com/pt-main/run/cmd/tal@latest

run is a tool for managing scripts, scripting any scenario in a built‑in Lua‑like language with incrementality, storing scripts in a global/local repository, full system and platform independence (runs anywhere Go compiles), and built‑in script distribution methods, e.g., via GitHub.

The project includes Task Lua (tal) – a task runner seamlessly integrated into run. For more details, see the README.


Why run?

Problem run solves
Scripts scattered across projects Global storage ~/run/
Need to remember paths One command: run -r myscript
Different languages Supports Python, Bash, Batch, Lua – and easily extensible
Grouping Tags for selective execution (--tagged)
Project scripts Local mode with .run/ in the current folder
Security TYCL config with a strict contract
Compactness Small binary with full platform independence

run gives globality, simplicity, and control without unnecessary complexity.

Why Tal?

Problem tal solves
Makefiles are hard to read and write Simple DSL with comments and Lua instead of Shell
Incremental builds are flaky SHA256 hashes instead of modification times
No way to call tasks from each other Built‑in function to invoke tasks
File dependencies are verbose Works out of the box

tal gives incrementality, modernity, and Lua – all in one tool.


Installation

As a binary

Download the release for your OS/architecture and place it in your PATH:

# Linux/macOS
chmod +x run-linux-amd64
sudo mv run-linux-amd64 /usr/local/bin/run

# Windows
# Just put run-windows-amd64.exe in a folder that's in your PATH

Via go install

go install github.com/pt-main/run@latest

On first run, run will create the structure in ~/run/:

  • config.tycl – configuration with the script list.
  • scripts/ – Lua wrappers for execution.
  • base/ – original script files.

Syntax

run [--<lm/localmode>/--<gm/globalmode>] <cmd> <args...>

Commands

Command Description Example
-add <path> <name> [docs] Add a script (supports .py, .sh, .bat, .lua) run -add script.py mypy
-remove <name> Remove a script run -remove mypy
-list List scripts run -list
-r <name> [args...] Run a script run -r mypy arg1 arg2
<name> [args...] Run a script (if the name doesn't conflict with a command) run mypy arg1
-tag <name> <tags...> Add tags run -tag mypy deploy prod
-rm-tag <name> <tags...> Remove tags run -rm-tag mypy prod
-localmode [true/false] Enable/disable local mode, show current state run -localmode true
-r --tagged="tag1;tag2;..." Run scripts with any of the tags run -r --tagged="deploy;test"
-r --tagged="..." --parallel Run scripts with the given tag in parallel run -r --tagged="deploy;build" --parallel
-r --tagged="..." --args="" Pass arguments to the script (useful to avoid conflicts, e.g., with run flags, or to not pass arguments) run -r --tagged="deploy;build" --args="--tagged dev", run -r --tagged="deploy;build" --parallel --args – passes no arguments, instead of passing --parallel
-version Show version run -version

--no_color – disables coloured output for the session.

Flags

  • --force with -add – replaces an existing script with the same name.
  • --tagged="tag1;tag2" with -r – run by tags.
  • --ll / --localmode / --gm / --globalmode right after run – run in local/global mode, restores the mode set by run -localmode after completion.

Local mode

By default, run works globally (config in ~/run/).
Enable local mode – and run will use .run/ in the current folder:

run -localmode true  # enable
run -localmode false # disable
run -localmode       # false – shows the current state

This is useful for projects: scripts live in the repository and don't interfere with the global config.


Language support

run automatically generates Lua wrappers that call the original scripts with the passed arguments.

Extension Language Notes
.py Python Looks for python3, then python
.sh Bash Executes via bash
.bat Batch Executes via cmd /c
.lua Lua Executes directly (no wrapper)
.task.lua Task Lua (Tal) Executes via run tal run

Project structure

~/run/
├── config.tycl          # TYCL config (strict contract)
├── scripts/             # Lua wrappers for execution
│   └── myscript.lua
└── base/                # Original scripts
    └── myscript.py

TYCL config

The script configuration is built on Tycl – a typed language with a contract concept (fixed configuration formats).

The config contract:

strict {
    scripts: objects = strict {
        name: string,        // Script name (command)
        script: string,      // Wrapper file name (matches the Lua script name inside run/scripts, without extension)
        description: string, // Description
        tags: strings,       // Tags
        ext: string,         // Extension (.py, .sh, .bat, .lua)
    },
}

The config is auto‑filled by the run CLI. After the first run it looks like this:

{
    scripts: objects = [
        {
            name: string = "test",
            script: string = "test",
            description: string = "[?BBK]Simple script for functions test[?RT]",
            ext: string = "",
            tags: strings = ["__test"],
        }
    ],
}

Built‑in Lua

Each wrapper is a Lua script that provides:

  • script_path(name) – path to the original script.
  • get_arg(idx) – get an argument by index.
  • get_args() – table of all arguments.
  • run_script(name, ...) – run another script from the wrapper.
  • run_script_parallel(name, ...) – runs the specified script asynchronously in a background thread. Does not block the current script execution. All arguments after the name are passed to the called script.
  • wait() – waits for all background scripts started via run_script_parallel to finish. It is recommended to call this after starting parallel tasks to ensure they complete before the main script exits.

Example:

run_script_parallel("build", "--release")
run_script_parallel("test")
wait()  -- wait for build and tests to finish

Examples

Adding a script

run -add ~/projects/tools/deploy.py deploy "Deploy to production"
run -list
# ╭─────── Scripts
# ⎬─ deploy (.py):
# │     Deploy to production
# ╰───────

Running

run -r deploy --env=prod
# or
run deploy --env=prod  # when the script name doesn't conflict with run commands

Tags

run -tag deploy prod utils
run -r --tagged="prod"   # runs all scripts with the prod tag

Local mode

cd ~/myproject
run -localmode true
run -add script.py build
# now the script is saved in .run/

or

run --localmode add script.py build

Important: the --localmode flag must appear right after run to work correctly.


By Pt, 2026 – written using lc, tap, pack, tycl.

About

Simple and powerful script manager

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages