A language agnostic make-like tool meant for python projects
Project description
Taskr
A magical, zero dependency, easy to use task runner with an original name. Inspired by Mage, a task runner for go. Made for python projects, but usable for any.
All that's needed is a tasks.py file.
A few highlights
- Basically make(1) without a build system
- Zero dependencies
- Auto load environment variable files
- Easily pass arguments
- Auto generated cli docs
- Usable in any subdirectory of your project
- Built functions to easily run system commands inside venvs
- Built in helper functions for python development
Installing
pip install taskr-cli
Check the version
taskr --version
Generate a default tasks file
taskr --init
Using
Make sure you have a tasks.py file defined in the root of your repo.
taskr
can be used from any sub directory if PYENV_DIR
or 'TASKR_DIR' is set to the projects root. There is a utility function "injectPath()" that can do this for you, included in the template. See other utility functions at the bottom of the readme.
CLI:
[master●] » taskr -h
usage: taskr [-h] [-d] [-i] [-l] [-p] [-v]
A cli utility to run generic tasks
options:
-h, --help show this help message and exit
-d, --docker run a task in an image with docker. Requires IMAGE_NAME set in tasks.py
-i, --init generate a template task file
-l, --list show defined tasks
-p, --podman run a task in an image with podman. Requires IMAGE_NAME set in tasks.py
-v, --version show the version number
When listing tasks, taskr will attempt to grab either the docblock or a single # comment above the function name and show it for cli documentation. Taskr will prefer the single # comment over the docblock to display if both exist.
Also note, any functions in tasks.py
that start with an underscore are ignored when listing.
[master●] » taskr -l
Tasks:
all : Runs all static analysis tools
build : Builds the wheel
clean : Remove build artifacts, cache, etc.
flake : Check flake8
fmt : Run black
mypy : Checks types
*reinstall : Re-installs taskr
sort : Sort imports
test : Run tests
upload_prod : Send it for real!
upload_test : Send it!
* = default
To run a task, just pass the name of a function after taskr
. Output from a task will be displayed
[master●] » taskr format
All done! ✨ 🍰 ✨
11 files left unchanged.
Configuration Variables
There are a few configuration setting, set in tasks.py itself. They are all uppercase and generally should be at the top of the file
VENV_REQUIRED = True
in your tasks.py file, taskr will only run if it detects it's running in a virtual environment. You can delete it otherwise
DEFAULT = "some_func"
marks the task as default. Default tasks are run when taskr
is run without any arguments
ENV = path/to/file.env
will load that environment file before every task
IMAGE_NAME = "my_docker_image"
will enable running tasks inside an image, though docker or podman (the image needs taskr-cli on the path). Details are down below
from taskr import runners
DEFAULT = "test"
VENV_REQUIRED = True
ENVS = "dev.env"
IMAGE_NAME = "dev_image"
# Run tests, and passed dev.env vars when running
def test
runners.run("python -m pytest tests/")
Running Any Task in an Image
Taskr can also attempt to run inside a built image. -d
will attempt docker, and -p
will attemty to use podman
IMAGE_NAME
Needs to be set in taskr.py so taskr knows what to run inside of. Right now, this is just though a subprocess call of
run --rm -a stdin -a stdout
to an image that has taskr-cli in its path
Helpful functions for running tasks
A few task running methods are provided for system running tasks. Taskr expects task functions to return either True
(The task was successful) for False
it failed. To determine if a subprocess/system call was successful or not, taskr looks at the return code of the called program. 0 is success, anything else fails.
Taskr will auto copy your existing environment variables when running tasks, so running tasks with programs installed in a virual environment (i.e. dev tools though pip) will work.
You can also run any code you want as well under a task, these are just helpful wrappers around subprocess that work nicely with taskr.
run
run
's argument can be either a list, or a string. A list is parsed into one command, not multiple
Optionally pass a an environment dictionary to be used at runtime.
from taskr import runners
# Run flake8
def flake_list() -> bool:
return runners.run(["python", "-m", "flake8", "taskr/*.py"])
# Run tests
def flake() -> bool:
return runners.run("python -m pytest tests/ -v")
# Build a wheel
def build():
ENV = {
"PRODUCTION": "true"
}
return runners.run("python setup.py install", ENV)
run_conditional
run_conditional
is a way to run tasks (functions) in order, as long as the previous task returns a non failure return code (False).
You can throw normal python functions in here to
from taskr import runners
import some_package as sp
# Run black
def fmt():
return runners.run("python -m black .")
# Check flake8
def flake():
return runners.run(["python", "-m", "flake8", "taskr/*.py"])
# Run all static tools
def all():
return runners.run_conditional(flake, fmt, sp.function)
run_output
run_output
' will run a command and return the output
from taskr import runners
# Get the number of env variables
def _get_count():
ret = runners.run_output("env | wc -l")
print(ret.status) # True
print(ret.stdout) # "90"
print(ret.sterr) # ""
You can an environment dict to this function.
Passing arguments to functions
You can also pass arbitrary arguments to any defined function. For example, passing the environment to starting a server. This requires the function to have a default argument set.
def start(env: str = "Dev"):
ENVS = {
"ENV": env
"WATCH": "true"
}
return taskr.run("python start.py", ENVS)
And from the command line
taskr start dev
# Or
taskr start
# Or
taskr start prod
You can also use key word arguments so pass only selected arguments. This requires all previous arguments to have a default value.
def start(env: str = "dev", timeout: int = 180):
ENVS = {
"ENV": env
"WATCH": "true"
"TIMEOUT": timeout
}
return taskr.run("python start.py", ENVS)
Only passing timeout in this example, and keeping env to be the default dev
taskr start timeout=60
Utilities
There are a few utility functions included, mostly for python package development.
from taskr import utils
# Removes dist/build folders
utils.cleanBuilds()
# Remove compiled files and folders
utils.cleanCompiles()
# In a venv or not
utils.inVenv()
# Transforms an ENV file into a dict
utils.readEnvFile(filename)
# Bumps setup.py's version number by 0.0.1, or replaces it with argument
utils.bumpVersion(version=None):
# Adds `export TASKR_DIR=CWD' to your VENV activation, so
# you can use taskr from any location in the VENV (e.g. sub directories)
utils.addTaskrToEnv()
Developing
This project uses pipenv. Make sure it's installed. Then call
python -m pipenv shell
pipenv install --dev
taskr check
taskr test
There are numerous tests in taskr/tests
which cover most functionality that's testable, as well as examples
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for taskr_cli-1.2.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce37464950a33afa6b618596827c9cad27be204e9195238569572ab91552586e |
|
MD5 | bda3301f0c881356b8a3f3114dfaa05e |
|
BLAKE2b-256 | c2eeac9765d85d4cbbc079431be7dcbdaa84cb2ba4d8bb15cf8cc93b682d93c7 |