You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
Ever wanted to have confidence that your shell programs would stay modular and componentized, even as they grow?
Ever wanted to add a plugin framework to your shell script, while keeping it simple?
Ever wanted to indulge your functional-programming side, even when writing code for OS-level automation?
Now you can!
Installation
Install into yourPATH. Do not set the execute bit; instead, use thesource builtin to incorporate the library's functions into your script.
Usage
Break your script down into small functions. Before each function, use aprovides line to list the variables or functionality provided by that function; inside each function, use aneeds line to list the variables which need to be evaluated before invocation.
#!/bin/bash# ^^^^ important! /bin/sh scripts are NOT SUPPORTEDsource declarative.bash # load the libraryis_not_empty() { [[ ${!1} ]]; } # define any assertionsdeclare_assertions varA varB -- is_not_empty # declare which variables your # ...assertions apply to.provides function_name varA varB # declare variables each function setsfunction_name() { declare -g varA varB # ..declare those as globals needs varC varD # ..and declare which variables you consume # ... put your logic here ...}
Some points to note:
While usage forprovides andneeds suggests using variable names for dependency names, and the provided leak checker whitelists any dependency names as global variables, it is not necessary to do so. For instance, anything which describes itself as providing tests could be invoked by aneeds tests call, even if notests variable exists.
More than one function can define itself as providing the same feature / setting the same variable. If this is the case, all defined setters will be invoked by a relatedneeds call. A suggested use case for this is to allow "plugins" sourced in from configuration files to be run in addition to built-in functions.
Loops are silently broken. IfA->B->C->A, theC->A link will be discarded.
IfDECLARATIVE_TEST_LEAKS is set, any variables leaked into global scope by functions invoked vianeeds will be detected and reported. This is important, as all variables are global in bash unless explicitly declared otherwise;local ordeclare (without-g) must be used to prevent this behavior).
If you make assertions about variables, these assertions will be checked after each function which declares that it writes to those variables. Be aware of the caveat this implies -- if multiple functions are used to build up a single variable, assertions will be enforced after each of them.
Requirements
bash 4.1 or newer.
About
A simple framework for writing declarative shell scripts