mirror of
https://github.com/NixOS/nix.git
synced 2025-11-25 03:39:36 +01:00
Improve support for subflakes
Subflakes are flakes in the same tree, accessed in flake inputs via
relative paths (e.g. `inputs.foo.url = "path:./subdir"`). Previously
these didn't work very well because they would be separately copied to
the store, which is inefficient and makes references to parent
directories tricky or impossible. Furthermore, they had their own NAR
hash in the lock file, which is superfluous since the parent is
already locked.
Now subflakes are accessed via the accessor of the calling flake. This
avoids the unnecessary copy and makes it possible for subflakes to
depend on flakes in a parent directory (so long as they're in the same
tree).
Lock file nodes for relative flake inputs now have a new `parent` field:
{
"locked": {
"path": "./subdir",
"type": "path"
},
"original": {
"path": "./subdir",
"type": "path"
},
"parent": [
"foo",
"bar"
]
}
which denotes that `./subdir` is to be interpreted relative to the
directory of the `bar` input of the `foo` input of the root flake.
Extracted from the lazy-trees branch.
This commit is contained in:
parent
bbe780b137
commit
b2be6fed86
14 changed files with 332 additions and 120 deletions
|
|
@ -116,31 +116,14 @@ struct PathInputScheme : InputScheme
|
|||
std::pair<ref<SourceAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) const override
|
||||
{
|
||||
Input input(_input);
|
||||
std::string absPath;
|
||||
auto path = getStrAttr(input.attrs, "path");
|
||||
|
||||
if (path[0] != '/') {
|
||||
if (!input.parent)
|
||||
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
|
||||
auto absPath = getAbsPath(input);
|
||||
|
||||
auto parent = canonPath(*input.parent);
|
||||
|
||||
// the path isn't relative, prefix it
|
||||
absPath = nix::absPath(path, parent);
|
||||
|
||||
// for security, ensure that if the parent is a store path, it's inside it
|
||||
if (store->isInStore(parent)) {
|
||||
auto storePath = store->printStorePath(store->toStorePath(parent).first);
|
||||
if (!isDirOrInDir(absPath, storePath))
|
||||
throw BadStorePath("relative path '%s' points outside of its parent's store path '%s'", path, storePath);
|
||||
}
|
||||
} else
|
||||
absPath = path;
|
||||
|
||||
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s'", absPath));
|
||||
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s' to the store", absPath));
|
||||
|
||||
// FIXME: check whether access to 'path' is allowed.
|
||||
auto storePath = store->maybeParseStorePath(absPath);
|
||||
auto storePath = store->maybeParseStorePath(absPath.abs());
|
||||
|
||||
if (storePath)
|
||||
store->addTempRoot(*storePath);
|
||||
|
|
@ -149,7 +132,7 @@ struct PathInputScheme : InputScheme
|
|||
if (!storePath || storePath->name() != "source" || !store->isValidPath(*storePath)) {
|
||||
// FIXME: try to substitute storePath.
|
||||
auto src = sinkToSource([&](Sink & sink) {
|
||||
mtime = dumpPathAndGetMtime(absPath, sink, defaultPathFilter);
|
||||
mtime = dumpPathAndGetMtime(absPath.abs(), sink, defaultPathFilter);
|
||||
});
|
||||
storePath = store->addToStoreFromDump(*src, "source");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue