Run Tool
A multi-purpose tool to aid developers in executing common tasks. Aiming to suit modern requirements, whilst not replicating make.
Whilst fairly stable, it is still in development and features may change
Features
- Configuration uses YAML
- Per project configuration file (if added at root of project)
- Supporting a global configuration (per user)
- Customisable targets
- Arguments
- Environment variables
- Settable current working directory
- Hooks (before and after target run)
- Conditional runs (only run target when conditions are met)
- Watch for file/folder changes
Use Case
- Running a project
- Building a project
- Run tests
- One-off commands, e.g. downloading test data
Goals
- Fast and easy to use
- Human readable configuration
- Cross-platform (for core functionality)
- Support mono-repos
- Support use in CI/CD
Non-Goals
- Be a complete replacement to make
Install
Currently the only way to install is using Cargo:
From crates.io (stable releases only):
cargo install run-tool
From repository (may include unstable):
cargo install --git https://github.com/enchant97/run-tool.git
Add
--tag vx.x.x
to install a specific version
Configuration
This chapter will go through everything supported in a "Run Tool" configuration file.
When running "Run Tool" unless overridden it will search the current directory for a file matching the defined configuration file names. If it does not find one it will move on to the parent directory; continuing until either no parents are left or a config has been located.
After a configuration file has been found the target will run from the current working directory of the configuration file, this allows for a mono-repo to have one file at the root of the project responsible for the whole project that can be loaded from any child directory.
Configuration Files
By default these will be either .run-tool.yml
or .run-tool.yaml
. You may adjust this globally by using the RUN_TOOL_FILENAME
environment variable or by passing as an argument when launching the app.
The File
There are many different configuration values that can be used to provide different functionality, this section documents them.
Reference
targets:
<target_name>:
# - optional, string
# - give the target a description
description: null
# - required, string
# - program to execute
program: ""
# - optional, string or array of strings
# - arguments to give program
args: []
# - optional, dictionary (var_key: var_val)
# - environment variables to give program
env: null
# - optional, string or array of strings
# - path to environment files to load
env_file: []
# - optional, string (default to loaded config file cwd)
# - current working directory to set for application
cwd: null
# - optional, array of strings
# - other targets to run before running this one
before_hooks: []
# - optional, array of strings
# - other targets to run after running this one
after_hooks: []
# - optional, array of dictionaries
# checks to meet before running target (including hooks)
run_when:
-
# - required, string
# - check name
when: ""
# - optional, boolean
# - whether to invert the check
invert: false
# - optional, dictionary
# - extra fields to give to check (depends on specified check)
fields: {}
# - optional, watch configuration
watch:
# - array of paths to watch
paths: []
Checks
Checks are used in the run_when
configuration. They decide whether to run the selected target or not.
Explanations in this section will assume the check has not been inverted.
Execution OK
Will allow target to run when the execution returns a status code of success (zero).
when: exec_ok
fields:
# required, string
# - program to execute
program: ""
# - optional, string or array of strings
# - arguments to give program
args: []
# - optional, dictionary (var_key: var_val)
# - environment variables to give program
env: null
# - optional, string or array of strings
# - path to environment files to load
env_file: []
# - optional, string (default to loaded config file cwd)
# - current working directory to set for application
cwd: null
Path Exists
Will allow target to run when given path exists, could mean it is a directory or file.
when: path_exists
fields:
# - required, string
# - path to check
path: ""
Path Is File
Will allow target to run when given path exists and is a file.
when: path_is_file
fields:
# - required, string
# - path to check
path: ""
Path Is Directory
Will allow target to run when given path exists and is a directory.
when: path_is_dir
fields:
# - required, string
# - path to check
path: ""
Example
Here is an example for building a project in a mono-repo.
#
# my-project/.run-tool.yml
#
targets:
dev-build:
program: cargo
args:
- build
cwd: backend/
watch:
paths:
- backend/
clean-build:
program: cargo
args:
- build
- --release
env:
CARGO_HOME: /mnt/cache/.cargo
cwd: backend/
before_hooks:
- clean
clean:
program: cargo
args:
- clean
cwd: backend/
Global Configuration
To utilise the global configuration functionality, you can place a "Run Tool" config in your home folder shown below:
Linux/Unix
$XDG_CONFIG_HOME/run-tool/
$HOME/.config/run-tool/
Darwin (MacOS)
$HOME/.config/run-tool/
Windows
%%USERPROFILE%%/.config/run-tool/
Usage
Whilst the application has in-build help (by running run-tool help
), this section will provide a rough overview of available commands.
Running A Target
run-tool run <target name>
Or add the ability to watch for file/folder changes:
run-tool run -w <target name>
You can also provide extra arguments to the targets executable appending to any specified in the config.
run-tool run <target name> -- --release
Viewing Config
To view the currently loaded configuration in a human readable format use this command:
run-tool config
Or view a more minimal version:
run-tool config -m
Tips
- Add an alias in your shell, e.g.
alias rt='run-tool run'
- You can name your config either:
.run-tool.yaml
or.run-tool.yml
Contributions
This project is open to contributions! So long as the simple rules are followed:
- Check existing contributions (open issues and pull requests) before posting your own
- Contributions must be licensed under the same as the project
- Make titles and commit messages clear, e.g. "changed x to allow for y"
- Fits the project goals & non-goals
Modifying Checks
- When adding a new check it should be positive e.g. "path exists" not "path missing", this allows for uniform checks since the user can set "invert" field.
- Adding new fields is permitted
- Removing fields unless they are deprecated is not permitted