Skip to content

Commit cee13c7

Browse files
committed
Skip package sets that may not exist in older nixpkgs revisions.
When running nix-index on old nixpkgs, scopes like rPackages are missing, so instead of exiting with an error, this change issues an error to stderr and skips such package set. Motivation: while it's possible to use an older version of nix-index to create the index for older nixpkgs, newer nix-index is much more performant so it's useful to be able to use it.
1 parent 01a2423 commit cee13c7

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use crate::package::StorePath;
44

55
error_chain::error_chain! {
66
errors {
7-
QueryPackages {
7+
QueryPackages(set: Option<String>) {
88
description("query packages error")
9-
display("querying available packages failed")
9+
display("querying available packages in set '{}' failed", set.as_ref().unwrap_or(&".".to_string()))
1010
}
1111
FetchFiles(path: StorePath) {
1212
description("file listing fetch error")

src/listings.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,20 @@ pub fn fetch_listings<'a>(
157157
let all_paths = all_queries
158158
.par_iter()
159159
.flat_map_iter(|&(system, scope)| {
160-
nixpkgs::query_packages(nixpkgs, system, scope.as_deref(), show_trace)
161-
.map(|x| x.chain_err(|| ErrorKind::QueryPackages))
160+
nixpkgs::query_packages(nixpkgs, system, scope.as_deref(), show_trace).map(|x| {
161+
x.chain_err(|| ErrorKind::QueryPackages(scope.as_deref().map(|s| s.to_string())))
162+
})
162163
})
163-
.collect::<Result<_>>()?;
164+
.filter_map(|res| match res {
165+
Ok(path) => Some(path),
166+
Err(e) => {
167+
// Older versions of nixpkgs may not have all scopes, so we skip them instead
168+
// of completely bailing out.
169+
eprintln!("Error getting package set: {e}");
170+
None
171+
}
172+
})
173+
.collect::<Vec<_>>();
164174

165175
Ok(fetch_listings_impl(fetcher, jobs, all_paths))
166176
}

src/nixpkgs.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub fn query_packages(
6464
parser: None,
6565
child: None,
6666
cmd: Some(cmd),
67+
had_error: false,
6768
}
6869
}
6970

@@ -74,6 +75,7 @@ pub struct PackagesQuery<R: Read> {
7475
parser: Option<PackagesParser<R>>,
7576
child: Option<Child>,
7677
cmd: Option<Command>,
78+
had_error: bool,
7779
}
7880

7981
impl PackagesQuery<ChildStdout> {
@@ -125,6 +127,11 @@ impl Iterator for PackagesQuery<ChildStdout> {
125127
type Item = Result<StorePath, Error>;
126128

127129
fn next(&mut self) -> Option<Self::Item> {
130+
// if we emitted an error in the previous call to next,
131+
// there is nothing meaningful we can emit, so signal that we have no more elements to emit.
132+
if self.had_error {
133+
return None;
134+
}
128135
if let Err(e) = self.ensure_initialized() {
129136
return Some(Err(e));
130137
}
@@ -137,7 +144,10 @@ impl Iterator for PackagesQuery<ChildStdout> {
137144
//
138145
// If the subprocess returned an error, then the parser probably tried to parse garbage output
139146
// so we will ignore the parser error and instead return the error printed by the subprocess.
140-
v.map_err(|e| self.check_error().unwrap_or_else(|| Error::from(e)))
147+
v.map_err(|e| {
148+
self.had_error = true;
149+
self.check_error().unwrap_or_else(|| Error::from(e))
150+
})
141151
})
142152
.or_else(|| {
143153
self.parser = None;

0 commit comments

Comments
 (0)