How to prevent version skew between the example app and `gome-assistant` itself
When working on the current version of gome-assistant, I noticed that the example app didn't compile. #35 fixes the problems that I encountered. But one of the problems was that the version of gome-assistant required by the example app was out of sync with the version of the library being shipped and also with the code in the example app. This problem will recur if we don't find a way to keep them in sync systematically.
The most convenient way, at least when developing, would be for the example app to always build using the version of gome-assistant that it ships with. That would prevent its go.mod from getting out of sync again in the future, and also make it easy to test that it builds with a version of gome-assistant that hasn't been released yet. Ensuring that the example app still compiles would also provide a slight regression test against unintended backwards-incompatible changes to the library.
However, the example app is not only interesting for gome-assistant devs but also for library users. They are more likely to want a tiny app that they can copy into their own repository and tweak to get it to work in their own setup. Anything that depends on requiring the example app to be embedded in the gome-assistant project tree will make life less convenient for those users.
Brainstorming some ways to keep the two in sync:
-
The example app could be made part of the
gome-assistantmodule, for example by moving it tocmd/exampleand removing itsgo.modandgo.sumfiles. This would add a few dependencies to the main project, but would also prevent gratuitous skew that currently exists between versions of other dependencies required by the main project vs. the example app:$ git diff --no-index -U0 <(sort go.mod | sed -nE -e 's| // indirect$||' -e 's|^\t(.*)$|\1|p') <(sort example/go.mod | sed -nE -e 's| // indirect$||' -e 's|^\t(.*)$|\1|p') | grep '^[-+][^-+]' | sort --stable -k 1.2,1 -k1.1,1.2r +github.com/golang-cz/devslog v0.0.8 -github.com/golang-module/carbon v1.7.1 +github.com/golang-module/carbon v1.7.3 -github.com/joho/godotenv v1.4.0 +github.com/joho/godotenv v1.5.1 -github.com/rogpeppe/go-internal v1.9.0 +github.com/rogpeppe/go-internal v1.11.0 -github.com/stretchr/objx v0.5.0 +golang.org/x/mod v0.9.0 +saml.dev/gome-assistant v0.6.0On the other hand, this would be it a bit harder for a user to copy the
exampledirectory and use it as the starting point for their own app. -
The example app's
go.modcould use areplacedirective to cause it to use thesaml-dev/gome-assistantthat is located in its parent directory:index 6973a7a..42b3204 100644 --- a/example/go.mod +++ b/example/go.mod @@ -22,3 +22,5 @@ require ( github.com/rogpeppe/go-internal v1.11.0 // indirect golang.org/x/mod v0.9.0 // indirect ) + +replace saml.dev/gome-assistant => ..But this would also make it a bit harder to copy the
exampledirectory and use it as the starting point for one's own app. -
The
README.mdcould include instructions for setting up ago.workfile locally containing similarreplacedirective, and encourage devs to use that. However, I find the use of workspaces somewhat confusing, and ran into a lot of dependency friction when I tried this. I guess that it also makes it possible forexample/go.sumto get out of sync with the top-levelgo.sum. -
We could create a test suite that checks that
examplebuilds, and encourage devs to run the test suite while working, and/or set up GitHub actions to run the build test automatically against PRs. But this still doesn't prevent version drift, including the risk that the "current" example app doesn't compile against thegome-assistantin the corresponding commit. -
We could add an automated test that the example app's
go.moddepends on the corresponding version ofgome-assistant. But this is awkward to determine, as it depends on the presence/absence of upstream tags, plus it doesn't allow compiling the example app against non-released versions ofgome-assistant.
All in all, my personal opinion is that the least-bad option is (1), ideally combined with automated tests that all components compile (including cmd/generate).
Or maybe this is all overengineering, and we shouldn't worry about the problem.