Skip to content

Commit 8b483c2

Browse files
committed
Some changes, also run fmt
1 parent 34f2326 commit 8b483c2

32 files changed

+288
-166
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
target
22
.direnv
33
result*
4+
by-name-config-generated.json

by-name-config.json

Lines changed: 0 additions & 16 deletions
This file was deleted.

by-name-config.nix

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Configure by-name directories in this file.
2+
# Then build with `nix-build -A build` to automatically generate by-name-config-generated.json
3+
# (Or, to generate manually, `nix-instantiate --eval --json --strict by-name-config.nix > by-name-config-generated.json`)
4+
{
5+
by_name_dirs = [
6+
{
7+
path = "pkgs/development/python-modules/by-name";
8+
attr_path_regex = "^(python3\\d*Packages|python3\\d*.pkgs)\\..*";
9+
unversioned_attr_prefix = "python3Packages";
10+
}
11+
{
12+
path = "pkgs/development/tcl-modules/by-name";
13+
attr_path_regex = "^(tcl\\d*Packages)\\..*";
14+
unversioned_attr_prefix = "tclPackages";
15+
}
16+
{
17+
path = "pkgs/by-name";
18+
attr_path_regex = ".*"; # There must be exactly one wildcard. All non-wildcard regexes must be mutually exclusive.
19+
unversioned_attr_prefix = ""; # Ditto for this field.
20+
}
21+
];
22+
}

