gokrazy / tools

this repository contains the gok CLI tool of gokrazy
https://gokrazy.org
BSD 3-Clause "New" or "Revised" License
50 stars 26 forks source link

packer should use separate go.mod files for different packages #38

Open stapelberg opened 1 year ago

stapelberg commented 1 year ago

Creating this issue for discussion / reporting issues with this change.

mhofstetter commented 1 year ago

Hi @stapelberg

Even though I understand and welcome the idea behind these changes - I'd like to share my thoughts and experience with it.

At first I realised these changes when trying to update a GoKrazy package of my GoKrazy instance. Before updating the version of the package, I already executed a remote deployment (via -update) with the old state to ensure that everything was still working as expected. This also created this new builddir directory with the copies of the go.mod files from the root. I wasn't paying that much attention to this folder - not before I realised that my following remote deployments with the updated GoKrazy package version in the root go.mod are still deployed with the old versions - of course due to the fact that now my root go.mod file with the updated versions isn't of any interest for gokr-packer.

My solution was to delete the root go.mod as this is no longer necessary (because new packages wouldn't need this as a starting point anyway) - and cleanup & manage the GoKrazy package versions of my instance in the go.mod files in the corresponding builddir subdirectory (also having them under version control).

I'm aware that this aproach of having this instance directory for each GoKrazy instance is only one use case how gokr-packer can be used. There's also the use case of packaging the GoKrazy instance directly from the workspace of a package itself - as you do with router7 which is often mentioned in the comments of your changes related to this builddir changes.

From the perspective of the instance directory use case (which is also the way how it's documented in the userguide quickstart) I have some questions & thoughts:

Naming

Why is this directory called builddir and not something like packages or modules? IMO builddir indicates that it's something temporary which gets overwritten by gokr-packer on every run (which it doesn't) and which doesn't need to be under version control.

The current naming might feel right for the "router7" use case but maybe isn't ideal for the instance directory one.

An alternative workaround would be to keep the root go.mod file and treat the builddir as temporary directory by deleting it before each deplolyment - but this is against the whole idea of this change of having the possibility to have different go.mod files for each package.

Combine with flags & env

Now having three directories (builddir, flags & env) with the directory structure of the packages, it might be worth a thought of merging them under the builddir (-> packages?) directory - of course in a backwards compatible way of still respecting the old directories for some time.

Migration

From a user perspective, copying the root go.mod into the builddir subdirectories is a migration. Probably gokr-packer should threat it like this and output this to the user - maybe even with the possibility to delete root go.mod afterwards to prevent missunderstandings like mine in the first place. But again, this might differ between the use cases.

Flag for use cases

All mentioned aspects feel right or wrong depending on these two main use cases of how to use gokr-packer. They might not even be all I'm aware of :) Would it make sense to introduce a flag for the second (router7 etc) use case where someone isn't building from within a "instance directory".

It might would help in handling the mentioned aspects - whether it's naming, flags & envs or the migration part.

Documentation

This needs to be documented in the userguide :D I guess somewhere around https://gokrazy.org/development/modules/. I would even propose to bring this topic in general a little bit closer to the quickstart section. It's not really about how to develop a package, rather than how to package & deploy a GoKrazy instance.


I hope this helps to see into the head of one happy GoKrazy user :D Thanks!

stapelberg commented 1 year ago

Hey, thanks for the feedback!

I wasn't paying that much attention to this folder - not before I realised that my following remote deployments with the updated GoKrazy package version in the root go.mod are still deployed with the old versions - of course due to the fact that now my root go.mod file with the updated versions isn't of any interest for gokr-packer.

Right, you’ll need to update the individual respective go.mod files. The root go.mod file is still used when you add new packages, though.

My solution was to delete the root go.mod as this is no longer necessary (because new packages wouldn't need this as a starting point anyway)

If you have replace directives in there that you want to apply to future new packages, too, it can still make sense to use this as a starting point.

I'm aware that this aproach of having this instance directory for each GoKrazy instance is only one use case how gokr-packer can be used. There's also the use case of packaging the GoKrazy instance directly from the workspace of a package itself - as you do with router7 which is often mentioned in the comments of your changes related to this builddir changes.

I actually no longer do that in router7 (all my gokrazy deployments are now instance directories, and that is the single recommended way going forward), and being able to separate the project directory from the instance directory was one of the motivations for this whole change.

Why is this directory called builddir and not something like packages or modules? IMO builddir indicates that it's something temporary which gets overwritten by gokr-packer on every run (which it doesn't) and which doesn't need to be under version control.

The directory is named builddir because it’s the directory that’s used when building — the packer is literally running go build, and now it runs go build from that directory. gokrazy always operates on packages, so calling the directory packages is not very descriptive either. I don’t have the association that builddir sounds temporary, but I can understand that you do.

Renaming the directory will cause extra churn / confusion, so I’d rather avoid a rename.

An alternative workaround would be to keep the root go.mod file and treat the builddir as temporary directory by deleting it before each deplolyment - but this is against the whole idea of this change of having the possibility to have different go.mod files for each package.

Exactly — I considered making the builddir temporary originally and even had a prototype that worked like that, but discarded it quickly. To achieve the goal of different dependency versions in different packages, you’d need to strip require directives from the file and let the go tool re-resolve, which is slow and not reproducible. Managing replace directives would still need to happen in the root go.mod file, which makes it awkward / convoluted. Also, having temporary files that the user can’t see or work with (e.g. with the gopls LSP support of your editor) isn’t very transparent.

Now having three directories (builddir, flags & env) with the directory structure of the packages, it might be worth a thought of merging them under the builddir (-> packages?) directory - of course in a backwards compatible way of still respecting the old directories for some time.

Yes, I know. I’m actually looking into a more unified structure for this as we speak, so stay tuned :)

