taskr-cli


Nametaskr-cli JSON
Version 1.2.6 PyPI version JSON
download
home_page
SummaryA language agnostic make-like tool meant for python projects
upload_time2023-09-07 00:36:37
maintainer
docs_urlNone
author
requires_python>=3
licenseMIT License Copyright (c) 2021 Kyle Peasley Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords cli utility
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Taskr
[![PyPI version](https://badge.fury.io/py/taskr-cli.svg)](https://badge.fury.io/py/taskr-cli)

A magical, zero dependency, easy to use task runner with an original name. Inspired by [Mage](https://github.com/magefile/mage), a make-like tool 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 to tasks from the command line
- Auto generated cli documentation
- Usable in any subdirectory of your project
- Built in functions to easily run system commands inside virtual environments
- Built in helper functions for python development

## Installing

```shell
pip install taskr-cli
```

Check the version
```shell
taskr --version
```

Generate a default tasks file
```shell
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:

```shell
[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
  -i, --init     generate a template task file
  -l, --list     show defined tasks
  -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. Bellow's an example print out of taskr with a valid `task.py` file.

```shell
[master●] » taskr -l

Tasks:
 build       : Builds a wheel file
 check       : Run all static analysis tools
 clean       : Remove build artifacts, cache, etc.
 fmt         : Run black
 mypy        : Check types
 *reinstall  : Re-installs taskr
 ruff        : Run ruff
 sort        : Sort imports
 test        : Run tests
 upload      : Upload project to PYPI

* = default
```

To run a task, just pass the name of a function after `taskr`. Output from a task will be displayed

```shell
[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


```python
from taskr import runners

DEFAULT = "test"
VENV_REQUIRED = True
ENVS = "dev.env"

# Run tests, and passed dev.env vars when running 'taskr' in the cli
def test
  runners.run("python -m pytest tests/")
```

## 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.

```python
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. As of the current release, you cannot pass arguments to functions passed to `run_conditional`.

```python
from taskr import runners
import some_package as sp

# Run black
def fmt():
    return runners.run("python -m black .")

# Check flake8
def ruff():
    return runners.run("python -m ruff")

# 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

```python
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.

```python
def start(env: str = "Dev"):
  ENVS = {
    "ENV": env
    "WATCH": "true"
  }
  return taskr.run("python start.py", ENVS)

```

And from the command line
```shell
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.

```python
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`

```shell
taskr start timeout=60
```

## Utilities

There are a few utility functions included, mostly for python package development. These are not the main focus of the package and more will probably not be added, rather spun out into a different package

```python
from taskr import utils

# Removes dist/build folders
utils.cleanBuilds()

# Remove compiled files and folders (.pyc, __pycache__)
utils.cleanCompiles()

# In a venv or not
utils.inVenv()

# In a container (docker, podman) or not
utils.inContainer()

# Transforms an ENV file into a dict
utils.readEnvFile(filename = None)

# Bumps setup.py's version number by 0.0.1, or replaces it with argument
utils.bumpVersion(version = None, variable = "version", filename = "setup.py"):

# Adds `export TASKR_DIR=CWD' to your VENV activation, so
# you can use taskr from any location in the VENV (e.g. sub directories)
# Probably don't use this
utils.addTaskrToEnv()
```

## Developing

This project uses pipenv. Make sure it's installed. Then call
```shell
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

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "taskr-cli",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3",
    "maintainer_email": "",
    "keywords": "cli,utility",
    "author": "",
    "author_email": "Kyle Peasley <Kyle.Peasley@gmail.com>",
    "download_url": "",
    "platform": null,
    "description": "# Taskr\n[![PyPI version](https://badge.fury.io/py/taskr-cli.svg)](https://badge.fury.io/py/taskr-cli)\n\nA magical, zero dependency, easy to use task runner with an original name. Inspired by [Mage](https://github.com/magefile/mage), a make-like tool for go. Made for python projects, but usable for any.\n\nAll that's needed is a tasks.py file.\n\nA few highlights:\n\n- Basically make(1) without a build system\n- Zero dependencies\n- Auto load environment variable files\n- Easily pass arguments to tasks from the command line\n- Auto generated cli documentation\n- Usable in any subdirectory of your project\n- Built in functions to easily run system commands inside virtual environments\n- Built in helper functions for python development\n\n## Installing\n\n```shell\npip install taskr-cli\n```\n\nCheck the version\n```shell\ntaskr --version\n```\n\nGenerate a default tasks file\n```shell\ntaskr --init\n```\n\n## Using\n\nMake sure you have a tasks.py file defined in the root of your repo.\n`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.\n\nCLI:\n\n```shell\n[master\u25cf] \u00bb taskr -h\nusage: taskr [-h] [-d] [-i] [-l] [-p] [-v]\n\nA cli utility to run generic tasks\n\noptions:\n  -h, --help     show this help message and exit\n  -i, --init     generate a template task file\n  -l, --list     show defined tasks\n  -v, --version  show the version number\n\n```\n\nWhen 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.\n\nAlso note, any functions in `tasks.py` that start with an underscore are ignored when listing. Bellow's an example print out of taskr with a valid `task.py` file.\n\n```shell\n[master\u25cf] \u00bb taskr -l\n\nTasks:\n build       : Builds a wheel file\n check       : Run all static analysis tools\n clean       : Remove build artifacts, cache, etc.\n fmt         : Run black\n mypy        : Check types\n *reinstall  : Re-installs taskr\n ruff        : Run ruff\n sort        : Sort imports\n test        : Run tests\n upload      : Upload project to PYPI\n\n* = default\n```\n\nTo run a task, just pass the name of a function after `taskr`. Output from a task will be displayed\n\n```shell\n[master\u25cf] \u00bb taskr format\nAll done! \u2728 \ud83c\udf70 \u2728\n11 files left unchanged.\n```\n\n## Configuration Variables\n\nThere are a few configuration setting, set in tasks.py itself. They are all uppercase and generally should be at the top of the file\n\n`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\n\n`DEFAULT = \"some_func\"` marks the task as default. Default tasks are run when `taskr` is run without any arguments\n\n`ENV = path/to/file.env` will load that environment file before every task\n\n\n```python\nfrom taskr import runners\n\nDEFAULT = \"test\"\nVENV_REQUIRED = True\nENVS = \"dev.env\"\n\n# Run tests, and passed dev.env vars when running 'taskr' in the cli\ndef test\n  runners.run(\"python -m pytest tests/\")\n```\n\n## Helpful functions for running tasks\n\nA 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.\n\nTaskr 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.\n\nYou can also run any code you want as well under a task, these are just helpful wrappers around subprocess that work nicely with taskr.\n\n### run\n`run`'s argument can be either a list, or a string. A list is parsed into one command, not multiple\n\nOptionally pass a an environment dictionary to be used at runtime.\n\n```python\nfrom taskr import runners\n\n# Run flake8\ndef flake_list() -> bool:\n    return runners.run([\"python\", \"-m\", \"flake8\", \"taskr/*.py\"])\n\n# Run tests\ndef flake() -> bool:\n    return runners.run(\"python -m pytest tests/ -v\")\n\n# Build a wheel\ndef build():\n  ENV = {\n    \"PRODUCTION\": \"true\"\n  }\n  return runners.run(\"python setup.py install\", ENV)\n\n```\n\n### run_conditional\n`run_conditional` is a way to run tasks (functions) in order, as long as the previous task returns a non failure return code (False).\nYou can throw normal python functions in here to. As of the current release, you cannot pass arguments to functions passed to `run_conditional`.\n\n```python\nfrom taskr import runners\nimport some_package as sp\n\n# Run black\ndef fmt():\n    return runners.run(\"python -m black .\")\n\n# Check flake8\ndef ruff():\n    return runners.run(\"python -m ruff\")\n\n# Run all static tools\ndef all():\n    return runners.run_conditional(flake, fmt, sp.function)\n```\n\n### run_output\n`run_output`' will run a command and return the output\n\n```python\nfrom taskr import runners\n\n# Get the number of env variables\ndef get_count():\n    ret = runners.run_output(\"env | wc -l\")\n    print(ret.status) # True\n    print(ret.stdout) # \"90\"\n    print(ret.sterr)  # \"\"\n```\n\nYou can an environment dict to this function.\n\n## Passing arguments to functions\n\nYou can also pass arbitrary arguments to any defined function. For example, passing the environment to starting a server.\nThis requires the function to have a default argument set.\n\n```python\ndef start(env: str = \"Dev\"):\n  ENVS = {\n    \"ENV\": env\n    \"WATCH\": \"true\"\n  }\n  return taskr.run(\"python start.py\", ENVS)\n\n```\n\nAnd from the command line\n```shell\ntaskr start dev\n# Or\ntaskr start\n# Or\ntaskr start prod\n\n```\n\nYou can also use key word arguments so pass only selected arguments. This requires all previous arguments to have a default value.\n\n```python\ndef start(env: str = \"dev\", timeout: int = 180):\n  ENVS = {\n    \"ENV\": env\n    \"WATCH\": \"true\"\n    \"TIMEOUT\": timeout\n  }\n  return taskr.run(\"python start.py\", ENVS)\n\n```\n\nOnly passing timeout in this example, and keeping env to be the default `dev`\n\n```shell\ntaskr start timeout=60\n```\n\n## Utilities\n\nThere are a few utility functions included, mostly for python package development. These are not the main focus of the package and more will probably not be added, rather spun out into a different package\n\n```python\nfrom taskr import utils\n\n# Removes dist/build folders\nutils.cleanBuilds()\n\n# Remove compiled files and folders (.pyc, __pycache__)\nutils.cleanCompiles()\n\n# In a venv or not\nutils.inVenv()\n\n# In a container (docker, podman) or not\nutils.inContainer()\n\n# Transforms an ENV file into a dict\nutils.readEnvFile(filename = None)\n\n# Bumps setup.py's version number by 0.0.1, or replaces it with argument\nutils.bumpVersion(version = None, variable = \"version\", filename = \"setup.py\"):\n\n# Adds `export TASKR_DIR=CWD' to your VENV activation, so\n# you can use taskr from any location in the VENV (e.g. sub directories)\n# Probably don't use this\nutils.addTaskrToEnv()\n```\n\n## Developing\n\nThis project uses pipenv. Make sure it's installed. Then call\n```shell\npython -m pipenv shell\npipenv install --dev\ntaskr check\ntaskr test\n```\n\nThere are numerous tests in ```taskr/tests``` which cover most functionality that's testable, as well as examples\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2021 Kyle Peasley  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "A language agnostic make-like tool meant for python projects",
    "version": "1.2.6",
    "project_urls": {
        "documentation": "https://gitlab.com/peasleyk/taskr",
        "homepage": "https://gitlab.com/peasleyk/taskr",
        "repository": "https://gitlab.com/peasleyk/taskr"
    },
    "split_keywords": [
        "cli",
        "utility"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "007648d3eaada0492dfd7629a228fdd2d0eb0f2d2df1018a2218dae3da05c5ef",
                "md5": "ebded0e0fd983a4abb9aa5c6ea34f236",
                "sha256": "00ec0203ad6b0eb9c60978695e29c32cd04abc4af0cf67178cb85e2f59368665"
            },
            "downloads": -1,
            "filename": "taskr_cli-1.2.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ebded0e0fd983a4abb9aa5c6ea34f236",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3",
            "size": 14942,
            "upload_time": "2023-09-07T00:36:37",
            "upload_time_iso_8601": "2023-09-07T00:36:37.192987Z",
            "url": "https://files.pythonhosted.org/packages/00/76/48d3eaada0492dfd7629a228fdd2d0eb0f2d2df1018a2218dae3da05c5ef/taskr_cli-1.2.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-09-07 00:36:37",
    "github": false,
    "gitlab": true,
    "bitbucket": false,
    "codeberg": false,
    "gitlab_user": "peasleyk",
    "gitlab_project": "taskr",
    "lcname": "taskr-cli"
}
        
Elapsed time: 0.11531s