75 lines
3.0 KiB
Markdown
75 lines
3.0 KiB
Markdown
|
|
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
|