Skip to content

Commit

Permalink
nix flake {metadata,archive}: Fix chroot stores
Browse files Browse the repository at this point in the history
Fixes

  $ nix flake metadata --store /tmp/nix nixpkgs
  error: path '/tmp/nix/nix/store/65xpqkz92d9j7k5ric4z8lzhiigxsfbg-source/flake.nix' is not in the Nix store

This has been broken since 598deb2.
  • Loading branch information
edolstra committed Sep 9, 2024
1 parent 4c7a6ff commit c5a4dfa
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 13 deletions.
27 changes: 16 additions & 11 deletions src/libflake/flake/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,21 @@ LockedFlake lockFlake(
}
}

std::pair<StorePath, Path> sourcePathToStorePath(
ref<Store> store,
const SourcePath & _path)
{
auto path = _path.path.abs();

if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) {
auto realStoreDir = store2->getRealStoreDir();
if (isInDir(path, realStoreDir))
path = store2->storeDir + path.substr(realStoreDir.size());
}

return store->toStorePath(path);
}

void callFlake(EvalState & state,
const LockedFlake & lockedFlake,
Value & vRes)
Expand All @@ -768,17 +783,7 @@ void callFlake(EvalState & state,

auto lockedNode = node.dynamic_pointer_cast<const LockedNode>();

// FIXME: This is a hack to support chroot stores. Remove this
// once we can pass a sourcePath rather than a storePath to
// call-flake.nix.
auto path = sourcePath.path.abs();
if (auto store = state.store.dynamic_pointer_cast<LocalFSStore>()) {
auto realStoreDir = store->getRealStoreDir();
if (isInDir(path, realStoreDir))
path = store->storeDir + path.substr(realStoreDir.size());
}

auto [storePath, subdir] = state.store->toStorePath(path);
auto [storePath, subdir] = sourcePathToStorePath(state.store, sourcePath);

emitTreeAttrs(
state,
Expand Down
10 changes: 10 additions & 0 deletions src/libflake/flake/flake.hh
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,16 @@ void callFlake(
const LockedFlake & lockedFlake,
Value & v);

/**
* Map a `SourcePath` to the corresponding store path. This is a
* temporary hack to support chroot stores while we don't have full
* lazy trees. FIXME: Remove this once we can pass a sourcePath rather
* than a storePath to call-flake.nix.
*/
std::pair<StorePath, Path> sourcePathToStorePath(
ref<Store> store,
const SourcePath & path);

}

void emitTreeAttrs(
Expand Down
4 changes: 2 additions & 2 deletions src/nix/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
auto & flake = lockedFlake.flake;

// Currently, all flakes are in the Nix store via the rootFS accessor.
auto storePath = store->printStorePath(store->toStorePath(flake.path.path.abs()).first);
auto storePath = store->printStorePath(sourcePathToStorePath(store, flake.path).first);

if (json) {
nlohmann::json j;
Expand Down Expand Up @@ -1079,7 +1079,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun

StorePathSet sources;

auto storePath = store->toStorePath(flake.flake.path.path.abs()).first;
auto storePath = sourcePathToStorePath(store, flake.flake.path).first;

sources.insert(storePath);

Expand Down
3 changes: 3 additions & 0 deletions tests/functional/flakes/flakes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ nix registry list | grepInverse '^user' # nothing in user registry
nix flake metadata flake1
nix flake metadata flake1 | grepQuiet 'Locked URL:.*flake1.*'

# Test 'nix flake metadata' on a chroot store.
nix flake metadata --store $TEST_ROOT/chroot-store flake1

# Test 'nix flake metadata' on a local flake.
(cd "$flake1Dir" && nix flake metadata) | grepQuiet 'URL:.*flake1.*'
(cd "$flake1Dir" && nix flake metadata .) | grepQuiet 'URL:.*flake1.*'
Expand Down

0 comments on commit c5a4dfa

Please sign in to comment.