Skip to content

Commit b74aac5

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 6aed7e7 commit b74aac5

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

src/errors.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use crate::{hydra, nixpkgs, package::StorePath};
66

77
#[derive(Error, Debug)]
88
pub enum Error {
9-
#[error("querying available packages failed: {source}")]
9+
#[error("querying available packages in set {} failed: {source}", package_set.as_ref().unwrap_or(&".".to_string()))]
1010
QueryPackages {
11+
package_set: Option<String>,
1112
#[source]
1213
source: nixpkgs::Error,
1314
},
@@ -36,13 +37,13 @@ pub enum Error {
3637
#[error("writing the paths.cache file failed: {source}")]
3738
WritePathsCache {
3839
#[source]
39-
source: Box<dyn std::error::Error>,
40+
source: Box<dyn std::error::Error + Send>,
4041
},
4142
#[error("creating the database at '{path:?}' failed: {source}")]
4243
CreateDatabase {
4344
path: PathBuf,
4445
#[source]
45-
source: Box<dyn std::error::Error>,
46+
source: Box<dyn std::error::Error + Send>,
4647
},
4748
#[error("creating the directory for the database at '{path:?}' failed: {source}")]
4849
CreateDatabaseDir {

src/listings.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,23 @@ pub fn fetch<'a>(
166166
let all_paths = all_queries
167167
.par_iter()
168168
.flat_map_iter(|&(system, scope)| {
169-
nixpkgs::query_packages(nixpkgs, system, scope.as_deref(), show_trace)
169+
nixpkgs::query_packages(nixpkgs, system, scope.as_deref(), show_trace).map(|x| {
170+
x.map_err(|e| Error::QueryPackages {
171+
package_set: scope.as_deref().map(|s| s.to_string()),
172+
source: e,
173+
})
174+
})
170175
})
171-
.collect::<std::result::Result<_, nixpkgs::Error>>()
172-
.map_err(|e| Error::QueryPackages { source: e })?;
176+
.filter_map(|res| match res {
177+
Ok(path) => Some(path),
178+
Err(e) => {
179+
// Older versions of nixpkgs may not have all scopes, so we skip them instead
180+
// of completely bailing out.
181+
eprintln!("Error getting package set: {e}");
182+
None
183+
}
184+
})
185+
.collect::<Vec<_>>();
173186

174187
Ok(fetch_listings_impl(fetcher, jobs, all_paths))
175188
}

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)