Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gomod2nix: init at 1.5.0 #188272

Closed
wants to merge 2 commits into from
Closed

Conversation

adisbladis
Copy link
Member

@adisbladis adisbladis commented Aug 25, 2022

Description of changes

This adds gomod2nix, a generator for Nix expressions using Go modules (and the associated build infrastructure).
It has quite some differences to buildGoModule which are laid out in https://www.tweag.io/blog/2021-03-04-gomod2nix/.

I don't feel quite ready yet to promote buildGoApplication and mkGoEnv to first-class top-level attributes so in nixpkgs these will be accessed by gomod2nix.buildGoApplication & gomod2nix.mkGoEnv respectively.

This is developed external over at https://github.com/tweag/gomod2nix/.

This work has been sponsored by both the NLNet Foundation under the NGI Zero program and by Tweag.


Due to a mistake this is a new instance of #188035. See that PR for previous discussion.

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 22.11 Release Notes (or backporting 22.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
    • (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes
  • Fits CONTRIBUTING.md.

@adisbladis
Copy link
Member Author

Repating myself from: #188035 (comment)

I intend to merge this within the next couple of days unless there are any objections.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

The update script seems broken, doesn't seem to eval. I said previously I won't block on this so if you just want to drop it from this PR and deal with it in a follow up I'm fine with that.

Can you share your plans and time frame for promoting for this?

@adisbladis
Copy link
Member Author

The update script seems broken, doesn't seem to eval. I said previously I won't block on this so if you just want to drop it from this PR and deal with it in a follow up I'm fine with that.

I made a fix to make the updater work in the case that pname isn't explicitly passed.

Can you share your plans and time frame for promoting for this?

I have patches ready for all the Go packages I maintain in nixpkgs and will announce the availability of gomod2nix in nixpkgs shortly after at least a few of those have been merged.
I will however not try to go on some crusade to get everyone to adopt it immediately.

Additionally I also have patches for most of the packages that still use vgo2nix ready too, it's just blocked on this PR.

@adisbladis
Copy link
Member Author

@zowoq FYI the upstream repo has been moved to nix-community.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

I think the case-sensitive problems in #129730 may also be a problem for this?


I made a fix to make the updater work in the case that pname isn't explicitly passed.

Sorry, still doesn't seem to work. Can you add an example to this PR?

I have patches ready for all the Go packages I maintain in nixpkgs

Not any of the podman packages please.

will announce the availability of gomod2nix in nixpkgs shortly after at least a few of those have been merged.

Can we wait at least a couple weeks on this? I'd like to do some testing and fix some nits first. I really don't see why this needs to be rushed, at one point I thought the upstream project had been abandoned. IIRC the go no vendor patch was added 18 months ago.

FYI the upstream repo has been moved to nix-community.

Cool, thanks.

@adisbladis
Copy link
Member Author

adisbladis commented Aug 25, 2022

Can we wait at least a couple weeks on this? I'd like to do some testing and fix some nits first. I really don't see why this needs to be rushed

Sure that could wait, no problem.

Not any of the podman packages please.

I was talking about the ones where I'm the sole maintainer,.

I think the case-sensitive problems in #129730 may also be a problem for this?

I don't think so, I could add a test case for it though.

Sorry, still doesn't seem to work. Can you add an example to this PR?

Sure, I've added repackaged a fairly low impact package in this PR.
It was generated by running gomod2nix generate github.com/google/trillian/cmd/trillian_log_server github.com/google/trillian/cmd/trillian_log_signer github.com/google/trillian/cmd/createtree github.com/google/trillian/cmd/deletetree github.com/google/trillian/cmd/updatetree.

@@ -0,0 +1,167 @@
schema = 3
subPackages = ["cmd/trillian_log_server", "cmd/trillian_log_signer", "cmd/createtree", "cmd/deletetree", "cmd/updatetree"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be moved?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not moved per se, you can still set the same attribute in the Nix expression.
This is just another way to set the same thing which is a lot easier to control from the code generator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but why do we need to pass this through the code generator? This often needs to be modify to build additional tools or not build testing tools. For me this belongs into the nix-expression and not in the generated code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For one it serves to reduce the build time closure size.
We don't actually need everything in the root level go.mod and by making the generator aware of what needs to be built we only need to pull in the actually required subset of dependencies.

Comment on lines +2 to +3
subPackages = ["cmd/trillian_log_server", "cmd/trillian_log_signer", "cmd/createtree", "cmd/deletetree", "cmd/updatetree"]
goPackagePath = "github.com/google/trillian"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Why is this needed?
  • Why can't we infer this from the src?
  • Why does it need to be in this file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no src attribute explicitly being set.
The goPackagePath is there so the derivation knows which sources to select for the src attribute.

You could separate the src if you wanted to and do the whole manual hash update dance, nothing stops you from doing that but that will leave you without an update script.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no src attribute explicitly being set.

I am not really a fan of this. If I want to access the source files nix is building things from to investigate and debug packages I often use nix build .#name.src and I would tell people to do that when debugging. Could we add it at least as an alias back to make things more uniform with other packages?

Also we need to make sure that it is clear in the documentation that goPackagePath here has nothing to do with buildGoPackage.

BTW what is your plan for documentation?

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

oh the whole thing gets stuffed into the toml. src, version and everything. TBH I really don't like this:

{ lib
, gomod2nix
, fetchFromGitHub
}:

gomod2nix.buildGoApplication {
  pname = "trillian";
  pwd = ./.;
  meta = {
    homepage = "https://github.com/google/trillian";
    description = "A transparent, highly scalable and cryptographically verifiable data store.";
    license = [ lib.licenses.asl20 ];
    maintainers = [ lib.maintainers.adisbladis ];
  };
}

@adisbladis
Copy link
Member Author

adisbladis commented Aug 25, 2022

oh the whole thing gets stuffed into the toml. src, version and everything. TBH I really don't like this:

You could rewrite it in a more verbose way if you wanted to. Look at how https://github.com/nix-community/gomod2nix/blob/master/generic.nix or https://github.com/crypto-org-chain/chain-main/blob/master/default.nix are constructed for example.

There are very good reasons to do it this way though. In buildGoModule src and vendorSha256 requires you to update multiple hashes which is absolutely terrible UX.
I didn't want to repeat this terrible UX and made the code generated file the only thing you need to update as a single atomic unit.

Otherwise we'd have a similarly bad user experience once again for very little reason.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

To get the package version I either need to query the package via nix or grep the toml?

@adisbladis
Copy link
Member Author

To get the package version I either need to query the package via nix or grep the toml?

In this instance, yes.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

Sorry but I think burying the version in the toml is absolutely horrible.

@adisbladis
Copy link
Member Author

Sorry but I think burying the version in the toml is absolutely horrible.

Ok, I don't see the problem. There is plenty of prior art in nixpkgs already.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

There is plenty of prior art in nixpkgs already.

Package sets or separate packages like this?

I don't see the problem.

Searching "github.com/google/trillian" to find the version isn't a problem? Seems like we're trading one form of bad UX for another?

trillian

@adisbladis
Copy link
Member Author

Package sets or separate packages like this?

Both. Ruby packages comes to mind.

Searching "github.com/google/trillian" to find the version isn't a problem? Seems like we're trading one form of bad UX for another?

Would you feel better if we also stuck the version attribute in the top-level attributes in the toml file?

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

Ruby packages comes to mind.

If you mean bundlerEnv with gemset.nix and gemfile.lock that seems very different. Any others? I'm actually curious as I can't think of any. haskell, emacs, vim, node all seem much easier to inspect visually.

Would you feel better if we also stuck the version attribute in the top-level attributes in the toml file?

Only marginally. Would need to be enforced, I really don't want debates over it and packages flipping back and forth between (buried in toml|top of toml|set in default.nix).

You could rewrite it in a more verbose way if you wanted to. Look at how https://github.com/nix-community/gomod2nix/blob/master/generic.nix or https://github.com/crypto-org-chain/chain-main/blob/master/default.nix are constructed for example.

I'm kinda worried about the fact that this is possible. At the moment there is (basically) one way of writing a go package, this seems to allow a lot more variation (and more debates). Consistency is good UX also.

@adisbladis
Copy link
Member Author

adisbladis commented Aug 25, 2022

Any others? I'm actually curious as I can't think of any. haskell, emacs, vim, node all seem much easier to inspect visually.

Carnix is another one (code generator), so is poetry2nix (reads pyproject.toml).

I think it's disingenuous to say that Emacs is easier to inspect visually, the majority of that lives in massive auto generated files. The same goes for Haskell, Node & many more.

My take is that this whole version in the nix file or not comment is just bike shedding with extremely small practical impact.

I'm kinda worried about the fact that this is possible. At the moment there is (basically) one way of writing a go package, this seems to allow a lot more variation (and more debates).

Which is intentional. The needs of a packager packaging up an application in a private repo has somewhat different concerns than someone packaging something that is developed entirely outside of the package tree.

buildGoModule lacks this flexibility which (imo) makes it unusable as a tool to integrate into a typical development workflow.

gomod2nix was designed with both use cases in mind.

@zowoq
Copy link
Contributor

zowoq commented Aug 25, 2022

Carnix is another one (code generator)

toml2nix = crates.crates.toml2nix."0.1.1" deps;

so is poetry2nix (reads pyproject.toml).

Not familiar with these but at a glance they both seem pretty close to a standard package?

I think it's disingenuous to say that Emacs is easier to inspect visually, the majority of that lives in massive auto generated files. The same goes for Haskell, Node & many more.

They all seem to declare a version that isn't mixed in with it's own deps?


My take is that this whole version in the nix file or not comment is just bike shedding with extremely small practical impact.

The needs of a packager packaging up an application in a private repo has somewhat different concerns than someone packaging something that is developed entirely outside of the package tree.

buildGoModule lacks this flexibility which (imo) makes it unusable as a tool to integrate into a typical development workflow.

I'll response to these all at once as it's basically the same point:

Yeah, I agree that buildGoModule isn't fit for dev use outside of nixpkgs and yes, I agree that different packagers have different needs. For packages that are in nixpkgs we don't need (and IMO really don't want) a more complex tool that can be used in multiple ways/styles. We have ~1200 go packages and we add more each day. Allowing go packaging to become more complicated and more prone to debate doesn't make the lives of the go maintainers easier. Same applies for people reviewing go package PRs.

Just to be clear: I'm not objecting to using gomod2nix in nixpkgs, I'd just like to only allow one style to be used in nixpkgs that covers all but extreme cases so we have less bike shedding.

@SuperSandro2000
Copy link
Member

Did you do some testing with big go.mod files and how they behave like https://github.com/golangci/golangci-lint/blob/master/go.mod and more complex ones like https://github.com/open-policy-agent/gatekeeper/blob/master/go.mod ? Also what if the project uses replace where we can't use go install with the package name?

@SuperSandro2000
Copy link
Member

oh the whole thing gets stuffed into the toml. src, version and everything. TBH I really don't like this:

same for me. This is not very great from a reviewers perspective who needs to double check that people did not forgot to update version or some hash.

@FRidh
Copy link
Member

FRidh commented Aug 30, 2022

Glad to see a solution without vendorSha256!

Copy link
Member

@SuperSandro2000 SuperSandro2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry that we are doing another review round but I'd rather do this correct the first time than fixing it up multiple times and potentially breaking already packaged packages with it.

pkgs/build-support/go/gomod2nix/parser.nix Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/symlink/symlink.go Outdated Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/symlink/symlink.go Outdated Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/symlink/symlink.go Outdated Show resolved Hide resolved
pkgs/development/tools/gomod2nix/generic.nix Outdated Show resolved Hide resolved
pkgs/top-level/all-packages.nix Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/default.nix Outdated Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/default.nix Outdated Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/default.nix Outdated Show resolved Hide resolved
pkgs/build-support/go/gomod2nix/default.nix Show resolved Hide resolved
adisbladis added a commit to nix-community/gomod2nix that referenced this pull request Sep 2, 2022
@adisbladis adisbladis force-pushed the gomod2nix-1_4_0 branch 2 times, most recently from d257851 to 06e13d1 Compare September 2, 2022 05:36
@adisbladis adisbladis changed the title gomod2nix: init at 1.4.0 gomod2nix: init at 1.5.0 Sep 2, 2022
@adisbladis
Copy link
Member Author

Trying this again: If there is nothing new and actionable by Friday (2022-09-09) I will merge this.

@zowoq
Copy link
Contributor

zowoq commented Sep 7, 2022

Trying this again: If there is nothing new and actionable by Friday (2022-09-09) I will merge this.

You haven’t responded to a few concerns from Sandro and myself. Between us we’ve done the majority of the go maintenance for the last year so I don’t think our concerns should be dismissed.

There is no src attribute explicitly being set.

I am not really a fan of this. If I want to access the source files nix is building things from to investigate and debug packages I often use nix build .#name.src and I would tell people to do that when debugging. Could we add it at least as an alias back to make things more uniform with other packages?

I don’t think this has been addressed?

Also we need to make sure that it is clear in the documentation that goPackagePath here has nothing to do with buildGoPackage.

Renaming goPackagePath to goModPath, goSrcPath or something else would eliminate any confusion with buildGoPackage.

what is your plan for documentation?

I don’t mind if this PR is merged without docs but I think having docs is a blocker for gomod2nix, etc being promoted.

oh the whole thing gets stuffed into the toml. src, version and everything. TBH I really don't like this:

same for me. This is not very great from a reviewers perspective who needs to double check that people did not forgot to update version or some hash.

This hasn’t been addressed. As you asked for something actionable: I’d like to see the src/hash/version not treated as just another dep and be moved to the top of the toml with the other attributes.

I consider this a blocker for merging this PR.

Did you do some testing with big go.mod files and how they behave like https://github.com/golangci/golangci-lint/blob/master/go.mod and more complex ones like https://github.com/open-policy-agent/gatekeeper/blob/master/go.mod ? Also what if the project uses replace where we can't use go install with the package name?

Sandro's asked about this twice (in this PR and #188035 (comment)) and there doesn't seem to have been a response?

@06kellyjac
Copy link
Member

As someone who's also been packaging go modules a bunch I agree with all @zowoq & @SuperSandro2000 's points in that comment


I'll try this out with cosign which has a bajillion dependencies

symlink = mkInternalPkg "symlink" ./symlink/symlink.go;

# Install development dependencies from tools.go
install = mkInternalPkg "symlink" ./install/install.go;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
install = mkInternalPkg "symlink" ./install/install.go;
install = mkInternalPkg "install" ./install/install.go;

"strconv"
)

const filename = "tools.go"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually enforced that the file is called tools.go or just that the build tag is tools?

https://marcofranssen.nl/manage-go-tools-via-go-modules

// +build tools

I can't really find any docs on this

@wegank wegank marked this pull request as draft October 1, 2023 01:46
@adisbladis adisbladis closed this Feb 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants