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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve path value documentation #10560

Merged
merged 3 commits into from May 6, 2024
Merged

Conversation

roberth
Copy link
Member

@roberth roberth commented Apr 19, 2024

Motivation

Reduce my anxiety levels when people discuss path value related code on the internet.
They're an important feature that deserves to be understood well.

This improves the description of path literals and path values to

  • be more accurate
  • explain their behavior, which is important info for why you should choose to use them
  • explains briefly that absolute path literals are best avoided.

Also this defines "base directory", which is a useful term when discussing path values, which are usually relative. I'll remove that commit if it's not easy to get into a good state.

Context

Priorities and Process

Add 馃憤 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@roberth roberth added documentation language The Nix expression language; parser, interpreter, primops, evaluation, etc labels Apr 19, 2024
@roberth roberth requested a review from edolstra as a code owner April 19, 2024 13:18

Paths are the preferred type for referring to local files.
This is thanks to the following properties:
- Path values are always in a canonical form, so that you are relieved from trailing slashes, `.` and `..`.
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately this isn't true, paths can have a trailing slash.

Copy link
Contributor

Choose a reason for hiding this comment

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

But why is this then:

nix-repl> a = /home/                   
error: path has a trailing slash

       at 芦string禄:1:2:

            1|  /home/
             |  ^

Copy link
Member

Choose a reason for hiding this comment

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

nix-repl> let x = "x"; in /home${x}  
/homex

nix-repl> let x = "x"; in /home/${x}
/home/x

I.e. /home/ is represented internally with a trailing slash, since canonicalizing it to /home would cause /home${x} to evaluate to /homex.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is internal to the /p/${e} expression and not observable as the result of a properly composable expression, right?
If it is, then I would expect that to be a bug.

At least these are fine:

nix-repl> /home${""}
/home

nix-repl> /home/${""}
/home

nix-repl> /home/${"/"}
/home

nix-repl> /home/${"////"}
/home

I should clarify that trailing slashes do matter in the literals.

doc/manual/src/glossary.md Outdated Show resolved Hide resolved
doc/manual/src/language/values.md Outdated Show resolved Hide resolved
doc/manual/src/language/values.md Outdated Show resolved Hide resolved
doc/manual/src/language/values.md Outdated Show resolved Hide resolved
- Path values are always in a canonical form, so that you are relieved from trailing slashes, `.` and `..`.
- Path literals are automatically resolved [relative to the file](@docroot@/glossary.md#gloss-base-directory).
- Path values are automatically copied into the Nix store when used in a string interpolation or concatenation.
- Tooling can recognize path literals and provide additional features, such as autocompletion, refactoring automation and jump-to-file.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- Tooling can recognize path literals and provide additional features, such as autocompletion, refactoring automation and jump-to-file.

This is hypothetical from the perspective of the Nix language

Copy link
Member Author

Choose a reason for hiding this comment

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

Users really do get to enjoy autocompletion in the repl already.

I don't know, should I be writing a guide "How to pick a Nix value representation for local files"?
That'd be quite absurd.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, this one's low impact, feel free to ignore then.

Comment on lines 104 to 116
A path literal must contain at least one slash to be recognised as such.
For instance, `builder.sh` is not a path:
it's parsed as an expression that selects the attribute `sh` from the variable `builder`.

Path literals may also refer to absolute paths by starting with a slash.
This is generally not recommended, because it makes the expression less portable.
In the case where a path literal is translated into an absolute path string for a configuration file, it is recommended to just use strings.
This avoids some confusion about whether files at that location will be used during evaluation,
and it avoids unintentional situations where some function might try to copy everything at the location into the store.

If the first component of a path is a `~`, it is interpreted such that the rest of the path were relative to the user's home directory.
For example, `~/foo` would be equivalent to `/home/edolstra/foo` for a user whose home directory is `/home/edolstra`.
Path literals that start with `~` are not allowed in [pure](@docroot@/command-ref/conf-file.md#conf-pure-eval) evaluation or flakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

I was recently thinking about moving the Nix language tutorial section on paths here, but I'd approach it a bit differently, and never find time for it. I really dislike the idea of perpetuating dense prose in the reference manual. But as we discussed on the other thread, doing things properly takes time no one has, and having something at all is probably better than nothing.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought we didn't write tutorials in the manual.
I wouldn't oppose it, because the tutorial would be scoped to the project nicely, and I suppose you have a good reason to change course?

- Tooling can recognize path literals and provide additional features, such as autocompletion, refactoring automation and jump-to-file.

A path literal must contain at least one slash to be recognised as such.
For instance, `builder.sh` is not a path:
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

@roberth roberth Apr 19, 2024

Choose a reason for hiding this comment

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

That would disrupt the flow for something that isn't even an example of a path.
Worse, when scanning the text, "Example: builder.sh" under Paths, that would suggest that it is a path.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right. I'm generally skeptical of this conversational tone that meanders between facts and counterfactuals. It would take me way too much time to unravel this with concrete suggestions for that text, so I don't know. See the other comment on using parts from nix.dev.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, let's postpone that then.

doc/manual/src/language/values.md Outdated Show resolved Hide resolved
Paths can be used in [string interpolation] and string concatenation.
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` from the same directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.

Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
Copy link
Contributor

Choose a reason for hiding this comment

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

Make a proper highlight

Copy link
Member Author

Choose a reason for hiding this comment

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

What makes a highlight proper?
Note that this was in the original text.

Paths can be used in [string interpolation] and string concatenation.
For instance, evaluating `"${./foo.txt}"` will cause `foo.txt` from the same directory to be copied into the Nix store and result in the string `"/nix/store/<hash>-foo.txt"`.

Note that the Nix language assumes that all input files will remain _unchanged_ while evaluating a Nix expression.
For example, assume you used a file path in an interpolated string during a `nix repl` session.
Copy link
Contributor

Choose a reason for hiding this comment

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

Make a proper example

Copy link
Member Author

Choose a reason for hiding this comment

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

I am not rewriting everything, sorry.

Copy link
Member Author

Choose a reason for hiding this comment

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

Rewriting everything blows up the scope of the PR.
Our priority should be to get improvements merged.

@fricklerhandwerk
Copy link
Contributor

The base directory part can stand on its own, we could merge that quickly instead of blocking on the lengthy prose.

doc/manual/src/language/values.md Outdated Show resolved Hide resolved
doc/manual/src/language/values.md Outdated Show resolved Hide resolved
roberth and others added 3 commits May 6, 2024 18:22
See NixOS#8738 for a more pointed
criticism of absolute paths.
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
@roberth roberth enabled auto-merge May 6, 2024 16:30
@roberth roberth merged commit cbafa1b into NixOS:master May 6, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation language The Nix expression language; parser, interpreter, primops, evaluation, etc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants