Package: tackle
tackleDocumentationDiscordPyPIBSD LicenseTackle is an experimental general purpose configuration language for building modular code generators and declarative CLIs. Built as a fork ofcookiecutter, 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, you can build:Modular code generators / repo scaffolding tools that can be updated over timeInteractive glue code for infrastructure-as-code deployment strategiesGeneric utilities like SSH helpers and dotfile managersCombinations of all of the above and anything else you can think ofIf this project gets enough adoption / stars, it will be re-written in a compiled language, either Go or Rust. Give it a star if you'd like to see that.FeaturesMakes arbitrary yaml / json / tomldynamicEmbed loops, conditionals, and other custom logicSelf documenting CLI to call logicShips with a collection of over100 hooksthat act like plugins within your config filePrompt user for inputsGenerate code from templatesRead and writeyaml/toml/jsonfilesMake http callsRun arbitrary system commandsManipulate the contextRun other tackle filesModular design allows creating / importing new hooks easySupports bothpythonanddeclarativehooks which can be imported / called / defined in-line or within jinja templatesHooks can be composed of other hooks allowing complex objects to be validated and operated againstInstallNote: tackle can install dependencies on its own. Checkdocsfor advanced installation methods to isolate tackle from your system python.python-mvenvenv&&sourceenv/bin/activate
pipinstalltackleQuick Demo:tackle sudoblockio/tackle-hello-worldHello worldCheck out thedocsfor >10 hello worlds that demonstrate the various aspects of the syntax with the simplest one using theprinthook, one of>100 hooks.hello.yaml# Any time a key ends with `->`, we are calling a hookhw->:print Hello world!To run, calltackle hello.yaml. Can also beversion controlled->tackle sudoblockio/tackle-hello-world.Can also useloops, conditionals, and other base methods.hello.yamlthe:words:-Hello-cruel-world!one liner->:print {{item}} --for the.words --if "item != 'cruel'"multiple lines:->:printobjects:{{item}}for:-Hello-world!if:item != 'cruel'# Or combinations of the above with other methods like try/exceptNew hooks can bemade in pythonwhich under the hood is apydanticmodel..hooks/hello.pyfromtackleimportBaseHookclassGreeter(BaseHook):hook_type:str="greeter"target:strargs:list=['target']defexec(self):expression=f"Hello{self.target}"print(expression)returnexpressionOr can bedefined inline within your tackle file, imported remotely, or in ahooksdirectory...hooks/hello.yaml# Keys ending with `<-` mean we are creating a hook / methodgreeter<-:target:strargs:['target']exec<-:expression->:var Hello {{target}}# var hook renders variablesp->:print {{expression}}return:expressionAnd both can becalled the same way.tackle.yamlhello:world!With a flag->:greeter --target {{hello}}Target in argument->:greeter {{hello}}Expanded fields:->:greetertarget:{{hello}}Jinja template->:{{greeter(hello)}}# Or combinations jinja and compact / expanded hooks allowing chaining of hook calls.With the declarative hooks beingcallable from the command line:tacklehello.yamlgreeter--targetworld!# Or from a github repotacklesudoblockio/tackle-hello-worldgreeter--targetworld!Documentation can be embedded into the hooks.hello.yaml<-:help:This is the default hooktarget:type:union[str, int]default->:inputdescription:The thing to say hello toexec<-:greeting->:select Who to greet? --choices ['world',target]hi->:greeter --target {{greeting}}greeting-method<-:help:A method that greets# ... Greeting options / logicextends:greetergreeter<-:help:A reusable greeter objecttarget:strexec<-:hi->:print Hello {{target}}Which when runningtackle hello.yaml helpproduces 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 objectHooks can be importedwithin a tackle providerorthrough hooks,linked, and/or combined withinheritanceorcompositioncreating a web of CLIs.Use CasesCode GenerationWIP TutorialsDeclarative UtilitiesInfrastructure-as-Code ManagementKubernetes Manifest ManagementToolchain ManagementTopicsWriting Tackle FilesCreating ProvidersPython HooksDeclarative HooksBlocksandFlow ControlMemory ManagementSpecial VariablesDeclarative CLIsKnown IssuesWindows Supporttackle is lacking some windows support as shown in thefailed tests. If you are a windows user, it is highly recommended to use WSL.Please get in touchif you are motivated to fix these tests to make tackle fully cross-platform. It probably isn't that hard to fix them as they mostly are due to differences in how windows handles paths.Whitespacestackle relies heavily on parsing based on whitespaces which if you are not careful can easily bite you. Whenever you need to have some whitespaces preserved, make sure to quote the entire expression. Future work will be put in to overhaul theregex based parserwith a PEG parser likeparsimonious.ContributingContributions are welcome but please be advised of the following notes.This project usesconventional commitswhich generates thechangelogwithrelease-please-actionin thereleaseCI 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. It definitely can be improved but consistency is more important than making directed improvements. Tests should be runnable from the test's directory and viamake 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. 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 ConductEveryone interacting in the tackle project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow thePyPA Code of Conduct.CreditSpecial thanks to thecookiecuttercommunity for laying the basis for this project.