80 lines
3.4 KiB
Text
80 lines
3.4 KiB
Text
|
|
= 1: Go
|
||
|
|
:page-pagination: next
|
||
|
|
|
||
|
|
This is a minimal sample for Zilch's Go support, intended to show off the
|
||
|
|
ability to edit dependencies with ease, without losing the reproducibility that
|
||
|
|
Zilch provides.
|
||
|
|
|
||
|
|
To start, run `zilch-cli-go -m examples/go` and see the resulting binary
|
||
|
|
operate:
|
||
|
|
|
||
|
|
[,console]
|
||
|
|
----
|
||
|
|
$ zilch-cli-go -m examples/go
|
||
|
|
example.com/go /nix/store/wh1iaiplnkznh8x4rgqxs89qn90xaf3v-example.com_go
|
||
|
|
|
||
|
|
$ /nix/store/wh1iaiplnkznh8x4rgqxs89qn90xaf3v-example.com_go
|
||
|
|
1980-01-01T13:37:00.000Z INFO main/main.go:9 This is an example Go program. {"exampleString": "yes", "example": true}
|
||
|
|
----
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
If, say, you find a bug (e.g. you are of the opinion the line number should come
|
||
|
|
before the file name), this has to be patched in the logging module, which is
|
||
|
|
provided by zap. Clone the repo (`https://github.com/uber-go/zap`). In our case
|
||
|
|
we have it at `./zap`. To make sure the bug isn't patched in this current
|
||
|
|
version, let's first try building the example program again with it. This can be
|
||
|
|
done with the `--replace` command, or `-r` for short. This takes a directory
|
||
|
|
with a `go.mod`, and prioritizes it over the version of the Go module used in
|
||
|
|
the `go.mod` of the main module.
|
||
|
|
|
||
|
|
[,console]
|
||
|
|
----
|
||
|
|
$ zilch-cli-go -m examples/go -r zap
|
||
|
|
example.com/go /nix/store/75r8574ccq8vhsjyrr8jm9icdy5f19c1-example.com_go
|
||
|
|
|
||
|
|
$ /nix/store/75r8574ccq8vhsjyrr8jm9icdy5f19c1-example.com_go
|
||
|
|
1980-01-01T13:37:00.000Z INFO main/main.go:9 This is an example Go program. {"exampleString": "yes", "example": true}
|
||
|
|
----
|
||
|
|
|
||
|
|
Sadly, after updating, nothing changed. So we'll have to make changes. The
|
||
|
|
filename and line number are written in `zap/zapcore/entry.go`, around line 91;
|
||
|
|
inside `FullPath()`. After patching the function to swap them around, rerunning
|
||
|
|
the `zilch-cli-go` command shown previously will go through and recompile only
|
||
|
|
the changed files. So:
|
||
|
|
|
||
|
|
[,console]
|
||
|
|
----
|
||
|
|
$ zilch-cli-go -m examples/go -r zap
|
||
|
|
example.com/go /nix/store/vl6dd9d4ry7xhh31vpimjsn9khpqmxgb-example.com_go
|
||
|
|
|
||
|
|
$ /nix/store/vl6dd9d4ry7xhh31vpimjsn9khpqmxgb-example.com_go
|
||
|
|
1980-01-01T13:37:00.000Z INFO 9:main/main.go This is an example Go program. {"exampleString": "yes", "example": true}
|
||
|
|
----
|
||
|
|
|
||
|
|
As you can see, the bug is fixed, by testing with a project in a different repo!
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
Whenever you run `zilch-cli-go`, the script runs from scratch, not using any
|
||
|
|
previous information. It performs a series of steps to build a build graph:
|
||
|
|
|
||
|
|
First, it walks the `go.mod` of the main module, as well as all its
|
||
|
|
dependencies, using the `go.sum` as a guide to ensure this all stays content-
|
||
|
|
addressed, similar to the `go` tool. Once it has all the modules that are used
|
||
|
|
in the program, it looks for all packages inside each of the modules. Each
|
||
|
|
package is then analyzed for which other packages it imports, which is used to
|
||
|
|
build Zilch-native build information.
|
||
|
|
|
||
|
|
At this point, enough information has been gathered to build the resulting
|
||
|
|
build graph. The main package's derivation is materialized into the Nix store,
|
||
|
|
and with it, all its dependencies are pulled in. All its dependencies are built
|
||
|
|
with two outputs; both the native code and the API are separately stored. This
|
||
|
|
ensures that any changes that don't affect the interface that other packages
|
||
|
|
depend on do not cause a butterfly effect, and stay localized to the native
|
||
|
|
code.
|
||
|
|
|
||
|
|
At no point does Zilch run any of this code on the local system, either. All
|
||
|
|
builds and information gathering are done entirely inside the Nix daemon, which
|
||
|
|
provides for a stable and sandboxed environment.
|