Declarative DSL for creating workflows, CLIs, and generating code. Extends cookiecutter templates with modules, loops, conditionals, and plugins to perform a wide array of actions.
Project description
Tackle Box
- Tackle Box Documentation: https://robcxyz.github.io/tackle-box
- GitHub: https://github.com/robcxyz/tackle-box
- PyPI: https://pypi.org/project/tackle-box/
- Free and open source software: BSD license
Tackle box is a DSL for easily creating CLIs, workflows, and generating code from templates. The framework is modular and empowered by a collection of hooks to easily extend functionality. Based off a fork of cookiecutter, this tool evolved from being a code generator to connecting git repositories into a web of CLIs.
Quick Demo
pip3 install tackle-box
tackle https://github.com/robcxyz/tackle-demos
Features
All cookiecutter features are supported in addition to loops, conditionals, and plugins. These features are only available to supplied dictionary objects with a type
key to trigger the associated hook. Loops and conditionals are triggered by rendering jinja expressions per the example below. Other cookiecutters can be called from a single tackle box to knit together modularized components.
tackle.yaml
---
name:
type: input # Input prompt which is stored in `name`
message: What is your name?
colors:
type: checkbox # Multi selector - returns a list
message: What are your favorite colors?
choices:
- blue
- green
- grey
outcome:
type: select # Single selector - returns a string
message: What is the airspeed velocity of an unladen swallow??
choices:
- flung-off-bridge: I donno # Map for choices interpretted as {key: question}
- walk-across-bridge: What do you mean? African or European swallow?
bad_outcome:
type: print
statement: Wrong answer {{ name }}... # Render the `name` variable
when: "{{ outcome == 'flung-off-bridge' }}" # Conditionals need to evaluate as booleans
color_essays:
type: input
message: Please tell me how much you like the color {{item}}?
default: Oh color {{item}}, you are so frickin cool...
loop: "{{ colors }}" # loops over colors
when: "{{ colors|length > 1 }}"
democmd:
type: command # Run arbitrary system commands and return stdout
command: pwd
output:
type: pprint # Pretty print the output
output: "{{ this }}" # Special var that contains a dictionary of all the value
Each hook is called via its type
which, in the case of the input
hook, can be looked up in the docs or by looking at the source code directly.
Prompts are enhanced by extending the functionality from PyInquirer as a set of hooks as noted by the types input
, select
, and checkbox
. Writing new hooks is super simple as seen in the print
hook:
Hooks and Providers
cookiecuttuer/providers/hooks/print.py
from tackle.models import BaseHook
from typing import Union
class PrintOperator(BaseHook):
type: str = 'print'
out: Union[dict, list, str] = None
def execute(self):
print(self.out)
return self.out
Hooks are built with pydantic by inheriting from the BaseHook that makes a number of useful methods and attributes available.
Base Methods
A number of useful methods are available when executing any hook. Here is a breif example of all of them being used.
this:
type: a_hook
chdir: /path/to/some/dir # Changes to the dir before executing
loop: # Expects a list, creates `item` and `index` variables in loop
- foo
- bar
when: "{{ item == 'foo' }}" # Jinja expression that evaluates to boolean
merge: True # Merge the outputs to the upper level context
For further documentation on base methods, see check out the docs.
Providers
Providers are groups of hooks and templates to
Hooks
Around 50 different hooks are currently available with more coming down the line. To understand how to use them, please refer to the API Docs.
The main type of operators are derivations of PyInquirer which greatly enhanced the capabilities of the original cookiecutter due to the ability to use multi-select inputs that return lists. Please inspect the PyInquirer API docs to understand the interface. All features are supported except for validation
and filter
which is not supported and when
which is implemented in jinja.
To see a number of good examples of the types of interfaces available for each operator, consider downloading the demo above and walking through the syntax.
Note to Users and Developers
This is a very early WIP but has long term ambitions of being a sort of swiss army knife for management of configuration files and boilerplate. Please consider contributing or leaving your comments in the issues section on where you see this project going and what features you would like added.
This project intends on being an edge release of cookiecutter
and would not have been possible were it not for the orginal maintainers of that repository. Development in this repository is meant to be a proving ground for features that could be implemented and merged into the original cookiecutter
repository. Please consider supporting both projects.
Windows will not have first class support. Several operators are built for POSIX systems. PRs welcome to build in full support. Basic features like PyInquirer style prompts are supported.
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 Distribution
Built Distribution
Hashes for tackle_box-0.1.0a1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cb7e0e2e6bad7b639bd7636ea1097d8f33846ea95173ca5c5c20b15824fb6e62 |
|
MD5 | 13d81346c42c2294b41e51c7d8b3f172 |
|
BLAKE2b-256 | 5428618cd708b22d8f94f3b22932bb3e8554ce0bac82704e938e20a1306747cb |