design guidelines - mvaltas/grind GitHub Wiki
Here's a couple of notes on what are the concerns of grind
and how to think about then when extending it.
There's a clear distinction of grind
as a tool and its definitions. It is important to remember that grind
tries to be as agnostic of environment as possible. It can, eventually, configure other systems that can run bash.
The definitions, although being bash scripts too, should not attempt to provide more than just enough for installing and configuring a machine. Since definitions can target a specific machine, is safe to assume the system which this definition will run. But the same can't be said about global definitions.
This said, there's nothing wrong on having definitions tailored to a known set of systems and machines. Although there's an effort of not assuming much, it is not realistic to assume a complete generic solution from grind
.
API's such as Homebrew API are sort of recipes for (see: _brew) certain interfaces of configuration and installation. For some it is possible to map their code directly to the Core Definition API. But sometimes they can to a little more, like the Appdmg API.
API's should eventually refer to the core API, especially for do_run
and unless
calls. This is to guarantee that run only once, force and dry-run behaviors are kept.
There's a simple model of idempotency in grind
. grind
keeps a list of all commands ran and refuses to run the same command twice so that we prevent possible problems and/or redundant definitions. The model applies equally for run and checks, so do_run 'true'
and unless 'true'
are equivalent. A definition like:
do_run 'true'
unless 'false'
do_run 'false'
unless 'true'
Will produce:
$ grind run singles/test
>>>singles/test<<<
do_run: true
unless: false
[RUN]
do_run: false
unless: true
WARN: already ran: true
[SKIP]
Using force mode will make grind
ignore the idempotency model, with the same definition as above issuing --force
will result in:
$ grind run -f singles/test
force execution mode enabled
>>>singles/test<<<
do_run: true
unless: false
[FORCE]
[RUN]
do_run: false
unless: true
WARN: already ran: true
[FORCE]
WARN: already ran: false
[RUN]