mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Ignore local registries for lock file generation
When resolving indirect flake references like `nixpkgs` in `flake.nix` files, Nix will no longer use the system and user flake registries. It will only use the global flake registry and overrides given on the command line via `--override-flake`.
This commit is contained in:
parent
ab5a9cf2db
commit
7ddf7300b5
8 changed files with 51 additions and 7 deletions
22
doc/manual/rl-next/ignore-local-registries.md
Normal file
22
doc/manual/rl-next/ignore-local-registries.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
synopsis: "Flake lock file generation now ignores local registries"
|
||||||
|
prs: [12019]
|
||||||
|
---
|
||||||
|
|
||||||
|
When resolving indirect flake references like `nixpkgs` in `flake.nix` files, Nix will no longer use the system and user flake registries. It will only use the global flake registry and overrides given on the command line via `--override-flake`.
|
||||||
|
|
||||||
|
This avoids accidents where users have local registry overrides that map `nixpkgs` to a `path:` flake in the local file system, which then end up in committed lock files pushed to other users.
|
||||||
|
|
||||||
|
In the future, we may remove the use of the registry during lock file generation altogether. It's better to explicitly specify the URL of a flake input. For example, instead of
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
outputs = { self, nixpkgs }: { ... };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
write
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
outputs = { self, nixpkgs }: { ... };
|
||||||
|
}
|
||||||
|
```
|
|
@ -178,7 +178,8 @@ Registries getRegistries(const Settings & settings, ref<Store> store)
|
||||||
|
|
||||||
std::pair<Input, Attrs> lookupInRegistries(
|
std::pair<Input, Attrs> lookupInRegistries(
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
const Input & _input)
|
const Input & _input,
|
||||||
|
const RegistryFilter & filter)
|
||||||
{
|
{
|
||||||
Attrs extraAttrs;
|
Attrs extraAttrs;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -190,6 +191,7 @@ std::pair<Input, Attrs> lookupInRegistries(
|
||||||
if (n > 100) throw Error("cycle detected in flake registry for '%s'", input.to_string());
|
if (n > 100) throw Error("cycle detected in flake registry for '%s'", input.to_string());
|
||||||
|
|
||||||
for (auto & registry : getRegistries(*input.settings, store)) {
|
for (auto & registry : getRegistries(*input.settings, store)) {
|
||||||
|
if (filter && !filter(registry->type)) continue;
|
||||||
// FIXME: O(n)
|
// FIXME: O(n)
|
||||||
for (auto & entry : registry->entries) {
|
for (auto & entry : registry->entries) {
|
||||||
if (entry.exact) {
|
if (entry.exact) {
|
||||||
|
|
|
@ -65,8 +65,15 @@ void overrideRegistry(
|
||||||
const Input & to,
|
const Input & to,
|
||||||
const Attrs & extraAttrs);
|
const Attrs & extraAttrs);
|
||||||
|
|
||||||
|
using RegistryFilter = std::function<bool(Registry::RegistryType)>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewrite a flakeref using the registries. If `filter` is set, only
|
||||||
|
* use the registries for which the filter function returns true.
|
||||||
|
*/
|
||||||
std::pair<Input, Attrs> lookupInRegistries(
|
std::pair<Input, Attrs> lookupInRegistries(
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
const Input & input);
|
const Input & input,
|
||||||
|
const RegistryFilter & filter = {});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,13 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
|
||||||
fetched.emplace(originalRef.fetchTree(state.store));
|
fetched.emplace(originalRef.fetchTree(state.store));
|
||||||
} else {
|
} else {
|
||||||
if (allowLookup) {
|
if (allowLookup) {
|
||||||
resolvedRef = originalRef.resolve(state.store);
|
resolvedRef = originalRef.resolve(
|
||||||
|
state.store,
|
||||||
|
[](fetchers::Registry::RegistryType type) {
|
||||||
|
/* Only use the global registry and CLI flags
|
||||||
|
to resolve indirect flakerefs. */
|
||||||
|
return type == fetchers::Registry::Flag || type == fetchers::Registry::Global;
|
||||||
|
});
|
||||||
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
|
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
|
||||||
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
|
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
|
||||||
flakeCache.push_back({resolvedRef, *fetchedResolved});
|
flakeCache.push_back({resolvedRef, *fetchedResolved});
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
#include "url-parts.hh"
|
#include "url-parts.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "registry.hh"
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -36,7 +35,9 @@ std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlakeRef FlakeRef::resolve(ref<Store> store) const
|
FlakeRef FlakeRef::resolve(
|
||||||
|
ref<Store> store,
|
||||||
|
const fetchers::RegistryFilter & filter) const
|
||||||
{
|
{
|
||||||
auto [input2, extraAttrs] = lookupInRegistries(store, input);
|
auto [input2, extraAttrs] = lookupInRegistries(store, input);
|
||||||
return FlakeRef(std::move(input2), fetchers::maybeGetStrAttr(extraAttrs, "dir").value_or(subdir));
|
return FlakeRef(std::move(input2), fetchers::maybeGetStrAttr(extraAttrs, "dir").value_or(subdir));
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "outputs-spec.hh"
|
#include "outputs-spec.hh"
|
||||||
|
#include "registry.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -57,7 +58,9 @@ struct FlakeRef
|
||||||
|
|
||||||
fetchers::Attrs toAttrs() const;
|
fetchers::Attrs toAttrs() const;
|
||||||
|
|
||||||
FlakeRef resolve(ref<Store> store) const;
|
FlakeRef resolve(
|
||||||
|
ref<Store> store,
|
||||||
|
const fetchers::RegistryFilter & filter = {}) const;
|
||||||
|
|
||||||
static FlakeRef fromAttrs(
|
static FlakeRef fromAttrs(
|
||||||
const fetchers::Settings & fetchSettings,
|
const fetchers::Settings & fetchSettings,
|
||||||
|
|
|
@ -165,7 +165,8 @@ can occur in *locked* flake references and are available to Nix code:
|
||||||
|
|
||||||
Currently the `type` attribute can be one of the following:
|
Currently the `type` attribute can be one of the following:
|
||||||
|
|
||||||
* `indirect`: *The default*. Indirection through the flake registry.
|
* `indirect`: *The default*. These are symbolic references to flakes
|
||||||
|
that are looked up in [the flake registries](./nix3-registry.md).
|
||||||
These have the form
|
These have the form
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -34,6 +34,8 @@ highest precedence:
|
||||||
* Overrides specified on the command line using the option
|
* Overrides specified on the command line using the option
|
||||||
`--override-flake`.
|
`--override-flake`.
|
||||||
|
|
||||||
|
Note that the system and user registries are not used to resolve flake references in `flake.nix`. They are only used to resolve flake references on the command line.
|
||||||
|
|
||||||
# Registry format
|
# Registry format
|
||||||
|
|
||||||
A registry is a JSON file with the following format:
|
A registry is a JSON file with the following format:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue