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
lib: add isInStore and isPath, slighly change isStorePath #31715
Conversation
lib/strings.nix
Outdated
*/ | ||
isInStore = s: | ||
(builtins.isString s || isPath s) | ||
&& (builtins.substring 0 (builtins.stringLength builtins.storeDir) s) == builtins.storeDir; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use hasPrefix builtins.storeDir s
here, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
- isStorePath now returns true for paths - isPath returns true only when the type of value is path - isInStore just asserts that the path is prefixed with store dir
7897128
to
05f5ab7
Compare
@@ -219,8 +219,7 @@ rec { | |||
|
|||
path = mkOptionType { | |||
name = "path"; | |||
# Hacky: there is no ‘isPath’ primop. | |||
check = x: builtins.substring 0 1 (toString x) == "/"; | |||
check = x: isString x || isPath x; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering whether this was intended to be isString x && isPath x
. As-is, wouldn't some nonsense value like "$%^&*" be accepted, as long as it is a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As-is, wouldn't some nonsense value like "$%^&*" be accepted, as long as it is a string?
Yeah, that seems to be the case. Is that intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why arbitrary strings should be accepted as a path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this needs to allow (string or path type) paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would need to be (isString x && is absolute) || isPath x
. Will try to fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add tests (lib/tests/misc.nix
) for all changed functions? I’m not sure all examples are working as they should in the current implementation.
@@ -438,13 +438,53 @@ rec { | |||
=> true | |||
isStorePath pkgs.python | |||
=> true | |||
isStorePath ./types.nix | |||
=> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should have always been handled like this. I’d count it as a bug fix.
@@ -429,7 +429,7 @@ rec { | |||
*/ | |||
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n); | |||
|
|||
/* Check whether a value is a store path. | |||
/* Check whether a string or a path is a store path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s still a value, since we’re returning a bool for every possible value. I’d change the docs to:
/* Check whether a value is a store path.
Every literal path (e.g. `./foobar`) is a store path,
every string that points to a file directly under `buildins.storeDir` as well.
*/
&& builtins.substring 0 1 (toStringContext x) == "/" | ||
&& dirOf (toStringContext x) == builtins.storeDir; | ||
|
||
/* Check whether a string or a path is in the store. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, it’s really a check for any value. Otherwise you have to omit the isString
/isPath
check.
@@ -219,8 +219,7 @@ rec { | |||
|
|||
path = mkOptionType { | |||
name = "path"; | |||
# Hacky: there is no ‘isPath’ primop. | |||
check = x: builtins.substring 0 1 (toString x) == "/"; | |||
check = x: isString x || isPath x; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As-is, wouldn't some nonsense value like "$%^&*" be accepted, as long as it is a string?
Yeah, that seems to be the case. Is that intended?
isInStore "/home/me/whatever.nix" | ||
=> false | ||
isInStore ./types.nix | ||
=> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not make sense, given that toString ./types.nix
returns /local/directory/types.nix
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words, this function doesn't test whether something is in the store but whether it can be coerced to a store path in certain contexts (such as in a string anti-quotation)..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same could be argued that strings lose their context. It does coerce it to string (and thus import it to store), but it doesn't mean it can't be converted to another type which gets another meaning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand...
The nonStorePath type is the more interesting of the two; it should help prevent secrets from being written to the store inadvertently. Note that this is based somewhat on the proposal here: NixOS/nixpkgs#31715 but is a bit less ambitious.
What is the status of this pull request? |
Closing due to lack of activity, feel free re-open this if needed. |
Motivation for this change
Groundwork for #24288 (comment)
This adds better tooling to differentiate between string and path types. Also allows to see if path is in nix store or just a regular one.
I plan to add docs once we agree this is a good idea.