Skip to content

Commit 0e892a2

Browse files
committed
Parse flake references in NIX_PATH
Now, `NIX_PATH=nixpkgs:flake:nixpkgs` won't be treated as a relative path. Consequently, changing the current directory wouldn't invalidate the cache.
1 parent bb4c221 commit 0e892a2

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ fn run_from_args(args: Vec<OsString>) {
387387
current_dir().expect("Can't get PWD")
388388
} else if arg.as_bytes().starts_with(b"<")
389389
&& arg.as_bytes().ends_with(b">")
390-
|| nix_path::is_uri(arg.as_bytes())
390+
|| nix_path::is_pseudo_url(arg.as_bytes())
391391
{
392392
// in: nix-shell '<foo>'
393393
// out: cd /var/empty; nix-shell '<foo>'

src/nix_path.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ fn is_relative(b: &[u8]) -> bool {
1919
.position(|&c| c == b'=')
2020
.map(|x| x + 1)
2121
.unwrap_or(0);
22-
b.get(pos) != Some(&b'/') && !is_uri(&b[pos..])
22+
b.get(pos) != Some(&b'/') && !is_pseudo_url(&b[pos..])
2323
}
2424

25-
/// Reference: https://github.com/NixOS/nix/blob/2.3.10/src/libexpr/eval.cc#L242-L277
25+
/// Reference: https://github.com/NixOS/nix/blob/2.23.0/src/libexpr/eval-settings.cc#L9-L45
2626
fn parse_nix_path(s: &[u8]) -> Vec<&[u8]> {
2727
let mut res = Vec::new();
2828
let mut p = 0;
@@ -45,7 +45,7 @@ fn parse_nix_path(s: &[u8]) -> Vec<&[u8]> {
4545
}
4646

4747
if s[p] == b':' {
48-
if is_uri(&s[start2..]) {
48+
if is_pseudo_url(&s[start2..]) {
4949
p += 1;
5050
while p < s.len() && s[p] != b':' {
5151
p += 1;
@@ -63,8 +63,8 @@ fn parse_nix_path(s: &[u8]) -> Vec<&[u8]> {
6363
res
6464
}
6565

66-
/// Reference: https://github.com/NixOS/nix/blob/2.3.10/src/libstore/download.cc#L936-L943
67-
pub fn is_uri(s: &[u8]) -> bool {
66+
/// Reference: https://github.com/NixOS/nix/blob/2.23.0/src/libexpr/eval-settings.cc#L79-L86
67+
pub fn is_pseudo_url(s: &[u8]) -> bool {
6868
let prefixes = &[
6969
"channel:",
7070
"http://",
@@ -74,6 +74,7 @@ pub fn is_uri(s: &[u8]) -> bool {
7474
"git://",
7575
"s3://",
7676
"ssh://",
77+
"flake:", // Not in the original code
7778
];
7879
prefixes
7980
.iter()
@@ -82,28 +83,41 @@ pub fn is_uri(s: &[u8]) -> bool {
8283

8384
#[cfg(test)]
8485
mod tests {
85-
use super::{is_relative, parse_nix_path};
86+
use super::*;
87+
8688
macro_rules! v {
8789
( $($a:literal),* ) => {{
8890
vec![ $( Vec::<u8>::from($a as &[_])),* ]
8991
}}
9092
}
93+
9194
#[test]
92-
fn it_works() {
95+
fn test_parse_nix_path() {
9396
assert_eq!(parse_nix_path(b"foo:bar:baz"), v![b"foo", b"bar", b"baz"]);
9497
assert_eq!(
9598
parse_nix_path(b"foo:bar=something:baz"),
9699
v![b"foo", b"bar=something", b"baz"]
97100
);
98101
assert_eq!(
99-
parse_nix_path(b"foo:bar=https://something:baz"),
100-
v![b"foo", b"bar=https://something", b"baz"]
102+
parse_nix_path(
103+
b"foo:bar=https://something:baz=flake:something:qux"
104+
),
105+
v![
106+
b"foo",
107+
b"bar=https://something",
108+
b"baz=flake:something",
109+
b"qux"
110+
]
101111
);
112+
}
102113

114+
#[test]
115+
fn test_is_relative() {
103116
assert!(is_relative(b"foo"));
104117
assert!(is_relative(b"foo=bar"));
105118
assert!(!is_relative(b"http://foo"));
106119
assert!(!is_relative(b"foo=/bar"));
107120
assert!(!is_relative(b"foo=http://bar"));
121+
assert!(!is_relative(b"foo=flake:bar"));
108122
}
109123
}

0 commit comments

Comments
 (0)