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 0123] Flake names #123

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
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
91 changes: 91 additions & 0 deletions rfcs/0123-flake-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
feature: flake-names
start-date: 2022-03-12
author: Anselm Schüler
co-authors: None
shepherd-team: None
shepherd-leader: None
related-issues: None
---

# Summary
[summary]: #summary

Flakes can declare the field `name`.
It represents the name of the flake.
The store paths corresponding to a flake source are no longer called `source`, but use the flake name.

# Motivation
[motivation]: #motivation

- Flakes generate store paths named “source”, and it’s difficult to navigate this when manually inspecting the store.
- This metadata can be used to make flakes more approachable and usable, in particular, it can be output instead or with the URI, making the nix commands friendlier.

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
- Unique names are useful for the purpose of finding duplicate things caused by diamond dependencies. (E.g. `a -> b -> d1`, `a -> c -> d2`. Without a unique name (`d`), it is not possible to correlate `d1` and `d2` reliably.)

# Detailed design
[design]: #detailed-design

A new supported property for flakes is introduced, `name`.
The derivation that contains the flake’s content is called `flake-source-${name}`

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

Running `nix flake metadata` on a flake that declares this field displays it at the top.
Running `nix flake show` on a flake that declares this field shows the name instead of the URL, followed by the URL in parentheses.

Examples:

File `/example/flake.nix`
```nix
{
name = "example";
outputs = { ... }: {
lib.example = "example";
};
Comment on lines +42 to +44
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
outputs = { ... }: {
lib.example = "example";
};
outputs = { self, ... }: {
lib.example = self.name;
};

Making the name accessible will allow flake definition libraries (flake-utils, flake-parts, etc) to automatically use it in some places. For instance when defining an anonymous (non-path-value) module, it's a good idea to use the flake name and module attribute to form the module key. Otherwise, the module can't be disabled with disabledModules.
It will also allow to detect when multiple versions of the same flake are combined, and report a good error message instead of "suchandsuch option has already been defined".

}
```

Shell
```console
$ nix eval git+file:///example
[…] copying flake-source-example
"example"
```

Example of interactions:

Shell (using the previous file)
```
$ nix flake metadata /example
Name: example
Resolved URL: git+file:///example
Locked URL: …
$ nix flake show /example
example (git+file:///home/anselmschueler/Code/example?rev=b0&rev=c714c8624f5d49a9d88e6e24550dd88515923c18)
└───lib: unknown
```

# Drawbacks
Copy link
Member

Choose a reason for hiding this comment

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

The big drawback here (where “big” would probably need to be refined, I’ve no idea how much of an issue it is in practice) is that since the name is part of the store path, two flakes with the same content but a different name will end-up in a different place in the store − which itself means that everything that depends on them would have to be rebuild.

Copy link
Author

Choose a reason for hiding this comment

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

But flakes with a different name will necessarily have different content? Or are the flake.* files not copied to the store?

Copy link
Member

Choose a reason for hiding this comment

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

Fair point (I had a convoluted scenario in mind, but that’s probably way out of the scope of this RFC now that I think of it).

That’s actually highlighting an interesting design challenge: There’s currently a neat separation between the fetching code and the code that knows about what the flake is. inputs.foo = something gets translated to a call to builtins.fetchTree something, and its result is then fed to the outputs function. And the fetchTree part doesn’t know (nor has to know) that it’s fetching a flake.
But if the name gets defined in the flake (and used in the output path), then the fetchTree logic must be a bit more convoluted:

  • It has to know whether it is fetching a flake
  • When fetching a flake, it must get its flake.nix, evaluate it to find its name, and only then put it in the store with the correct name.

Copy link
Author

Choose a reason for hiding this comment

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

Wouldn’t it be better to have this conversation outside the review widget? I feel like this aspect of the discussion is somewhat hidden & non-chronological.

Copy link
Member

Choose a reason for hiding this comment

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

  • When fetching a flake, it must get its flake.nix, evaluate it to find its name, and only then put it in the store with the correct name.

This can be solved by adding name to the lock file.
We can use the same trick for other fetch-related parameters, like whether to fetch submodules or not, whether to git-crypt decrypt, etc, all of which would also be nice to configure in flake.nix.
fetchTree remains unaware of flake-ness.

[drawbacks]: #drawbacks

- This may cause clutter and additional maintenance.
- Since this changes the output of nix flake metadata and nix flake show, it might cause scripts that read this output to break.
- This requires a significant change to the way flakes are handled.
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
- This requires a significant change to the way flakes are handled.

All changes come with an implementation cost. I don't think this RFC is special, because it seems like an addition that doesn't require action by the ecosystem, especially if the name is allowed to be unset.

- This treats the Nix store as a user-facing part of Nix, which is generally not intended.
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
- This treats the Nix store as a user-facing part of Nix, which is generally not intended.

The store has always been user-facing. Users interact with it, store paths show up in logs, etc.

Sometimes you don't have to think much about the store and that's good.

How will users will have to pay more attention to the store after this change?


# Alternatives
[alternatives]: #alternatives

- Flake names could be handled entirely through outside means, with things like the global registry merely pointing to flakes under names.

# Unresolved questions
[unresolved]: #unresolved-questions

- The name scheme could be changed. `flake-source-${name}` could be too long. Alternatives include `source-${name}`.
- The interactions with nix flake metadata and nix flake show are not critical to the design, which is mostly aimed at clarifying derivation names.

# Future work
[future]: #future-work

- Flake usability can be improved.
- Issues with indicipherable derivations named “source” also exist elsewhere.