Skip to content

Latest commit

 

History

History
74 lines (53 loc) · 2.99 KB

DESIGN.md

File metadata and controls

74 lines (53 loc) · 2.99 KB

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