github.com/joshdk/godel@v0.0.0-20170529232908-862138a45aee/docs/Architecture.md (about) 1 gödel consists of the `godelw` wrapper script, the project configuration files in `godel/config` and the `godel` Go 2 executable. 3 4 godelw 5 ------ 6 `godelw` is a bash script that is used as the entry point for gödel. The purpose of the script is to locate and invoke 7 the real `godel` executable and to provide it with the configuration specified in the current project. 8 9 If the executable exists at the expected location, it is invoked. The `godelw` script is built as part of the 10 distribution and embeds the checksum of the `godel` executable in its source and verifies that the checksum of the 11 executable it is invoking matches the checksum stored in its source. 12 13 If the executable does not exist, then the wrapper script gets the URL for the distribution from the 14 `godel/config/config.properties` file, downloads the distribution from that location (using `wget` or `curl`), verifies 15 the checksum of the downloaded distribution (if provided), expands the distribution into the expected location and then 16 invokes it. 17 18 This setup is used so that the `godel` executable itself does not need to be checked in as part of a project. 19 20 The `godelw` script invokes the `godel` executable with the `--wrapper` flag that provides the location of the invoking 21 wrapper script. This value is used by `godel` to determine the location from which the project configuration should be 22 loaded. All of the user-provided arguments to `godelw` are passed on directly to `godel`. 23 24 godel 25 ----- 26 `godel` is a single Go executable. It contains several Go libraries that use [`amalgomate`](https://github.com/palantir/amalgomate) 27 to combine disparate Go `main` programs into a single library. Thus, `godel` contains and can run as several disparate 28 Go programs such as `errcheck`, `go-junit-report` and others. 29 30 Many `godel` tasks act as an orchestrator of other sub-tasks. For example, the `check` command uses `okgo` to run 31 several different checks like `deadcode` and `errcheck`. The nifty thing is that, because `godel` embeds the 32 functionality of these programs and can run as them, the programs do not need to be separately installed. Instead, when 33 `godel` needs the functionality of one of these programs, it re-invokes itself as a sub-process with specific arguments 34 that instruct it to run as a specific sub-program. 35 36 This can be observed by manually invoking `godel` with special syntax: 37 38 ``` 39 ./godelw __check __errcheck --help 40 Usage of /Users/nmiyake/.godel/dists/godel-0.9.0/bin/darwin-amd64/godel: 41 -abspath 42 print absolute paths to files 43 -asserts 44 if true, check for ignored type assertion results 45 -blank 46 if true, check for errors assigned to blank identifier 47 -ignore value 48 comma-separated list of pairs of the form pkg:regex 49 the regex is used to ignore names within pkg (default "fmt:.*") 50 -ignorepkg string 51 comma-separated list of package paths to ignore 52 -ignoretests 53 if true, checking of _test.go files is disabled 54 -tags value 55 space-separated list of build tags to include 56 -verbose 57 produce more verbose logging 58 ``` 59 60 When `godel` is invoked with `__check __errcheck`, it runs in a manner that is identical to running the stand-alone 61 `errcheck` program. Thus, when `godel` needs the functionality of `errcheck`, it can invoke itself as a subprocess with 62 these arguments to get the functionality. 63 64 Package scope definition 65 ------------------------ 66 gödel defines global configuration that is used to specify the scope of the files that it should deal with. Projects 67 often have certain classes of files that should not be operated on by automated tooling (for example, the `vendor` 68 directory or generated source directories). The `godel/config/exclude.yml` file is used to define rules for excluding 69 certain paths from consideration. The `cfgcli` package is used so that all of the tasks (including those defined by 70 other stand-alone applications) can receive this configuration and thus operate on the same set of files. 71 72 Task encapsulation 73 ------------------ 74 gödel is composed of many independent tasks. Some of the simple tasks are implemented directly in the gödel project. 75 However, in order to prevent the project from becoming a single monolithic program, the large pieces of core 76 functionality are implemented as independent sub-programs that also expose their functionality as a library. For 77 example, `distgo` handles building products, creating distributions and running publish operations, while `okgo` handles 78 running all of the code checks. 79 80 Most of the sub-programs define a configuration file from which its configuration is read. The configuration file 81 typically contains program-specific configuration and an `exclude` object that specifies files and directories that 82 should be excluded from consideration. 83 84 However, when run as part of `godel`, the `exclude` configuration is typically defined globally in `exclude.yml`. 85 Requiring every separate sub-program to copy the `exclude` block would be cumbersome and error-prone. In order to deal 86 with this, sub-programs also accept configuration as a JSON string provided by the `--json` flag and can either combine 87 the JSON configuration with the file-based one or override the file-based configuration using the values provided in the 88 JSON. The `github.com/palantir/pkg/cli/cfgcli` provides a common API to do this. 89 90 Task API 91 -------- 92 Tasks that are implemented as sub-programs use the `github.com/palantir/pkg/cli/cfgcli` package as an API to manage 93 configuration. Tasks should use declarative file-based configuration. Most tasks have a corresponding configuration file 94 in `godel/config` -- for example, the `check` task is configured using `godel/config/check.yml`, while the `distgo` 95 tasks (`build`, `dist`, `publish`, etc.) are configured using `godel/config/dist.yml`. 96 97 When a task is invoked using `godel`, `godel` configures the global variables in the `cfgcli` package to store the 98 proper values for the configuration file and JSON configuration for the task. The JSON configuration is populated with 99 the `exclude` contents specified in `godel/config/exclude.yml` so that sub-programs can use the global excludes.