Files
blackbox/DESIGN.md

75 lines
3.0 KiB
Markdown
Raw Permalink Normal View History

BlackBox Internals
==================
The goal of the Go rewrite is to improve the usability and
maintainability of Blackbox, meanwhile make it easier to implement new
The system is built in distinct layers: view, controller, model.
Suppose there is a subcommand "`foo`". `blackbox.go` parses the
user's command line args and calls `cmdFoo()`, which is given
everything it needs to do the operation. For example, it is given the
filenames the user specified exactly; even if an empty list means "all
files", at this layer the empty list is passed to the function.
`cmdFoo()` contains the business logic of how the operation should be
done: usually iterating over filenames and calling verb(s) for each
one. For example if an empty file list means "all files", this is the
layer that enumerates the files.
`cmdFoo()` is implemented in the file `cmd_foo.go`. The caller of
`cmdFoo()` should provide all data it needs to get the job done.
`cmdFoo()` doesn't refer to global flags, they are passed to the
function as parameters. Therefore the function has zero side-effects
(except possibly logging) and can be called as library functions by
other systems. This is the external (binary) API which should be
relatively stable.
`cmdFoo()` calls verbs that are in `bbutil/`. Some of those verbs are
actually interfaces. For example, any VCS-related verbs are actually a
Go interface which might be implemented one of many ways (Git,
Subversion, Mercurial), GPG-functions may be implemented by shelling
out to `gpg.exe` or by using Go's gpg library.
They layers look like this:
| View | `blackbox.go` | Parses User Commands, calls controller |
| Controller | `cmd_*.go` | The business logic. Iterates and calls verbs |
| Model | `pkg/bbutil` | Verbs |
| Interfaces | `pkg/*` | Interfaces and their implementations |
At least that's the goal. We'll see how well we can achieve this.
Version 2.0
===========
Software architecture.
We try to keep the command-line parsing separate from the business
logic and all plug-ins. This keeps things clean and easy to refactor.
In fact layer 2 could be used as a stand-alone module for projects
that want to embed blackbox actions.
Layer 1: The command itself
* cmd/blackbox/blackbox.go -- main() not much more
* cmd/blackbox/cli.go -- Set up and call the ufave/cli flag parser
* cmd/blackbox/drive.go -- Check # of arguments, conflicting flags, and then call the businss logic layer
Layer 2: The business logic
* pkg/box/box.go -- The interface to accessing .blackbox (admins, files, etc.)
* pkg/box/verbs.go -- Verbs called by Layer 1. Just the verbs
* pkg/box/boxutils.go -- Functions needed by the verbs
Layer 3: The plug-ins
* pkg/vcs/... -- Plug-ins for Git, (Mercurial, Subversion, Perforce,) and None
* pkg/crypters/... -- Plug-ins for PGP access: GnuPG, (go-openpgp, others in the future)
Layer 4: Support functions for use by Layer 3
* pkg/bbutil/filestats.go -- File manipulations
* pkg/bbutil/runbash.go -- Safely run external Linux commands