package.nix

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ rustPlatform.buildRustPackage {
5050
env.NIXPKGS_VET_NIX_PACKAGE = lib.getBin nix;
5151
env.NIXPKGS_VET_NIXPKGS_LIB = "${path}/lib";
5252

53+
postBuild = ''
54+
nix-instantiate --eval --json --strict ${./by-name-config.nix} > by-name-config-generated.json
55+
'';
56+
5357
checkPhase = ''
5458
# This path will be symlinked to the current version that is being tested
5559
nixPackage=$(mktemp -d)/nix
@@ -60,8 +64,6 @@ rustPlatform.buildRustPackage {
6064
# This is what nixpkgs-vet uses
6165
export NIXPKGS_VET_NIX_PACKAGE=$nixPackage
6266
63-
cp ${./by-name-config.json} by-name-config.json
64-
6567
${lib.concatMapStringsSep "\n" (nix: ''
6668
ln -s ${lib.getBin nix} "$nixPackage"
6769
echo "Testing with $(nix --version)"

src/eval.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ use anyhow::Context;
66
use relative_path::RelativePathBuf;
77
use serde::Deserialize;
88

9-
use crate::NixFileStore;
109
use crate::nix_file::CallPackageArgumentInfo;
1110
use crate::problem::{
1211
npv_100, npv_101, npv_102, npv_103, npv_104, npv_105, npv_106, npv_107, npv_108, npv_120,
1312
};
1413
use crate::ratchet::RatchetState::{Loose, Tight};
15-
use crate::structure::{self, Config};
14+
use crate::structure::{self, ByNameDir, Config};
1615
use crate::validation::ResultIteratorExt as _;
1716
use crate::validation::{self, Validation::Success};
17+
use crate::NixFileStore;
1818
use crate::{location, ratchet};
1919

2020
const EVAL_NIX: &[u8] = include_bytes!("eval.nix");
@@ -159,6 +159,7 @@ pub fn check_values(
159159
nixpkgs_path: &Path,
160160
nix_file_store: &mut NixFileStore,
161161
package_names: &[String],
162+
by_name_dir: &ByNameDir,
162163
config: &Config,
163164
) -> validation::Result<BTreeMap<String, ratchet::Package>> {
164165
let work_dir = tempfile::Builder::new()
@@ -169,6 +170,8 @@ pub fn check_values(
169170
// Canonicalize the path so that if a symlink were returned, we wouldn't ask Nix to follow it.
170171
let work_dir_path = work_dir.path().canonicalize()?;
171172

173+
println!("package_names: {}", package_names.join(", "));
174+
172175
// Write the list of packages we need to check into a temporary JSON file.
173176
let package_names_path = work_dir_path.join("package-names.json");
174177
let package_names_file = fs::File::create(&package_names_path)?;
@@ -224,7 +227,11 @@ pub fn check_values(
224227

225228
if !result.status.success() {
226229
// Early return in case evaluation fails
227-
return Ok(npv_120::NixEvalError::new(String::from_utf8_lossy(&result.stderr)).into());
230+
return Ok(npv_120::NixEvalError::new(
231+
String::from_utf8_lossy(&result.stderr),
232+
by_name_dir.clone(),
233+
)
234+
.into());
228235
}
229236

230237
// Parse the resulting JSON value
@@ -247,13 +254,15 @@ pub fn check_values(
247254
&attribute_name,
248255
non_by_name_attribute,
249256
config,
257+
by_name_dir,
250258
)?,
251259
Attribute::ByName(by_name_attribute) => by_name(
252260
nix_file_store,
253261
nixpkgs_path,
254262
&attribute_name,
255263
by_name_attribute,
256264
config,
265+
by_name_dir,
257266
)?,
258267
};
259268
Ok::<_, anyhow::Error>(check_result.map(|value| (attribute_name.clone(), value)))
@@ -271,16 +280,18 @@ fn by_name(
271280
attribute_name: &str,
272281
by_name_attribute: ByNameAttribute,
273282
config: &Config,
283+
by_name_dir: &ByNameDir,
274284
) -> validation::Result<ratchet::Package> {
275-
// At this point we know that `pkgs/by-name/fo/foo/package.nix` has to exists. This match
285+
println!("attribute_name: {attribute_name}");
286+
// At this point we know that `pkgs/by-name/fo/foo/package.nix` has to exist. This match
276287
// decides whether the attribute `foo` is defined accordingly and whether a legacy manual
277288
// definition could be removed.
278289
let manual_definition_result = match by_name_attribute {
279290
// The attribute is missing.
280291
ByNameAttribute::Missing => {
281292
// This indicates a bug in the `pkgs/by-name` overlay, because it's supposed to
282293
// automatically define attributes in a `by-name` directory
283-
npv_100::ByNameUndefinedAttribute::new(attribute_name).into()
294+
npv_100::ByNameUndefinedAttribute::new(attribute_name, by_name_dir.clone()).into()
284295
}
285296
// The attribute exists
286297
ByNameAttribute::Existing(AttributeInfo {
@@ -294,7 +305,7 @@ fn by_name(
294305
//
295306
// We can't know whether the attribute is automatically or manually defined for sure,
296307
// and while we could check the location, the error seems clear enough as is.
297-
npv_101::ByNameNonDerivation::new(attribute_name).into()
308+
npv_101::ByNameNonDerivation::new(attribute_name, by_name_dir.clone()).into()
298309
}
299310
// The attribute exists
300311
ByNameAttribute::Existing(AttributeInfo {
@@ -310,7 +321,7 @@ fn by_name(
310321
let is_derivation_result = if is_derivation {
311322
Success(())
312323
} else {
313-
npv_101::ByNameNonDerivation::new(attribute_name).into()
324+
npv_101::ByNameNonDerivation::new(attribute_name, by_name_dir.clone()).into()
314325
};
315326

316327
// If the definition looks correct
@@ -366,6 +377,7 @@ fn by_name(
366377
definition,
367378
location,
368379
config,
380+
by_name_dir,
369381
)
370382
} else {
371383
// If manual definitions don't have a location, it's likely `mapAttrs`'d
@@ -401,13 +413,15 @@ fn by_name_override(
401413
definition: String,
402414
location: location::Location,
403415
config: &Config,
416+
by_name_dir: &ByNameDir,
404417
) -> validation::Validation<ratchet::RatchetState<ratchet::ManualDefinition>> {
405418
let Some(syntactic_call_package) = optional_syntactic_call_package else {
406419
// Something like `<attr> = foo`
407420
return npv_104::ByNameOverrideOfNonSyntacticCallPackage::new(
408421
attribute_name,
409422
location,
410423
definition,
424+
by_name_dir.clone(),
411425
)
412426
.into();
413427
};
@@ -418,13 +432,19 @@ fn by_name_override(
418432
attribute_name,
419433
location,
420434
definition,
435+
by_name_dir.clone(),
421436
)
422437
.into();
423438
}
424439

425440
let Some(actual_package_path) = syntactic_call_package.relative_path else {
426-
return npv_108::ByNameOverrideContainsEmptyPath::new(attribute_name, location, definition)
427-
.into();
441+
return npv_108::ByNameOverrideContainsEmptyPath::new(
442+
attribute_name,
443+
location,
444+
definition,
445+
by_name_dir.clone(),
446+
)
447+
.into();
428448
};
429449

430450
let expected_by_name_dir = structure::expected_by_name_dir_for_package(attribute_name, config);
@@ -436,6 +456,7 @@ fn by_name_override(
436456
attribute_name,
437457
actual_package_path,
438458
location,
459+
by_name_dir.clone(),
439460
)
440461
.into();
441462
}
@@ -444,8 +465,13 @@ fn by_name_override(
444465
// continue to be allowed. This is the state to migrate away from.
445466
if syntactic_call_package.empty_arg {
446467
Success(Loose(
447-
npv_107::ByNameOverrideContainsEmptyArgument::new(attribute_name, location, definition)
448-
.into(),
468+
npv_107::ByNameOverrideContainsEmptyArgument::new(
469+
attribute_name,
470+
location,
471+
definition,
472+
by_name_dir.clone(),
473+
)
474+
.into(),
449475
))
450476
} else {
451477
// This is the state to migrate to.
@@ -461,9 +487,10 @@ fn handle_non_by_name_attribute(
461487
attribute_name: &str,
462488
non_by_name_attribute: NonByNameAttribute,
463489
config: &Config,
490+
by_name_dir: &ByNameDir,
464491
) -> validation::Result<ratchet::Package> {
465-
use NonByNameAttribute::EvalSuccess;
466492
use ratchet::RatchetState::{Loose, NonApplicable, Tight};
493+
use NonByNameAttribute::EvalSuccess;
467494

468495
// The ratchet state whether this attribute uses a `by-name` directory
469496
//
@@ -573,7 +600,7 @@ fn handle_non_by_name_attribute(
573600
_ => {
574601
// Otherwise, the path is outside a `by-name` directory, which means it can be
575602
// migrated.
576-
Loose((syntactic_call_package, location.file))
603+
Loose((syntactic_call_package, location.file, by_name_dir.to_owned()))
577604
}
578605
}
579606
}

src/main.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ mod validation;
2222

2323
use anyhow::Context as _;
2424
use clap::Parser;
25-
use relative_path::{RelativePath, RelativePathBuf};
2625
use std::collections::BTreeMap;
2726
use std::path::{Path, PathBuf};
2827
use std::process::ExitCode;
@@ -32,7 +31,7 @@ use std::{panic, thread};
3231
use crate::nix_file::NixFileStore;
3332
use crate::problem::Problem;
3433
use crate::status::{ColoredStatus, Status};
35-
use crate::structure::{Config, check_structure, read_config};
34+
use crate::structure::{check_structure, read_config, ByNameDir, Config};
3635
use crate::validation::Validation::{Failure, Success};
3736

3837
/// Program to check the validity of pkgs/by-name
@@ -77,15 +76,16 @@ fn main() -> ExitCode {
7776
/// - `base_nixpkgs`: Path to the base Nixpkgs to run ratchet checks against.
7877
/// - `main_nixpkgs`: Path to the main Nixpkgs to check.
7978
fn process(base_nixpkgs: &Path, main_nixpkgs: &Path, config: &Config) -> Status {
80-
let by_name_dir_paths: Vec<RelativePathBuf> =
81-
config.by_name_dirs.iter().map(|x| x.path.clone()).collect();
79+
let by_name_dirs: &Vec<ByNameDir> = &config.by_name_dirs;
8280
let mut thread_results: Vec<Status> = vec![];
8381
thread::scope(|s| {
8482
let mut threads: Vec<ScopedJoinHandle<Status>> = vec![];
85-
for path in by_name_dir_paths {
86-
let new_thread =
87-
s.spawn(move || process_by_name_dir(base_nixpkgs, main_nixpkgs, &path, config));
88-
threads.push(new_thread);
83+
for dir in by_name_dirs {
84+
if dir.path != "pkgs/by-name" {
85+
let new_thread =
86+
s.spawn(move || process_by_name_dir(base_nixpkgs, main_nixpkgs, dir, config));
87+
threads.push(new_thread);
88+
}
8989
}
9090
for thread in threads {
9191
thread_results.push(thread.join().unwrap())
@@ -158,7 +158,7 @@ fn process(base_nixpkgs: &Path, main_nixpkgs: &Path, config: &Config) -> Status
158158
fn process_by_name_dir(
159159
base_nixpkgs: &Path,
160160
main_nixpkgs: &Path,
161-
by_name_dir: &RelativePath,
161+
by_name_dir: &ByNameDir,
162162
config: &Config,
163163
) -> Status {
164164
let (main_result, base_result) = thread::scope(|s| {
@@ -206,7 +206,7 @@ fn process_by_name_dir(
206206
/// ratchet check against another result.
207207
fn check_nixpkgs(
208208
nixpkgs_path: &Path,
209-
by_name_subpath: &RelativePath,
209+
by_name_dir: &ByNameDir,
210210
config: &Config,
211211
) -> validation::Result<ratchet::Nixpkgs> {
212212
let nixpkgs_path = nixpkgs_path.canonicalize().with_context(|| {
@@ -219,15 +219,21 @@ fn check_nixpkgs(
219219
let mut nix_file_store = NixFileStore::default();
220220

221221
let package_result = {
222-
if !nixpkgs_path.join(by_name_subpath.as_str()).exists() {
222+
if !nixpkgs_path.join(by_name_dir.path.as_str()).exists() {
223223
// No pkgs/by-name directory, always valid
224224
Success(BTreeMap::new())
225225
} else {
226-
let structure = check_structure(&nixpkgs_path, &mut nix_file_store, by_name_subpath)?;
226+
let structure = check_structure(&nixpkgs_path, &mut nix_file_store, by_name_dir)?;
227227

228228
// Only if we could successfully parse the structure, we do the evaluation checks
229229
structure.result_map(|package_names| {
230-
eval::check_values(&nixpkgs_path, &mut nix_file_store, package_names.as_slice(), config)
230+
eval::check_values(
231+
&nixpkgs_path,
232+
&mut nix_file_store,
233+
package_names.as_slice(),
234+
by_name_dir,
235+
config,
236+
)
231237
})?
232238
}
233239
};
@@ -249,7 +255,7 @@ mod tests {
249255

250256
use anyhow::Context;
251257
use pretty_assertions::StrComparison;
252-
use tempfile::{TempDir, tempdir_in};
258+
use tempfile::{tempdir_in, TempDir};
253259

254260
use crate::structure;
255261

@@ -369,7 +375,7 @@ mod tests {
369375
process(
370376
&base_nixpkgs,
371377
&main_path,
372-
&structure::read_config(Path::new("by-name-config.json")),
378+
&structure::read_config(Path::new("by-name-config-generated.json")),
373379
)
374380
});
375381

src/nix_file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use relative_path::RelativePathBuf;
77
use rnix::ast;
88
use rnix::ast::Expr;
99
use rnix::ast::HasEntry;
10+
use rowan::ast::AstNode;
1011
use rowan::TextSize;
1112
use rowan::TokenAtOffset;
12-
use rowan::ast::AstNode;
13-
use std::collections::HashMap;
1413
use std::collections::hash_map::Entry;
14+
use std::collections::HashMap;
1515
use std::fs::read_to_string;
1616
use std::path::Path;
1717
use std::path::PathBuf;

0 commit comments

Comments
 (0)