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

[RFC 0067] Common override interface derivations #67

Closed
wants to merge 5 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions rfcs/0067-common-override-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
feature: common-override-interface
start-date: 2020-03-17
author: Frederik Rietdijk
co-authors: (find a buddy later to help out with the RFC)
shepherd-team: (names, to be nominated and accepted by RFC steering committee)
shepherd-leader: (name to be appointed by RFC steering committee)
related-issues: (will contain links to implementation PRs)
---

# Summary
[summary]: #summary

Define commonly used attributes for overriding in Nixpkgs.

# Motivation
[motivation]: #motivation

In Nixpkgs several methods exist to override functions calls. The primary ones are:

1. `.override` to override, typically, the first function call.
2. `.overrideAttrs` to override the call to `stdenv.mkDerivation`.
3. `.overrideDerivation` to override the call to `derivation`.

The first two are mainly used and are typically sufficient. However, how can we override generic package builders, such as `buildPythonPackage` and `buildGoPackage`?

For the `buildPythonPackage` function the `.overridePythonAttrs` was introduced that would override the call to `buildPythonPackage` because using `.overrideAttrs` would often not result in what the user expect would happen. In hindsight, it would have been better to attach a custom `.overrideAttrs` to `buildPythonPackage`.

This RFC thus proposes to let generic builders define a custom `.overrideAttrs` that overrides the call to the generic builder.

# Detailed design
[design]: #detailed-design

The method `.overrideAttrs` will be modified so that instead of

- `.overrideAttrs` to override the call to `stdenv.mkDerivation`.

it will be

- `.overrideAttrs` to override the call to the generic builder.

The generic builders such as `buildGoPackage` would thus apply the function `makeOverridable` to it.

In case of Python that already has `.overridePythonAttrs`, support for
```nix
buildGoPackage = makeOverridable buildGoPackage;
```

# Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

-

# Drawbacks
[drawbacks]: #drawbacks

After invoking a generic builder it is no longer possible to override the call to `stdenv.mkDerivation`.

# Alternatives
[alternatives]: #alternatives

An alternative would be to add a new method for overriding, `.overrideArgs`, thus allowing one to still call `.overrideAttrs` to override `stdenv.mkDerivation`.

Copy link
Member

Choose a reason for hiding this comment

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

Another alternative could be some mechanism to unify override/overrideAttrs into a single override mechanism supporting multiple (probably named?) levels, like overrideCall pkg "callPackage" (x: {…})

Copy link
Member

Choose a reason for hiding this comment

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

Very much this, and it's also what NixOS/nixpkgs#87394 seems to implement. I think this is the only way to not end up with a mess when you have arbitrarily deeply nested function calls.

With this

  • .override becomes .overrideCall "callPackage" { ... }
  • .overrideAttrs becomes .overrideCall "mkDerivation" { ... }
  • .overridePythonAttrs becomes .overrideCall "buildPythonPackage" { ... }
  • .overrideDerivation becomes .overrideCall "derivation" { ... }
  • etc.

With this, there's much less confusion as to how you need to override what. And it's a unified interface for the current override functions.

Copy link
Member Author

Choose a reason for hiding this comment

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

I like this approach, but I do want to clarify that from a UI point of view, end users should typically need one and only one function that helps them. That is my motivation for shadowing .overrideAttrs. Of course, if we can provide something like proposed here, as well as a call that is expected to override what is typically expected, then that would be great.

Choose a reason for hiding this comment

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

I fail to see how this helps to be honest, because the difficult part (at least in my opinion) is understanding the semantics of the different override functions, not their actual name. But all this (I'm using @infinisil's example here because it is concrete) does is rename override to overrideCall "callPackage" etc. but I still have to look at the code to see which of the strings (instead of functions) I have to use to achieve some specific goal.

I also don't know if shoving all these functions under one name will be very helpful documentation wise, as now I have to read more, and more importantly about a wider range of topics, to find out if this one function will solve my problem or not.

I think the problem lies more in the fact that it is difficult to grasp all the mechanics at play in nixpkgs, but I don't think that's solved by overloading a function.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we need to be better at documenting the parameters and how they transform the data. In the past there were ideas for attaching docstrings to functions NixOS/nixpkgs#23505.

# Unresolved questions
[unresolved]: #unresolved-questions

-

# Future work
[future]: #future-work

Implement the custom `.overrideAttrs` for the generic builders.