From a user perspective, copying the root go.mod into the builddir subdirectories is a migration. Probably gokr-packer should threat it like this and output this to the user - maybe even with the possibility to delete root go.mod afterwards to prevent missunderstandings like mine in the first place. But again, this might differ between the use cases.

Yeah, we could probably make this process more explicit via better log messages.

This needs to be documented in the userguide :D I guess somewhere around https://gokrazy.org/development/modules/. I would even propose to bring this topic in general a little bit closer to the quickstart section. It's not really about how to develop a package, rather than how to package & deploy a GoKrazy instance.

Yep, agreed that we should update the documentation. I wanted to give this change a little time to bake, but you’re right that we’re currently not doing a good job of explaining the new way. I’ll try to come back to this over the next few days.

mhofstetter commented 1 year ago

Thank you very much for your answers and insights!

I actually no longer do that in router7 (all my gokrazy deployments are now instance directories, and that is the single recommended way going forward), and being able to separate the project directory from the instance directory was one of the motivations for this whole change.

Good to hear that :)

Yes, I know. I’m actually looking into a more unified structure for this as we speak, so stay tuned :)

Curious what's the idea on this side :) Maybe even something into the direction of a declarative definition of the GoKrazy instance deployment?

Sometimes i wish that one could define the "packages" and all their config (flags, envvars, ...) - and the other relevant flags of gokr-packer in a "config file". To get rid of the long argument list when executing gokr-packer :)

stapelberg commented 1 year ago

Curious what's the idea on this side :) Maybe even something into the direction of a declarative definition of the GoKrazy instance deployment?

Sometimes i wish that one could define the "packages" and all their config (flags, envvars, ...) - and the other relevant flags of gokr-packer in a "config file". To get rid of the long argument list when executing gokr-packer :)

Yep, that’s pretty much it! See https://github.com/gokrazy/gokrazy/issues/147 for more details, and comment over there in case you have any feedback. Thanks :)

stapelberg commented 1 year ago

https://gokrazy.org/quickstart/ and https://gokrazy.org/development/modules/ are now updated :)