I thought the nix path type was just a data type to handle constructing paths [relative to the current source file, optionally], but it this made me confused:
nix-repl> ./dotfiles
/home/juliano/dotfiles
nix-repl> "${./dotfiles}"
"/nix/store/3wx89z1lm6p1i6hn76v6j1wjhpcb2ynm-dotfiles"
Does using the path type automatically map or import some [relative] path into the nix store?
Bonus wat I’d love some help understanding:
nix-repl> "${./dotfiles/homedir/.bash_profile}"
error: The path name '.bash_profile' is invalid: it is illegal to start the name with a period. Path names are alphanumeric and can include the symbols +-._?= and must not begin with a period. Note: If '.bash_profile' is a source file and you cannot rename it on disk, builtins.path { name = ... } can be used to give it an alternative name.
1 Like
Yea, ./dotfiles
has type path
:
nix-repl> builtins.typeOf ./dotfiles
"path"
Paths just have some unique behavior when it comes to strings. When a path is interpolated into a string or used as a derivation argument or something, Nix automatically copies that path into the store and interpolates that path instead.
nix-repl> "${./foo}"
"/nix/store/1hnsi1lbhwq0dzlikx3r69pzhhk44bnp-foo"
nix-repl> builtins.typeOf "${./foo}"
"string"
But finally, you can actually coax Nix into putting the original path into a string with toString.
nix-repl> toString ./dotfiles
"/home/will/dotfiles"
nix-repl> typeOf (toString ./dotfiles)
"string"
The error message is fairly self explanatory. Nix store paths have certain restrictions on their names. One of them is that the part immediately after the hash can’t begin with a period. You can use builtins.path { name = "bash_profile"; path = ./dotfiles/homedir/.bash_profile; }
instead, as there is no period at the beginning of the name
argument.
1 Like