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

buildGoModule: Fix overriding with overlay-style stdenv #225051

Merged
merged 2 commits into from
Aug 16, 2024

Conversation

ShamrockLee
Copy link
Contributor

@ShamrockLee ShamrockLee commented Apr 6, 2023

Description of changes

The Go package builder buildGoModule is refactored to adopt the overlay-style stdenv.mkDerivation (#119942) and to fix overriding. One can now override vendorHash using overrideAttrs. This addresses #86349 (comment)

The goModules and vendorHash attributes are moved out of passthru as they are already exposed as stdenv.mkDerivation attributes. They can still be accessed as pet.vendorHash, but no longer pet.passthru.vendorHash. The builder now only adds go to passthru.

To address the issue of vendorHash = null through overrideAttrs may break the overriding of goModules, this PR also provides an overridable passthru.overrideModAttrs that will be applied to goModules when vendorHash is not null.

Closes #86349

Comparison to similar PRs:

In this PR, the diff of pkgs/build-support/go/module.nix is shorter than #171586.

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/)
  • 23.05 Release Notes (or backporting 22.11 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
  • Fits CONTRIBUTING.md.

@github-actions github-actions bot added 6.topic: golang 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog 8.has: documentation labels Apr 6, 2023
@ShamrockLee ShamrockLee changed the title goModule: Fix overriding with overlay-style stdenv and add missing parentheses goModule: Fix overriding with overlay-style stdenv Apr 6, 2023
@ShamrockLee ShamrockLee changed the title goModule: Fix overriding with overlay-style stdenv buildGoModule: Fix overriding with overlay-style stdenv Apr 6, 2023
zowoq
zowoq previously requested changes Apr 6, 2023
Copy link
Contributor

@zowoq zowoq left a comment

Choose a reason for hiding this comment

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

It may not be a breaking change but I think we're to close to branch off for this so I'm a very strongly against including it in 23.05.

Also, I am planning to make a few changes to buildGoModule after the branch, e.g. drop vendorSha256 and only have vendorHash, it'll be easier and make this PR simpler if that happens first.

cc @NixOS/golang

@ShamrockLee
Copy link
Contributor Author

It may not be a breaking change but I think we're too close to branch off for this so I'm strongly against including it in 23.05.

Agree. Should I drop change to the the release note?

I place them there just because the new release note hasn't come out yet.

@ShamrockLee
Copy link
Contributor Author

Would it be okay to just remove those mod*Phase attributes? We alredy have overrideModAttrs, which itself will also become a syntax sugar after this chage. Exposing those mod*Phase would be confusing.

@zowoq
Copy link
Contributor

zowoq commented Apr 7, 2023

Should I drop change to the the release note?

I place them there just because the new release note hasn't come out yet.

Fine to leave them there for now, can be moved once the new release note is created after branch off.

Would it be okay to just remove those mod*Phase attributes? We alredy have overrideModAttrs, which itself will also become a syntax sugar after this chage. Exposing those mod*Phase would be confusing.

Maybe, have to give it some thought first.


Also, I'd appreciate it if you would revert all of the unrelated formatting changes, it makes the diff much harder to review.

@ShamrockLee ShamrockLee force-pushed the go-module-overlay-stdenv branch 2 times, most recently from eeb5844 to 0e87a61 Compare April 8, 2023 20:40
@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Apr 8, 2023

Also, I'd appreciate it if you would revert all of the unrelated formatting changes, it makes the diff much harder to review.

It turns out that the indentation difference is not just caused by nixpkgs-fmt, but the inherent difference of two structures.

Even then, I managed to make them align by making reasonable adjustment to the original expression (mainly by simplifying the go-modules part before running nixpkgs-fmt). The adjustment (packed inside the first 2 commits) doesn't bring any rebuild. Maybe I could file another PR containing them to make this one easier to review.

The last commit contains the actual change. The relation between the original implementation and the new implementation can be seen from the diff. The expected attributes are organized at the beginning of the expression, and the corresponding comment documentation are prefixed with ATTRIBUTES:.

@ShamrockLee ShamrockLee marked this pull request as ready for review April 8, 2023 20:49
@ShamrockLee ShamrockLee requested a review from zowoq April 8, 2023 21:13
@zowoq
Copy link
Contributor

zowoq commented Apr 8, 2023

@ShamrockLee I'm switching this back to draft as it isn't going to be merged until after branch off.

@zowoq zowoq marked this pull request as draft April 8, 2023 23:08
pkgs/build-support/go/module.nix Show resolved Hide resolved
pkgs/build-support/go/module.nix Outdated Show resolved Hide resolved
@zowoq zowoq added the 2.status: work-in-progress This PR isn't done label Apr 9, 2023
@zowoq zowoq self-assigned this Apr 9, 2023
@zowoq
Copy link
Contributor

zowoq commented Apr 9, 2023

#225371

Still needs more testing but I've opened a PR to (mostly) get rid of vendorSha256.

@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Apr 9, 2023

Go packages built with this buildGoModule implementation seems to take noticable longer to evaluate. Not sure if it also happens to #171586.

How can we benchmark the evaluation time?

Copy link
Contributor

@doronbehar doronbehar left a comment

Choose a reason for hiding this comment

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

Looks good overall! Well done for all the work.

# Canonicallize `overrideModAttrs` as an attribute overlay.
# `passthru.overrideModAttrs` will be overridden
# when users want to override `goModules`.
overrideModAttrs = toExtension overrideModAttrs;
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is the only place that toExtension is used, perhaps you'd like to put it inline here? It might make the diff a bit smaller..

Copy link
Contributor

Choose a reason for hiding this comment

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

Quoting myself:

Since this is the only place that toExtension is used, perhaps you'd like to put it inline here? It might make the diff a bit smaller..

What do you think about this idea @ShamrockLee ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this function works well, I plan to move it into lib.fixedPoints, so I defined it separately.

Copy link
Contributor

Choose a reason for hiding this comment

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

If this function works well, I plan to move it into lib.fixedPoints, so I defined it separately.

OK sounds like a good idea to me.

pkgs/build-support/go/module.nix Show resolved Hide resolved

```sh
cd path/to/nixpkgs
nix-prefetch -E "{ sha256 }: ((import ./. { }).my-package.overrideAttrs (_: { vendorHash = sha256; })).go-modules"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
nix-prefetch -E "{ sha256 }: ((import ./. { }).my-package.overrideAttrs (_: { vendorHash = sha256; })).go-modules"
nix-prefetch -E "{ hash }: ((import ./. { }).my-package.overrideAttrs (_: { vendorHash = hash; })).go-modules"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not supported by nix-prefetch. I changed it back.

doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
@ShamrockLee ShamrockLee force-pushed the go-module-overlay-stdenv branch 2 times, most recently from 115a1a8 to 7352540 Compare July 30, 2024 03:27
@ShamrockLee
Copy link
Contributor Author

@doronbehar Thank you for reviewing and giving feedback. I revised the Overriding goModules part of the documentation. Please take a look.

Copy link
Contributor

@doronbehar doronbehar left a comment

Choose a reason for hiding this comment

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

Looks much better!

doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
doc/languages-frameworks/go.section.md Show resolved Hide resolved
Copy link
Contributor

@doronbehar doronbehar left a comment

Choose a reason for hiding this comment

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

One last round I hope!

doc/languages-frameworks/go.section.md Show resolved Hide resolved
doc/languages-frameworks/go.section.md Outdated Show resolved Hide resolved
};
}
);
pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit surprising, perhaps the paragraph above should mention why you set vendorHash = null;? Or perhaps explain this here in a a comment? (I think I understood correctly this is because you set overrideModAttrs...)

Copy link
Contributor Author

@ShamrockLee ShamrockLee Jul 31, 2024

Choose a reason for hiding this comment

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

venhorHash = null is to prevent vendoring from the Nix side by goModules. People set it because the source is "vendored" (contains the vendor directory), and they would like to use such vendoring. For example, the Apptainer project provided vendored source tarballs in each release when the project was still known as Singularity.

If a user would like to use the goModules vendoring instead of the upstream one, they would set deleteVendor = true instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

venhorHash = null is to prevent vendoring from the Nix side by goModules. People set it because the source is "vendored" (contains the vendor directory), and they would like to use such vendoring. For example, the Apptainer project provided vendored source tarballs in each release when the project was still known as Singularity.

If a user would like to use the goModules vendoring instead of the upstream one, they would set deleteVendor = true instead.

I'm sorry but I did not understand :). I'll write again what I wanted you to explain in a comment / what I felt is missing:

The purpose of this example is to demonstrate how to use overrideModAttrs, but what is peculiar to me, is that you perform an additional overrideAttrs of vendorHash = null;. I don't understand how that is related to overrdeModAttrs - if you set overrideModAttrs do you have to also set vendorHash = null; afterwards? If so, why (explain in a code comment)? If you don't have to set vendorHash = null; afterwards, please remove that, and finish with:

in 
pet-foo

Copy link
Contributor Author

@ShamrockLee ShamrockLee Aug 1, 2024

Choose a reason for hiding this comment

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

Sorry for causing the confusion.

In my imagination, the first overriding targeting goModules might be buried somewhere inside the codebase, while another user made another overriding and set vendorHash = null.

The purpose of this documentation is to avoid the conflicts between these overridings.

Comment on lines 116 to 118
pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
in
pet-vendored
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps (hopefully it is still nixfmt correct):

Suggested change
pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
in
pet-vendored
in
pet-foo.overrideAttrs { vendorHash = null; };

Comment on lines 99 to 118
let
pet-foo = pkgs.overrideAttrs (
finalAttrs: previousAttrs: {
passthru = previousAttrs.passthru // {
overrideModAttrs = lib.composeExtensions previousAttrs.passthru.overrideModAttrs (
finalModAttrs: previousModAttrs: {
# goModules-specific overriding goes here
postBuild = ''
# Here you have access to the `vendor` directory.
substituteInPlace vendor/github.com/example/repo/file.go \
--replace-fail "panic(err)" ""
'';
}
);
};
}
);
pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
in
pet-vendored
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for causing the confusion.

No worries :).

In my imagination, the first overriding targeting goModules might be buried somewhere inside the codebase, while another user made another overriding and set vendorHash = null.

The purpose of this documentation is to avoid the conflicts between these overridings.

Hmm this is a bit complicated for at this point, so I'm still not sure I understand. Let's ask this: Why not:

Suggested change
let
pet-foo = pkgs.overrideAttrs (
finalAttrs: previousAttrs: {
passthru = previousAttrs.passthru // {
overrideModAttrs = lib.composeExtensions previousAttrs.passthru.overrideModAttrs (
finalModAttrs: previousModAttrs: {
# goModules-specific overriding goes here
postBuild = ''
# Here you have access to the `vendor` directory.
substituteInPlace vendor/github.com/example/repo/file.go \
--replace-fail "panic(err)" ""
'';
}
);
};
}
);
pet-vendored = pet-foo.overrideAttrs { vendorHash = null; };
in
pet-vendored
let
pet-foo = pkgs.overrideAttrs (
finalAttrs: previousAttrs: {
# TODO: Explain this?
vendorHash = null;
passthru = previousAttrs.passthru // {
overrideModAttrs = lib.composeExtensions previousAttrs.passthru.overrideModAttrs (
finalModAttrs: previousModAttrs: {
# goModules-specific overriding goes here
postBuild = ''
# Here you have access to the `vendor` directory.
substituteInPlace vendor/github.com/example/repo/file.go \
--replace-fail "panic(err)" ""
'';
}
);
};
}
);
in
pet-foo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's avoid the confusion by removing vendorHash = null and leaving it as a simple example demonstrating the correct overriding approach.

Copy link
Contributor

@doronbehar doronbehar left a comment

Choose a reason for hiding this comment

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

Excellent work! Thanks for working on this @ShamrockLee . I will give a few days for @zowoq a few more days to respond to this (it seemed they didn't like it initially), and if there will be no reply I'll merge this.

Fix overriding of vendorHash and various attributes via the fixed point
attribute support of stdenv.mkDerivation.

Pass as derivation attributes
goModules, modRoot, vendorHash, deleteVendor, and proxyVendor.

Move goModules and vendorHash out of passthru.

Co-authored-by: Doron Behar <[email protected]>
@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Aug 11, 2024

The package in the overriding example in go.section.md was still named pet-foo. I renamed it to pet-overridden.

@doronbehar doronbehar dismissed zowoq’s stale review August 16, 2024 15:44

Haven't responded to any of the new changes happened to the PR recently.

@doronbehar doronbehar merged commit 0d920a9 into NixOS:staging Aug 16, 2024
23 checks passed
jian-lin added a commit that referenced this pull request Aug 16, 2024
@philiptaron
Copy link
Contributor

philiptaron commented Aug 20, 2024

The nixpkgs-manual fails to build due to this change:

### Overriding `goModules` (#buildGoModule-goModules-override)

The parentheses ought to be curly braces. I've opened PR #336061 to fix it.

@philiptaron philiptaron mentioned this pull request Aug 20, 2024
2 tasks
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/overrideattrs-and-go-query/50919/2

@SuperSandro2000
Copy link
Member

One of my overlays broke because of a mistake I did but I think we can avoid that. Fix in #339042

@ShamrockLee
Copy link
Contributor Author

@doronbehar I proposed lib.toExtension in #336414, addressing the concern in #225051 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

9 participants