Skip to main content

tackle-box

pypi python codecov codeql Foresight Docs Foresight Docs Foresight Docs

Tackle-box is an experimental DSL for building modular code generators and declarative CLIs. Built as a fork of cookiecutter, it can make any config file into a CLI with both strong and weakly typed programmable flow control common to a general purpose programming language. Basically you can write a fully functional Turing-complete program out of a config file. It's wild.

With tackle-box, you can build:

  • Modular code generators / repo scaffolding tools that can be updated over time
  • Declarative makefile alternatives for advanced toolchain management
  • Interactive glue code for infrastructure-as-code deployment strategies
  • Generic utilities like SSH registries and dotfile managers
  • Combinations of all of the above and anything else you can think of

If this project gets enough adoption / stars, it will be re-written in a compiled language. Its current goal is defining the syntax which should remain stable after a rewrite.

Features

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

Quick Demo: tackle robcxyz/tackle-hello-world

Hello world

Check out the docs for >10 hello worlds that demonstrate the various aspects of the syntax with the simplest one using the print hook.

hello.yaml

# Any time a key ends with `->`, we are calling a hook
hw->: print Hello world!

To run, call tackle hello.yaml. Can also be version controlled -> tackle robcxyz/tackle-hello-world.

Can also use loops, conditionals, and other base methods.

hello.yaml

the:
  words:
    - Hello
    - cruel
    - world!
one liner->: print --for the.words --if "item != 'cruel'" {{item}}
multiple lines:
  ->: print
  for:
    - Hello
    - world!
# Or combinations of the above with other methods like try/except

New hooks can be made in python which under the hood is a pydantic model.

from tackle import BaseHook

class Greeter(BaseHook):
    hook_type: str = "greeter"
    target: str
    args: list = ['target']
    def exec(self):
      expression = f"Hello {self.target}"
      print(expression)
      return expression

Or can be defined inline within your tackle file..

# Keys ending with `<-` mean we are creating a hook / method
greeter<-:
  target: str
  args: ['target']
  exec<-:
    expression->: print Hello {{target}}
  return: expression

And both can be called in the same way.

hello: world!
With a flag->: greeter --target {{hello}}
Target in argument->: greeter {{hello}}
Expanded fields:
  ->: greeter
  target: {{hello}}
Jinja template->: {{ greeter(hello) }}
# Or combinations jinja and compact / expanded hooks allowing chaining of hook calls.  

With the declarative hooks being callable from the command line:

tackle hello.yaml --target world!
# Or from a github repo
tackle robcxyz/tackle-hello-world --checkout v0.1.0

Documentation can be embedded into the hooks.

<-:
  help: This is the default hook
  target:
    type: str
    default->: input
    description: The thing to say hello to
  exec<-:
    greeting->: select Who to greet? --choices ['world',target]
    hi->: greeter --target {{greeting}}
  greeting-method<-:
    help: A method that greets
    # ... Greeting options / logic
greeter<-:
  help: A reusable greeter object
  target: str
  exec<-:
    hi->: print Hello {{target}}

Which when running tackle hello.yaml help produces its own help screen.

usage: tackle hello.yaml [--target]

This is the default hook

options:
    --target [str] The thing to say hello to
methods:
    greeting-method     A method that greets
    greeter     A reusable greeter object

Hooks can be imported, linked, and/or combined creating a web of CLIs.

Use Cases

WIP Tutorials

Topics

Contributing

Contributions are welcome but please be advised of the following notes.

  • This project uses conventional commits which generates the changelog with release-please-action in the release CI workflow. If commits have been made outside of this convention they will be squashed accordingly.
  • For making changes to providers, please include test coverage using the existing fixtures and patterns from prior tests or communicate any suggestions that deviate from this style. Tests should be runnable from the test's directory and via make test.
  • For making changes to the core parser, please create a proposal first outlining your suggestions with examples before spending time working on code.

It is very easy to create new providers / hooks with tackle-box. Over time, it will adopt the same import pattern of what Ansible does where all provider / hooks (modules) are stored in version controlled locations. In the meantime, please feel free to contribute to this repository for hooks that have general applicability or create your own hooks in other repositories that are more bespoke / opinionated in nature.

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.

Metadata

Release files for tackle-box 0.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tackle-box 0.4.2
File Size Uploaded Provenance Actions
tackle-box-0.4.2.tar.gz 183.8 kB Without provenance Details for tackle-box-0.4.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tackle-box 0.4.2
File Interpreter ABI Platform Actions
tackle_box-0.4.2-py2.py3-none-any.whl Python 2, Python 3 none any Details for tackle_box-0.4.2-py2.py3-none-any.whl

Total release size: 437.9 kB

Release files / tackle-box-0.4.2.tar.gz

Download URL tackle-box-0.4.2.tar.gz
Size 183.8 kB
Tags Source
SHA-256 checksum
How to use checksums
cadec9d6d90adb3224451945f714ef016b02eae23f28c2b92a153d8ac94139f0
BLAKE2b-256 checksum
How to use checksums
a5855451ac0e18fb51ebf6564ef45bf775c640e577e03128b6c7f928a9a02a1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.7.15

Release files / tackle_box-0.4.2-py2.py3-none-any.whl

Download URL tackle_box-0.4.2-py2.py3-none-any.whl
Size 254.1 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
ce0e3b29962e6c17d5254dca657b080c6619b69b604c398dba8aa01feb49b628
BLAKE2b-256 checksum
How to use checksums
8d941d8c87d9792cce37a9f75f7b745fe40bc4b14d961cf575bd0ed6e87bc3e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.7.15

Security for tackle-box 0.4.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page