Tackle box is a declarative DSL for building modular workflows and code generators. Tool is plugins based and can easily be extended by writing additional hooks or importing external providers creating a web of interoperable CLIs.
Project description
Tackle
- Documentation
- Discord - wip
- Slack - wip
- PyPI
- BSD License
Tackle is a language for building modular code generators and declarative CLIs. It can make any config file dynamic with both strong and weakly typed programmable flow control common to a general purpose programming language. Basically you can write a fully functional CLI and Turing-complete program in yaml. It's wild.
Warning: Tool is in it's very early phases and only now considered stable enough to use. It may never reach 1.x version as, if it gets enough stars, it will be converted to a spec and re-written in rust (ie give it a star if you'd like to see that).
Install
Note: tackle can install dependencies on its own. Check docs for advanced installation methods to isolate tackle from your system python.
python -m venv env && source env/bin/activate
pip install tackle-box
Hello world
To call tackle, create a yaml file and run tackle hello-world.yaml
.
Simply use the print hook.
hw->: print Hello world!
Which using jinja templating can be called in four different ways.
words: Hello world!
expanded:
->: print
objects: "{{words}}"
compact->: print {{words}}
jinja_extension->: "{{ print(words) }}"
jinja_filter->: "{{ words | print }}"
And can also have interactive prompt hooks.
name->: input
target:
->: select Say hi to who?
choices:
- world
- universe
hello->: print My name is {{name}}. Hello {{target}}!
Hooks can have loops, conditionals, and other base methods.
words:
- Hello
- cruel
- world!
expanded:
->: print {{item}}
for: words
if: item != 'cruel'
compact->: print {{item}} --for words --if "item != 'cruel'"
Hooks can be written in python.
from tackle import BaseHook
class Greeter(BaseHook):
hook_type: str = "greeter"
target: str
args: list = ['target']
def exec(self):
print(f"Hello {self.target}")
Or new hooks can be declaratively created with tackle.
greeter<-:
target: str
args: ['target']
exec:
hi->: print Hello {{target}}
And both can be called in the same way.
hello: world!
compact->: greeter {{hello}}
expanded:
->: greeter
target: "{{hello}}"
jinja_extension->: "{{ greeter(hello) }}"
jinja_filter->: "{{ hello | greeter }}"
Declarative hooks are strongly typed objects with many declarative fields.
words<-:
hi:
type: str
regex: ^(Bonjour|Hola|Hello)
target: str
p->: print {{item}} --for values(words(hi="Hello",target="world!"))
Which can have methods that extend the base.
words<-:
hi: Wadup
say<-:
target: str
exec:
p->: print {{hi}} {{target}}
p->: words.say --hi Hello --target world!
And also support inheritance.
base<-:
hi:
default: Hello
words<-:
extends: base
say<-:
target: str
exec:
p->: print {{hi}} {{target}}
p->: words.say --target world!
And will later support extending common schemas like OpenAPI, protobuf, and json schema
Hooks and fields can have documentation embedded in them.
greeter<-:
help: Something that greets
hi:
default: Yo
description: Initial greeting.
target:
type: str
description: Thing to greet.
exec:
p->: print {{hi}} {{target}}
That [will] drive a
help
screen by runningtackle hello-world.yaml --help
-> Coming soon
And last, everything can be imported / called remotely from github repos.
import-hello_>: import robcxyz/tackle-hello-world
call->: greeter world!
# Or
local-call->: tackle hello-world.yaml
remote-call->: tackle robcxyz/tackle-hello-world --version v0.1.0
Creating a web of declarative CLIs.
Use Cases
- Code Generation
- Declarative Utilities - wip
- Kubernetes Manifest Management - wip
- Toolchain Management - wip
- Repo Management - wip
- Home - wip
Topics
- Writing Tackle Files - wip
- Creating Providers
- Blocks and Flow Control - wip
- Memory Management
- Declarative Hooks
- Declarative CLIs - wip
- Special Variables - wip
Roadmap
- Declarative schemas
- json schema
- openapi
- protobuf
- Cached providers
- State management
Contributing
Contributions welcome particularly for additional hooks and suggestions around their interfaces. If contributing to the core parser, please make sure any changes are non-breaking by running tests (make test
). For writing providers / hooks, please make sure to use the testing conventions laid out in the existing providers whereby the test uses pytest fixtures to change the directory into the test's directory. This is so the tests can be run from both the root of the project and from within the test directory to facilitate debugging.
Code of Conduct
Everyone interacting in the tackle-box project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the PyPA Code of Conduct.
Credit
Special thanks to the cookiecutter community for laying the basis for this project.
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.3.0b5-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8450593ea7015c1360db7725e1d37ede6a8802ec63c4f119927dec30b4c8855b |
|
MD5 | 70676edab0f2b93dbe349edf4b29e7b9 |
|
BLAKE2b-256 | ce36afa894897ad98d1b0ea82d2484db511d594524662a002b00f59e3bea22e4 |