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

Evaluate nix-shell -i args relative to script #5088

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

matthewbauer
Copy link
Member

When writing a shebang script, you expect your path to be relative to
the script, not the cwd. We previously handled this correctly for
relative file paths, but not for expressions.

This handles both -p & -E args. My understanding is this should be
what we want in any cases I can think of - people run scripts from
many different working directories. @edolstra is there any reason to
handle -p args differently in this case?

Fixes #4232

@arobertn
Copy link

What about the -I arg (also mentioned in #4232)? E.g. in case:

#!/usr/bin/env nix-shell
#! nix-shell -I nixpkgs=../nix/nixpkgs.nix --pure -p <pkgs...>

Or is there a preferred alternative way to set the search path?

@stale
Copy link

stale bot commented Jun 12, 2022

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Jun 12, 2022
@lf-
Copy link
Member

lf- commented Aug 9, 2022

Can this get reviewed? This still is an issue in Nix 2.9.1.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-03-03-nix-team-meeting-minutes-37/25998/1

Copy link
Contributor

@tomberek tomberek left a comment

Choose a reason for hiding this comment

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

This is a net-positive change. Please add release notes as this is a behavior change.

@Ericson2314 Ericson2314 added the idea approved The given proposal has been discussed and approved by the Nix team. An implementation is welcome. label Jun 14, 2023
@Ericson2314
Copy link
Member

Fixed conflicts, but this also needs tests.

@fricklerhandwerk fricklerhandwerk marked this pull request as draft June 19, 2023 11:30
@fricklerhandwerk
Copy link
Contributor

Please un-draft when ready, this is easier for maintainers to keep overview.

@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Nov 26, 2023
@tomberek
Copy link
Contributor

tomberek commented Nov 26, 2023

@matthewbauer I added tests and notes, let me know if thit is what you intended
(also pinging @lf- for visibility )

Fixes: #5431

I have some hesitation due to the this being a change in behavior for something that has been around for a while. (also, see the new nix-command shebang just released)

@tomberek tomberek marked this pull request as ready for review November 27, 2023 13:18
@tomberek
Copy link
Contributor

The worry is someone may have started to depend on these being relative to the call-site. Unfortunate, but might need a flag to control the behavior for the legacy CLI, "--relative"?

The new nix-command should not have this design oddity.

@lf-
Copy link
Member

lf- commented Nov 27, 2023

The worry is someone may have started to depend on these being relative to the call-site. Unfortunate, but might need a flag to control the behavior for the legacy CLI, "--relative"?

I think this is improbable and a bit of a bike shed. The workarounds (haskell plus bash polyglot! horrible) that people have had to apply would not be broken by this, as they start nix-shell in the same directory every time. I cannot see any conceivable reason someone would want the old behaviour: somehow you would be evaluating a script with respect to the current directory's default.nix?

That feels like a use case so contrived I doubt anyone has actually tried it, compared to the 99% use case that doesn't work today and I don't believe the new CLI supports at all.

matthewbauer and others added 2 commits November 27, 2023 14:40
When writing a shebang script, you expect your path to be relative to
the script, not the cwd. We previously handled this correctly for
relative file paths, but not for expressions.

This handles both -p & -E args. My understanding is this should be
what we want in any cases I can think of - people run scripts from
many different working directories. @edolstra is there any reason to
handle -p args differently in this case?

Fixes NixOS#4232
@tomberek
Copy link
Contributor

It seems that this would break (not difficult to fix): https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/ruby-modules/with-packages/test.rb#L61

I am slightly inclined to merge as-is due the niche nature of the breakage, but the proposal to add "--relative" was mentioned during discussion and I thought it worth bringing up for additional comments.

@fricklerhandwerk
Copy link
Contributor

Strongly in favor of merging and deferring backwards compatibility hacks to the improbable case of a spacebar heating outcry.

Copy link
Contributor

@fricklerhandwerk fricklerhandwerk left a comment

Choose a reason for hiding this comment

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

Some clarifications, because I had a hard time untangling what the release notes were trying to convey.

@roberth are we holding it correctly? Seems weird that there are two places for release notes now.

doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
prs: #5088
description: {

`nix-shell` shebangs use relative paths for files, but expressions were still evaluated using the current working directory. The new behavior is that evalutations are performed relative to the script.
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
`nix-shell` shebangs use relative paths for files, but expressions were still evaluated using the current working directory. The new behavior is that evalutations are performed relative to the script.
`nix-shell` shebangs use the script file's location to resolve relative paths to files passed as command line arguments, but expression arguments were evaluated using the current working directory as a base path.
The new behavior is that Nix language expressions passed to `nix-shell` when used in a `#!` context are now evaluated relative to the script's file system location.

Copy link
Member

Choose a reason for hiding this comment

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

This is a breaking change for example if you have a repo with a scripts directory and you invoke them as

$ ./scripts/foo

in which case the foo script likely has a workaround for this issue,

#!/usr/bin/env nix-shell
#!nix-shell --expr 'import ./scripts/shell.nix { withBar = true; }'

which will cause it to break when Nix is updated to a version after this PR.

error: getting status of '/home/user/src/unicorn/scripts/scripts/shell.nix': No such file or directory

Note the double scripts/.

I don't know if we should break an established command like this.
We should take this seriously and add --relative to opt in to the new behavior.
For what it's worth, it's also a way to "declare" that a recent Nix is needed by the script.

Copy link
Contributor

Choose a reason for hiding this comment

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

@roberth here's an attempt at adding a new "--relative" flag: 2fd7ee2

prs: #5088
description: {

`nix-shell` shebangs use relative paths for files, but expressions were still evaluated using the current working directory. The new behavior is that evalutations are performed relative to the script.
Copy link
Member

Choose a reason for hiding this comment

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

This is a breaking change for example if you have a repo with a scripts directory and you invoke them as

$ ./scripts/foo

in which case the foo script likely has a workaround for this issue,

#!/usr/bin/env nix-shell
#!nix-shell --expr 'import ./scripts/shell.nix { withBar = true; }'

which will cause it to break when Nix is updated to a version after this PR.

error: getting status of '/home/user/src/unicorn/scripts/scripts/shell.nix': No such file or directory

Note the double scripts/.

I don't know if we should break an established command like this.
We should take this seriously and add --relative to opt in to the new behavior.
For what it's worth, it's also a way to "declare" that a recent Nix is needed by the script.

@roberth
Copy link
Member

roberth commented Nov 27, 2023

I think it's great that we don't dogmatically only work on the new CLI, but we should take the old CLI more seriously when we change it.

@fricklerhandwerk
Copy link
Contributor

fricklerhandwerk commented Nov 27, 2023

Agreed on being especially careful about stable commands, but we also quite clearly said that what's obviously a bug (in the sense of an implementation error rather than a flawed design) should be just fixed. This is the case here. The current behavior is unintentionally inconsistent.

@roberth
Copy link
Member

roberth commented Nov 27, 2023

I'm not opposed to the change, only to the fact that it's currently not opt-in.

Do you want more #9412? Because that's how you get more #9412.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug idea approved The given proposal has been discussed and approved by the Nix team. An implementation is welcome. with-tests Issues related to testing. PRs with tests have some priority
Projects
Status: 🏁 Review
Development

Successfully merging this pull request may close these issues.

nix-shell shebang does not interpret -E relative to script dir
8 participants