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

builtins.toPath does not return a path #1074

Closed
veprbl opened this issue Sep 30, 2016 · 6 comments
Closed

builtins.toPath does not return a path #1074

veprbl opened this issue Sep 30, 2016 · 6 comments
Assignees

Comments

@veprbl
Copy link
Member

veprbl commented Sep 30, 2016

Despite documentation saying

Convert the string value s into a path value. The string s must represent an
absolute path (i.e., must start with /).  The path need not exist. The
resulting path is canonicalised, e.g., builtins.toPath "//foo/xyzzy/../bar/"
returns /foo/bar.

I get

nix-repl> builtins.toPath "/tmp"
"/tmp"
nix-repl> builtins.typeOf (builtins.toPath "/tmp")
"string"

I see that this was already requested in #47 , but then later reverted in 17dc306 .

I see that most of the uses of toPath in nixpkgs employ a hack like

./. + builtins.toPath "/path/to/something"

which works.
I've also tried to re-revert the original patch and evaluate nixpkgs and the only thing that seems to be broken is texlive fails the evaluation

error: string `/nix/store/whrg59jzykznma6xjjajpckf4vq79cxj-texlive-cm-super-2015' cannot refer to other paths

This I don't know how to fix.
Also lib.isStorePath needs a simple fix to wrap the builtins.storeDir with builtins.toPath call.

@alexeymuranov
Copy link

alexeymuranov commented Feb 25, 2017

Probably related:

builtins.toFile name s

Store the string s in a file in the Nix store and return its path. [...]

It would be the expected natural behaviour for me that it return a path object.

However, builtins.toFile actually returns the path as a string.

@domenkozar
Copy link
Member

domenkozar commented Mar 22, 2017

The gist of this issue:

nix-repl> :t ./. + "a"
a path

:t builtins.toPath "/a"
a string

:t builtins.toFile "foo" "a"
a string

Workaround is to use:

  toPath = s: ./. + s

@Warbo
Copy link
Contributor

Warbo commented Apr 26, 2018

Here's an asPath function I've used as a workaround for absolute paths (those not starting at ./.). It takes the path ./., counts how many / it contains, appends that many /.. to the end, then appends the given path:

with builtins;
with lib;
with rec {
  herePath   = ./.;
  hereString = toString herePath;
  hereDepth  = length (filter (x: x == "/") (stringToCharacters hereString));
  upDots     = concatStringsSep "/" (map (_: "..") (range 1 hereDepth));
  rootPath   = ./. + "/${upDots}";

  stillNeeded  = typeOf (toPath herePath) == "string";
  obsoleteWarn = x:
    if stillNeeded
       then x
       else trace "WARNING: toPath makes paths, is asPath now redundant?" x;

  go = path: if typeOf path == "path"
                then path
                else rootPath + "${path}";
};

assert   typeOf rootPath == "path"       || abort "rootPath should be a path, got ${typeOf rootPath}";
assert toString rootPath == "/"          || abort "rootPath should be /, got ${toString rootPath}";
assert   typeOf (go ./.) == "path"       || abort "asPath of a path should produce a path, got ${typeOf (go ./.)}";
assert toString (go ./.) == toString ./. || abort "asPath result ${toString (go ./.)} didn't match input ${toString ./.}";
obsoleteWarn go

@veprbl
Copy link
Member Author

veprbl commented May 25, 2018

@Warbo You can just write rootPath = /.;.

@veprbl
Copy link
Member Author

veprbl commented May 25, 2018

Btw toPath is being phased out from nixpkgs in NixOS/nixpkgs#40937

@Warbo
Copy link
Contributor

Warbo commented May 27, 2018

@veprbl Hah, never thought to check that! Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants