diff options
author | Tom Bereknyei <tomberek@gmail.com> | 2023-08-19 17:03:31 -0400 |
---|---|---|
committer | lunaphied <lunaphied@lunaphied.me> | 2024-03-25 15:30:36 +0000 |
commit | 4494f9097f7959b2f7e63decf04a5bd592018836 (patch) | |
tree | 37db3dc35cb83ce9fb1f9794d63b31885a399174 | |
parent | d3d7489571baeb651d3843dba3b638621694c174 (diff) |
feat: notation to refer to no attribute search prefix
An attrPath prefix of "." indicates no need to try default attrPath prefixes. For example `nixpkgs#legacyPackages.x86_64-linux.ERROR` searches through
```
trying flake output attribute 'packages.x86_64-linux.legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute ''
trying flake output attribute 'legacyPackages.x86_64-linux.legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute 'legacyPackages.x86_64-linux'
trying flake output attribute 'legacyPackages.x86_64-linux.ERROR'
using cached attrset attribute 'legacyPackages.x86_64-linux'
```
And there is no way to specify that one does not want the automatic
search behavior. Now one can specify
`nixpkgs#.legacyPackages.x86_64-linux.ERROR` to only refer to the rooted
attribute path without any default injection of attribute search path or
system.
Change-Id: Iac1334e1470137b7ce11dcf845513810230638ec
(cherry picked from commit d4aed18883b361133607296fb6cd789c47427a38)
-rw-r--r-- | src/libcmd/installable-flake.cc | 4 | ||||
-rw-r--r-- | src/libcmd/installables.cc | 12 | ||||
-rw-r--r-- | tests/functional/flakes/flakes.sh | 4 |
3 files changed, 18 insertions, 2 deletions
diff --git a/src/libcmd/installable-flake.cc b/src/libcmd/installable-flake.cc index bb75b8ff0..615f70945 100644 --- a/src/libcmd/installable-flake.cc +++ b/src/libcmd/installable-flake.cc @@ -28,6 +28,10 @@ namespace nix { std::vector<std::string> InstallableFlake::getActualAttrPaths() { std::vector<std::string> res; + if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")){ + res.push_back(attrPaths.front().substr(1)); + return res; + } for (auto & prefix : prefixes) res.push_back(prefix + *attrPaths.begin()); diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index b40632887..4ffc9af24 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -302,6 +302,11 @@ void completeFlakeRefWithFragment( completionType = ctAttrs; auto fragment = prefix.substr(hash + 1); + std::string prefixRoot = ""; + if (fragment.starts_with(".")){ + fragment = fragment.substr(1); + prefixRoot = "."; + } auto flakeRefS = std::string(prefix.substr(0, hash)); auto flakeRef = parseFlakeRef(expandTilde(flakeRefS), absPath(".")); @@ -310,6 +315,9 @@ void completeFlakeRefWithFragment( auto root = evalCache->getRoot(); + if (prefixRoot == "."){ + attrPathPrefixes.clear(); + } /* Complete 'fragment' relative to all the attrpath prefixes as well as the root of the flake. */ @@ -334,7 +342,7 @@ void completeFlakeRefWithFragment( auto attrPath2 = (*attr)->getAttrPath(attr2); /* Strip the attrpath prefix. */ attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size()); - completions->add(flakeRefS + "#" + concatStringsSep(".", evalState->symbols.resolve(attrPath2))); + completions->add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", evalState->symbols.resolve(attrPath2))); } } } @@ -345,7 +353,7 @@ void completeFlakeRefWithFragment( for (auto & attrPath : defaultFlakeAttrPaths) { auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath)); if (!attr) continue; - completions->add(flakeRefS + "#"); + completions->add(flakeRefS + "#" + prefixRoot); } } } diff --git a/tests/functional/flakes/flakes.sh b/tests/functional/flakes/flakes.sh index 128f759ea..7781eb51b 100644 --- a/tests/functional/flakes/flakes.sh +++ b/tests/functional/flakes/flakes.sh @@ -79,6 +79,10 @@ nix registry add --registry $registry nixpkgs flake1 nix registry list | grep '^global' nix registry list | grepInverse '^user' # nothing in user registry +# Test fuzzy and exact flake attribute syntax. +expectStderr 1 nix eval flake1#ERROR | grepQuiet "error:.*does not provide attribute.*or 'ERROR'$" +expectStderr 1 nix eval flake1#.ERROR | grepQuiet "error:.*does not provide attribute 'ERROR'$" + # Test 'nix flake metadata'. nix flake metadata flake1 nix flake metadata flake1 | grepQuiet 'Locked URL:.*flake1.*' |