• Stars
    star
    283
  • Rank 146,066 (Top 3 %)
  • Language
    Python
  • License
    MIT License
  • Created almost 5 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

the complementary task runner for python

General

pypi pypi-downloads ci All Contributors

The complementary task runner for python.

Every development pipeline has tasks, such as test, lint or publish. With taskipy, you can define those tasks in one file and run them with a simple command.

For instance, instead of running the following command:

python -m unittest tests/test_*.py

You can create a task called test and simply run:

poetry run task test

Or (if you're not using poetry):

task test

In addition, you can compose tasks and group them together, and also create dependencies between them.

This project is heavily inspired by npm's run script command.

Requirements

Python 3.6 or newer.

Your project directory should include a valid pyproject.toml file, as specified in PEP-518.

Usage

Installation

To install taskipy as a dev dependency, simply run:

poetry add --dev taskipy

Adding Tasks

In your pyproject.toml file, add a new section called [tool.taskipy.tasks].

The section is a key-value map, from the names of the task to the actual command that should be run in the shell.

There are two ways to define tasks. The easy way is to simply write the command down as a string:

pyproject.toml

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
lint = "pylint tests taskipy"

Alternatively, you can define tasks more explicitly by declaring both the command and a helpful description using an inline table:

pyproject.toml

[tool.taskipy.tasks]
test = { cmd = "python -m unittest tests/test_*.py", help = "runs all unit tests" }
lint = { cmd = "pylint tests taskipy", help = "confirms code style using pylint" } 

The explicit notation is more verbose, but provides better context to anyone who uses the task.

Running Tasks

In order to run a task, run the following command in your terminal:

$ poetry run task test

You can also list all existing tasks by running the following:

$ poetry run task --list
test                python -m unittest tests/test_*.py
lint                pylint tests taskipy

If you declared your task explicitly, you will see the description of the task by the side of the task's name:

$ poetry run task --list
test                runs all unit tests
lint                confirms code style using pylint

Passing Command Line Args to Tasks

If you want to pass command line arguments to tasks (positional or named), simply append them to the end of the task command.

For example, running the above task like this:

poetry run task test -h

Is equivalent to running:

python -m unittest tests/test_*.py -h

And will show unittest's help instead of actually running it.

⚠️ Note: if you are using pre \ post hooks, do notice that arguments are not passed to them, only to the task itself.

Composing Tasks

Grouping Subtasks Together

Some tasks are composed of multiple subtasks. Instead of writing plain shell commands and stringing them together, you can break them down into multiple subtasks:

[tool.taskipy.tasks]
lint_pylint = "pylint tests taskipy"
lint_mypy = "mypy tests taskipy"

And then create a composite task:

[tool.taskipy.tasks]
lint = "task lint_pylint && task lint_mypy"
lint_pylint = "pylint tests taskipy"
lint_mypy = "mypy tests taskipy"

Pre Task Hook

Tasks might also depend on one another. For example, tests might require some binaries to be built. Take the two following commands, for instance:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
build = "make ."

You could make tests depend on building, by using the pretask hook:

[tool.taskipy.tasks]
pre_test = "task build"
test = "python -m unittest tests/test_*.py"
build = "make ."

The pretask hook looks for pre_<task_name> task for a given task_name. It will run it before running the task itself. If the pretask fails, then taskipy will exit without running the task itself.

Post Task Hook

From time to time, you might want to run a task in conjuction with another. For example, you might want to run linting after a successful test run. Take the two following commands, for instance:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
lint = "pylint tests taskipy"

You could make tests trigger linting, by using the posttask hook:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
post_test = "task lint"
lint = "pylint tests taskipy"

The posttask hook looks for post_<task_name> task for a given task_name. It will run it after running the task itself. If the task failed, then taskipy will not run the posttask hook.

Using Variables

In some cases, you might find yourself passing the same arguments over and over again. Let us take a look at the following tasks:

[tool.taskipy.tasks]
lint = "pylint path/to/my_module"
black = "black path/to/my_module"

As you can see, we provide the same path argument to both pylint and black.

In order to encourage DRY and improve your ability to change these values later on, taskipy actually lets you declare and reuse variables in your tasks:

[tool.taskipy.variables]
path = "path/to/my_module"

[tool.taskipy.tasks]
lint = { cmd = "pylint {path}", use_vars = true }
black = { cmd = "pylint {path}", use_vars = true }

We have made the following changes to our configuration:

  1. We declared variables under tool.taskipy.variables
  2. We flagged the relevant task using use_vars to note that they should use the variables
  3. We replaced the repeating path with a {path} variable

String Formatting

The formatting of the task commands uses python's own string.format method, and therefore supports everything that python's formatted string literals let you do.

Always Use Variables

Using variables is opt-in, which means that by default commands do not use them, and you will have to turn them on a task to task basis.

If you want to turn on use_vars globally, all you need to do is to declare that under taskipy's settings table:

[tool.taskipy.settings]
use_vars = true

[tool.taskipy.variables]
path = "path/to/my_module"

[tool.taskipy.tasks]
lint = "pylint {path}"
black = "black {path}"

Recursive Variables

If we want to use variables within other variables, we can utilize recursive variables. By default, variables are not recursive, but we can specify a variable to be recursive by setting the recursive key to true.

[tool.taskipy.settings]
use_vars = true

[tool.taskipy.variables]
src_dir = "src"
package_dir = { var = "{src_dir}/package", recursive = true }

[tool.taskipy.tasks]
echo = "echo {package_dir}"

In this example, we could run task echo and we would then see src/package.

Using Taskipy Without Poetry

Taskipy was created with poetry projects in mind, but actually only requires a valid pyproject.toml file in your project's directory. As a result, you can use it even without poetry:

Installing With PIP

Install taskipy on your machine or in your virtualenv using:

pip install taskipy

Running Tasks

Head into your project's directory (don't forget to activate virtualenv if you're using one), and run the following command:

task TASK

Where TASK is the name of your task.

Advanced Use Cases

If you have a more specific use case, you might not be the first to run into it! Head over to the ADVANCED_FEATURES doc, and look it up.

Maintainers 🚧


Roy Sommer

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Eugene Triguba

πŸ’»

RobinFrcd

πŸ’»

Bernardas AliΕ‘auskas

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

More Repositories

1

react-electron-browser-window

Electron's BrowserWindow as a react component
JavaScript
14
star
2

jest-after-this

it's like afterEach, but for the current test
TypeScript
13
star
3

secured-chat-server

academic computer security project
Python
9
star
4

config.ts

πŸ“š Transparent, typesafe environment configuration
TypeScript
6
star
5

secured-chat-client

academic computer security project
JavaScript
6
star
6

twobees

assertions with a buzz 🐝
TypeScript
4
star
7

python-starter-kit

starter kit for quick python development
Python
4
star
8

ElectronScriptWindow

Electron windows without html files
JavaScript
3
star
9

concurrentp

Promise concurrency control done right
TypeScript
3
star
10

pysoup

Package management in a bowl (old project)
Python
3
star
11

spotify-tvos-app

πŸ“Ί TVOS Spotify App using Spotify Connect API
TypeScript
3
star
12

menoo

a simple, deploy ready interactive cli menu
Python
3
star
13

advent-2022

advent of code 2022 solutions in rust
Rust
2
star
14

clipsync

pythonic cli for zeroconf shared clipboards over local networks
Python
2
star
15

academic-assembly-assignment

an assembly implementation of conway's game of life, in a self developed assembly macro language
Assembly
2
star
16

dicebox

build tool for typescript based RPG Maker MV plugins
TypeScript
2
star
17

cake-rpc

fully typed rest library for your express & browser apps
TypeScript
1
star
18

plant-cli

cli for quick, opinionated creation of typescript projects
TypeScript
1
star
19

docsify-dynamo

docsify plugins for creating dynamic documentation sites
TypeScript
1
star
20

andromeda

declarative, class-driven framework written around flask
Python
1
star
21

nodegui-parcel-example

an example nodegui project that uses parcel for bundling and asset management
TypeScript
1
star
22

parcel-plugin-nodegui

use and bundle assets with your nodegui app
JavaScript
1
star