From 0551c8816ac7bc5bc10f9e20bb779db3d242139a Mon Sep 17 00:00:00 2001 From: Shulhan Date: Mon, 19 Jan 2026 04:13:33 +0700 Subject: journal/2026: new journal "Go workspace edge cases" The work flow using go.work is broken. So, lets remove the go.work and use the replace directive. --- .../2026/go_workspace_edge_cases/index.adoc | 141 +++++++++++++++++++++ _content/journal/2026/index.adoc | 2 + go.work | 21 --- go.work.sum | 36 ------ go.work.sum.license | 2 - 5 files changed, 143 insertions(+), 59 deletions(-) create mode 100644 _content/journal/2026/go_workspace_edge_cases/index.adoc delete mode 100644 go.work delete mode 100644 go.work.sum delete mode 100644 go.work.sum.license diff --git a/_content/journal/2026/go_workspace_edge_cases/index.adoc b/_content/journal/2026/go_workspace_edge_cases/index.adoc new file mode 100644 index 0000000..63f6735 --- /dev/null +++ b/_content/journal/2026/go_workspace_edge_cases/index.adoc @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: CC-BY-SA-4.0 +// SPDX-FileCopyrightText: 2026 M. Shulhan + += Go workspace edge cases +:toc: +:sectanchors: + +This journal contain log of edge cases that I found while using +https://go.dev/ref/mod#workspaces[Go workspace^]. + +== Shared dependency + +I have module `A` than depends on module `B` and `C`, with module `B` also +depends on `C`. + +---- +A -> C +A -> B +B -> C +---- + +There is a bug in module `A` that caused by `C`, but not affected on `B`. +This bug require fixing and breaking changes on function `F` on `C`. +Let say the function signature of `F` changes from + +---- +package C + +func F() (*Node) +---- + +to + +---- +package C + +func F() (*Node, int) +---- + +I fix it and then run build again on module `A`. +Since function `F` also used in module `B`, the build failed. +I switch to module `B`, do update as required, and switch back to module `A. + +Now `A` is buildable and pass all tests. + +I push module `C` with fix, pick up the git hash and run "go get -u C@hash" +inside module `A`, run `go mod tidy`, commit the changes, and push it. + +Turns out the module `A` failed to build on my CI: +---- +webhook_karajo: ==> Starting build()... +webhook_karajo: go run ./internal/cmd/karajo-build embed +webhook_karajo: # git.sr.ht/~shulhan/ciigo +/build/go/pkg/mod/git.sr.ht/~shulhan/ciigo@v0.15.3/server.go:56:24: \ + cannot use ciigo.onGet (value of type + func(node *memfs.Node, _ "net/http".ResponseWriter, req *"net/http".Request) (out *memfs.Node)) + as "git.sr.ht/~shulhan/pakakeh.go/lib/http".FSHandler value in assignment +webhook_karajo: make: *** [Makefile:18: memfs_www.go] Error 1 +---- + +This is correct behaviour of Go modules, according to +https://research.swtch.com/vgo-mvs[Minimal Version Selection]. +Since module `A` use the latest release of module `C`, it is also used when +building `B`. +Because I forgot to push the fix on module `B` and incorporate it on module +`A`, the module `A` fail to build on non-go workspace directory. + +The problem is in my local the build run successfully because the `go.work` +file use the local, non-released version of `B`. +This human error work flow is not handled when using Go workspace. + +In the non-workspace flow, I can use "replace" directive as an indicator in +go.mod that said "some dependencies is still in progress and must be fixed +and released before we can release this module". +Now, this mental model is gone. + + +== The same module inside module + +Still in the same repository (module) of `A`. + +I have packaging script in the same repository of `A`, that clone the +repository `A` itself inside directory `_AUR/src`. + +---- +. +├── _AUR +│   ├── karajo-git +│   │   ├── branches +│   │   ├── hooks +│   │   ├── info +│   │   ├── objects +│   │   └── refs +│   ├── pkg +│   │   └── karajo-git +│   └── src +│   └── karajo-git # <-- git clone of the same module. +... +---- + +Building the _AUR package result in the following error, + +---- +$ makepkg +... +==> Starting build()... +go run ./internal/cmd/karajo-build embed +main module (git.sr.ht/~shulhan/kilabit.info) does not contain package +git.sr.ht/~shulhan/kilabit.info/_project/src/karajo/_AUR/src/karajo-git/internal/cmd/karajo-build +make: *** [Makefile:18: memfs_www.go] Error 1 +==> ERROR: A failure occurred in build(). + Aborting... +---- + +NOTE: Main module (git.sr.ht/~shulhan/kilabit.info) is where I put the +`go.work` file. + +I then add the `/_project/src/karajo/_AUR/src/karajo-git/` into go +workspace. +Then re-run the `makepkg` command again. + +---- +$ makepkg +... +==> Starting build()... +go run ./internal/cmd/karajo-build embed +go: module git.sr.ht/~shulhan/karajo appears multiple times in workspace +make: *** [Makefile:18: memfs_www.go] Error 1 +==> ERROR: A failure occurred in build(). +---- + +It now give different error messages. + +To fix this we need to set the `GOWORK` environment variable to `off` before +running command that use Go tools: + +---- +$ GOWORK=off makepkg +---- + +This kind of error will never happen on non-workspace work flow. diff --git a/_content/journal/2026/index.adoc b/_content/journal/2026/index.adoc index 3f0c5cd..f898e0e 100644 --- a/_content/journal/2026/index.adoc +++ b/_content/journal/2026/index.adoc @@ -6,3 +6,5 @@ link:/journal/2026/go_gitignore/[Gitignore package for Go]. My thoughts when implementing gitignore parser and checker for Go programming language. + +link:/journal/2026/go_workspace_edge_cases/[Go workspace edge cases]. diff --git a/go.work b/go.work deleted file mode 100644 index a2fdf1c..0000000 --- a/go.work +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// SPDX-FileCopyrightText: 2026 M. Shulhan - -go 1.24.0 - -use ( - . - ./_project/src/asciidoctor-go - ./_project/src/awwan - ./_project/src/ciigo - ./_project/src/gorankusu - ./_project/src/gotp - ./_project/src/haminer - ./_project/src/jarink - ./_project/src/karajo - ./_project/src/lilin - ./_project/src/pakakeh.go - ./_project/src/pakakeh.go/lib/play/testdata/unsafe_run - ./_project/src/rescached - ./_project/src/spdxconv -) diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index 32d4198..0000000 --- a/go.work.sum +++ /dev/null @@ -1,36 +0,0 @@ -git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/alecthomas/jsonschema v0.0.0-20220216202328-9eeeec9d044b/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/dgryski/go-lttb v0.0.0-20230207170358-f8fc36cdbff1/go.mod h1:UwftcHUI/qTYvLAxrWmANuRckf8+08O3C3hwStvkhDU= -github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= -github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.53.1/go.mod h1:RZDkzs+ShMBDkAPQkLEaLBXpjmDcjhNxU2drUVPgKUU= -github.com/tsenart/go-tsz v0.0.0-20180814235614-0bd30b3df1c3/go.mod h1:SWZznP1z5Ki7hDT2ioqiFKEse8K9tU2OUvaRI0NeGQo= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= -golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= -gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/go.work.sum.license b/go.work.sum.license deleted file mode 100644 index 16f7767..0000000 --- a/go.work.sum.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: M. Shulhan -- cgit v1.3