Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

domenkozar
Copy link
Member

  • 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
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.

lib/strings.nix Outdated
*/
isInStore = s:
(builtins.isString s || isPath s)
&& (builtins.substring 0 (builtins.stringLength builtins.storeDir) s) == builtins.storeDir;
Copy link
Member

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.

Copy link
Member Author

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
@@ -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;
Copy link
Member

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?

Copy link
Member

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?

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member

@Profpatsch Profpatsch left a 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
Copy link
Member

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.
Copy link
Member

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.
Copy link
Member

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;
Copy link
Member

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
Copy link
Member

@edolstra edolstra Nov 16, 2017

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.

Copy link
Member

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)..

Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand...

dhess added a commit to dhess/nixpkgs-lib-quixoftic that referenced this pull request Feb 20, 2018
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.
@mmahut
Copy link
Member

mmahut commented Aug 3, 2019

What is the status of this pull request?

@mmahut
Copy link
Member

mmahut commented Oct 5, 2019

Closing due to lack of activity, feel free re-open this if needed.

@mmahut mmahut closed this Oct 5, 2019
@domenkozar domenkozar deleted the lib+paths branch June 9, 2020 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants