github.com/StackExchange/blackbox/v2@v2.0.1-0.20220331193400-d84e904973ab/DESIGN.md (about) 1 BlackBox Internals 2 ================== 3 4 The goal of the Go rewrite is to improve the usability and 5 maintainability of Blackbox, meanwhile make it easier to implement new 6 7 The system is built in distinct layers: view, controller, model. 8 9 Suppose there is a subcommand "`foo`". `blackbox.go` parses the 10 user's command line args and calls `cmdFoo()`, which is given 11 everything it needs to do the operation. For example, it is given the 12 filenames the user specified exactly; even if an empty list means "all 13 files", at this layer the empty list is passed to the function. 14 15 `cmdFoo()` contains the business logic of how the operation should be 16 done: usually iterating over filenames and calling verb(s) for each 17 one. For example if an empty file list means "all files", this is the 18 layer that enumerates the files. 19 20 `cmdFoo()` is implemented in the file `cmd_foo.go`. The caller of 21 `cmdFoo()` should provide all data it needs to get the job done. 22 `cmdFoo()` doesn't refer to global flags, they are passed to the 23 function as parameters. Therefore the function has zero side-effects 24 (except possibly logging) and can be called as library functions by 25 other systems. This is the external (binary) API which should be 26 relatively stable. 27 28 `cmdFoo()` calls verbs that are in `bbutil/`. Some of those verbs are 29 actually interfaces. For example, any VCS-related verbs are actually a 30 Go interface which might be implemented one of many ways (Git, 31 Subversion, Mercurial), GPG-functions may be implemented by shelling 32 out to `gpg.exe` or by using Go's gpg library. 33 34 They layers look like this: 35 36 | View | `blackbox.go` | Parses User Commands, calls controller | 37 | Controller | `cmd_*.go` | The business logic. Iterates and calls verbs | 38 | Model | `pkg/bbutil` | Verbs | 39 | Interfaces | `pkg/*` | Interfaces and their implementations | 40 41 At least that's the goal. We'll see how well we can achieve this. 42 43 44 Version 2.0 45 =========== 46 47 Software architecture. 48 49 We try to keep the command-line parsing separate from the business 50 logic and all plug-ins. This keeps things clean and easy to refactor. 51 In fact layer 2 could be used as a stand-alone module for projects 52 that want to embed blackbox actions. 53 54 Layer 1: The command itself 55 56 * cmd/blackbox/blackbox.go -- main() not much more 57 * cmd/blackbox/cli.go -- Set up and call the ufave/cli flag parser 58 * cmd/blackbox/drive.go -- Check # of arguments, conflicting flags, and then call the businss logic layer 59 60 Layer 2: The business logic 61 62 * pkg/box/box.go -- The interface to accessing .blackbox (admins, files, etc.) 63 * pkg/box/verbs.go -- Verbs called by Layer 1. Just the verbs 64 * pkg/box/boxutils.go -- Functions needed by the verbs 65 66 Layer 3: The plug-ins 67 68 * pkg/vcs/... -- Plug-ins for Git, (Mercurial, Subversion, Perforce,) and None 69 * pkg/crypters/... -- Plug-ins for PGP access: GnuPG, (go-openpgp, others in the future) 70 71 Layer 4: Support functions for use by Layer 3 72 73 * pkg/bbutil/filestats.go -- File manipulations 74 * pkg/bbutil/runbash.go -- Safely run external Linux commands