tests.nixpkgs-check-by-name: Use RelativePath for relative paths
Makes the code easier to understand and less error-prone
This commit is contained in:
parent
7858f06288
commit
5981aff212
6 changed files with 158 additions and 153 deletions
|
@ -8,6 +8,7 @@ use crate::utils;
|
|||
use crate::validation::ResultIteratorExt as _;
|
||||
use crate::validation::{self, Validation::Success};
|
||||
use crate::NixFileStore;
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
|
@ -56,18 +57,15 @@ struct Location {
|
|||
|
||||
impl Location {
|
||||
// Returns the [file] field, but relative to Nixpkgs
|
||||
fn relative_file(&self, nixpkgs_path: &Path) -> anyhow::Result<PathBuf> {
|
||||
Ok(self
|
||||
.file
|
||||
.strip_prefix(nixpkgs_path)
|
||||
.with_context(|| {
|
||||
fn relative_file(&self, nixpkgs_path: &Path) -> anyhow::Result<RelativePathBuf> {
|
||||
let path = self.file.strip_prefix(nixpkgs_path).with_context(|| {
|
||||
format!(
|
||||
"The file ({}) is outside Nixpkgs ({})",
|
||||
self.file.display(),
|
||||
nixpkgs_path.display()
|
||||
)
|
||||
})?
|
||||
.to_path_buf())
|
||||
})?;
|
||||
Ok(RelativePathBuf::from_path(path).expect("relative path"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,12 +350,12 @@ fn by_name(
|
|||
/// all-packages.nix
|
||||
fn by_name_override(
|
||||
attribute_name: &str,
|
||||
expected_package_file: PathBuf,
|
||||
expected_package_file: RelativePathBuf,
|
||||
is_semantic_call_package: bool,
|
||||
optional_syntactic_call_package: Option<CallPackageArgumentInfo>,
|
||||
definition: String,
|
||||
location: Location,
|
||||
relative_location_file: PathBuf,
|
||||
relative_location_file: RelativePathBuf,
|
||||
) -> validation::Validation<ratchet::RatchetState<ratchet::ManualDefinition>> {
|
||||
// At this point, we completed two different checks for whether it's a
|
||||
// `callPackage`
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use crate::utils::LineIndex;
|
||||
use anyhow::Context;
|
||||
use itertools::Either::{self, Left, Right};
|
||||
use relative_path::RelativePathBuf;
|
||||
use rnix::ast;
|
||||
use rnix::ast::Expr;
|
||||
use rnix::ast::HasEntry;
|
||||
|
@ -79,7 +80,7 @@ impl NixFile {
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub struct CallPackageArgumentInfo {
|
||||
/// The relative path of the first argument, or `None` if it's not a path.
|
||||
pub relative_path: Option<PathBuf>,
|
||||
pub relative_path: Option<RelativePathBuf>,
|
||||
/// Whether the second argument is an empty attribute set
|
||||
pub empty_arg: bool,
|
||||
}
|
||||
|
@ -369,8 +370,8 @@ pub enum ResolvedPath {
|
|||
/// The path is outside the given absolute path
|
||||
Outside,
|
||||
/// The path is within the given absolute path.
|
||||
/// The `PathBuf` is the relative path under the given absolute path.
|
||||
Within(PathBuf),
|
||||
/// The `RelativePathBuf` is the relative path under the given absolute path.
|
||||
Within(RelativePathBuf),
|
||||
}
|
||||
|
||||
impl NixFile {
|
||||
|
@ -402,7 +403,9 @@ impl NixFile {
|
|||
// Check if it's within relative_to
|
||||
match resolved.strip_prefix(relative_to) {
|
||||
Err(_prefix_error) => ResolvedPath::Outside,
|
||||
Ok(suffix) => ResolvedPath::Within(suffix.to_path_buf()),
|
||||
Ok(suffix) => ResolvedPath::Within(
|
||||
RelativePathBuf::from_path(suffix).expect("a relative path"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -506,14 +509,14 @@ mod tests {
|
|||
(
|
||||
6,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
relative_path: Some(RelativePathBuf::from("file.nix")),
|
||||
empty_arg: true,
|
||||
}),
|
||||
),
|
||||
(
|
||||
7,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
relative_path: Some(RelativePathBuf::from("file.nix")),
|
||||
empty_arg: true,
|
||||
}),
|
||||
),
|
||||
|
@ -527,7 +530,7 @@ mod tests {
|
|||
(
|
||||
9,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
relative_path: Some(RelativePathBuf::from("file.nix")),
|
||||
empty_arg: false,
|
||||
}),
|
||||
),
|
||||
|
|
|
@ -2,139 +2,140 @@ use crate::structure;
|
|||
use crate::utils::PACKAGE_NIX_FILENAME;
|
||||
use indoc::writedoc;
|
||||
use relative_path::RelativePath;
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Any problem that can occur when checking Nixpkgs
|
||||
/// All paths are relative to Nixpkgs such that the error messages can't be influenced by Nixpkgs absolute
|
||||
/// location
|
||||
#[derive(Clone)]
|
||||
pub enum NixpkgsProblem {
|
||||
ShardNonDir {
|
||||
relative_shard_path: PathBuf,
|
||||
relative_shard_path: RelativePathBuf,
|
||||
},
|
||||
InvalidShardName {
|
||||
relative_shard_path: PathBuf,
|
||||
relative_shard_path: RelativePathBuf,
|
||||
shard_name: String,
|
||||
},
|
||||
PackageNonDir {
|
||||
relative_package_dir: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
},
|
||||
CaseSensitiveDuplicate {
|
||||
relative_shard_path: PathBuf,
|
||||
relative_shard_path: RelativePathBuf,
|
||||
first: OsString,
|
||||
second: OsString,
|
||||
},
|
||||
InvalidPackageName {
|
||||
relative_package_dir: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
package_name: String,
|
||||
},
|
||||
IncorrectShard {
|
||||
relative_package_dir: PathBuf,
|
||||
correct_relative_package_dir: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
correct_relative_package_dir: RelativePathBuf,
|
||||
},
|
||||
PackageNixNonExistent {
|
||||
relative_package_dir: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
},
|
||||
PackageNixDir {
|
||||
relative_package_dir: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
},
|
||||
UndefinedAttr {
|
||||
relative_package_file: PathBuf,
|
||||
relative_package_file: RelativePathBuf,
|
||||
package_name: String,
|
||||
},
|
||||
EmptyArgument {
|
||||
package_name: String,
|
||||
file: PathBuf,
|
||||
file: RelativePathBuf,
|
||||
line: usize,
|
||||
column: usize,
|
||||
definition: String,
|
||||
},
|
||||
NonToplevelCallPackage {
|
||||
package_name: String,
|
||||
file: PathBuf,
|
||||
file: RelativePathBuf,
|
||||
line: usize,
|
||||
column: usize,
|
||||
definition: String,
|
||||
},
|
||||
NonPath {
|
||||
package_name: String,
|
||||
file: PathBuf,
|
||||
file: RelativePathBuf,
|
||||
line: usize,
|
||||
column: usize,
|
||||
definition: String,
|
||||
},
|
||||
WrongCallPackagePath {
|
||||
package_name: String,
|
||||
file: PathBuf,
|
||||
file: RelativePathBuf,
|
||||
line: usize,
|
||||
actual_path: PathBuf,
|
||||
expected_path: PathBuf,
|
||||
actual_path: RelativePathBuf,
|
||||
expected_path: RelativePathBuf,
|
||||
},
|
||||
NonSyntacticCallPackage {
|
||||
package_name: String,
|
||||
file: PathBuf,
|
||||
file: RelativePathBuf,
|
||||
line: usize,
|
||||
column: usize,
|
||||
definition: String,
|
||||
},
|
||||
NonDerivation {
|
||||
relative_package_file: PathBuf,
|
||||
relative_package_file: RelativePathBuf,
|
||||
package_name: String,
|
||||
},
|
||||
OutsideSymlink {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
},
|
||||
UnresolvableSymlink {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
io_error: String,
|
||||
},
|
||||
PathInterpolation {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
line: usize,
|
||||
text: String,
|
||||
},
|
||||
SearchPath {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
line: usize,
|
||||
text: String,
|
||||
},
|
||||
OutsidePathReference {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
line: usize,
|
||||
text: String,
|
||||
},
|
||||
UnresolvablePathReference {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
relative_package_dir: RelativePathBuf,
|
||||
subpath: RelativePathBuf,
|
||||
line: usize,
|
||||
text: String,
|
||||
io_error: String,
|
||||
},
|
||||
MovedOutOfByNameEmptyArg {
|
||||
package_name: String,
|
||||
call_package_path: Option<PathBuf>,
|
||||
file: PathBuf,
|
||||
call_package_path: Option<RelativePathBuf>,
|
||||
file: RelativePathBuf,
|
||||
},
|
||||
MovedOutOfByNameNonEmptyArg {
|
||||
package_name: String,
|
||||
call_package_path: Option<PathBuf>,
|
||||
file: PathBuf,
|
||||
call_package_path: Option<RelativePathBuf>,
|
||||
file: RelativePathBuf,
|
||||
},
|
||||
NewPackageNotUsingByNameEmptyArg {
|
||||
package_name: String,
|
||||
call_package_path: Option<PathBuf>,
|
||||
file: PathBuf,
|
||||
call_package_path: Option<RelativePathBuf>,
|
||||
file: RelativePathBuf,
|
||||
},
|
||||
NewPackageNotUsingByNameNonEmptyArg {
|
||||
package_name: String,
|
||||
call_package_path: Option<PathBuf>,
|
||||
file: PathBuf,
|
||||
call_package_path: Option<RelativePathBuf>,
|
||||
file: RelativePathBuf,
|
||||
},
|
||||
InternalCallPackageUsed {
|
||||
attr_name: String,
|
||||
|
@ -151,56 +152,56 @@ impl fmt::Display for NixpkgsProblem {
|
|||
write!(
|
||||
f,
|
||||
"{}: This is a file, but it should be a directory.",
|
||||
relative_shard_path.display(),
|
||||
relative_shard_path,
|
||||
),
|
||||
NixpkgsProblem::InvalidShardName { relative_shard_path, shard_name } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Invalid directory name \"{shard_name}\", must be at most 2 ASCII characters consisting of a-z, 0-9, \"-\" or \"_\".",
|
||||
relative_shard_path.display()
|
||||
relative_shard_path,
|
||||
),
|
||||
NixpkgsProblem::PackageNonDir { relative_package_dir } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: This path is a file, but it should be a directory.",
|
||||
relative_package_dir.display(),
|
||||
relative_package_dir,
|
||||
),
|
||||
NixpkgsProblem::CaseSensitiveDuplicate { relative_shard_path, first, second } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Duplicate case-sensitive package directories {first:?} and {second:?}.",
|
||||
relative_shard_path.display(),
|
||||
relative_shard_path,
|
||||
),
|
||||
NixpkgsProblem::InvalidPackageName { relative_package_dir, package_name } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Invalid package directory name \"{package_name}\", must be ASCII characters consisting of a-z, A-Z, 0-9, \"-\" or \"_\".",
|
||||
relative_package_dir.display(),
|
||||
relative_package_dir,
|
||||
),
|
||||
NixpkgsProblem::IncorrectShard { relative_package_dir, correct_relative_package_dir } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Incorrect directory location, should be {} instead.",
|
||||
relative_package_dir.display(),
|
||||
correct_relative_package_dir.display(),
|
||||
relative_package_dir,
|
||||
correct_relative_package_dir,
|
||||
),
|
||||
NixpkgsProblem::PackageNixNonExistent { relative_package_dir } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Missing required \"{PACKAGE_NIX_FILENAME}\" file.",
|
||||
relative_package_dir.display(),
|
||||
relative_package_dir,
|
||||
),
|
||||
NixpkgsProblem::PackageNixDir { relative_package_dir } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: \"{PACKAGE_NIX_FILENAME}\" must be a file.",
|
||||
relative_package_dir.display(),
|
||||
relative_package_dir,
|
||||
),
|
||||
NixpkgsProblem::UndefinedAttr { relative_package_file, package_name } =>
|
||||
write!(
|
||||
f,
|
||||
"pkgs.{package_name}: This attribute is not defined but it should be defined automatically as {}",
|
||||
relative_package_file.display()
|
||||
relative_package_file,
|
||||
),
|
||||
NixpkgsProblem::EmptyArgument { package_name, file, line, column, definition } =>
|
||||
writedoc!(
|
||||
|
@ -216,9 +217,9 @@ impl fmt::Display for NixpkgsProblem {
|
|||
|
||||
Such a definition is provided automatically and therefore not necessary. Please remove it.
|
||||
",
|
||||
structure::relative_dir_for_package(package_name).display(),
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_dir_for_package(package_name),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
line,
|
||||
indent_definition(*column, definition.clone()),
|
||||
),
|
||||
|
@ -234,9 +235,9 @@ impl fmt::Display for NixpkgsProblem {
|
|||
|
||||
{}
|
||||
",
|
||||
structure::relative_dir_for_package(package_name).display(),
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_dir_for_package(package_name),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
line,
|
||||
indent_definition(*column, definition.clone()),
|
||||
),
|
||||
|
@ -252,9 +253,9 @@ impl fmt::Display for NixpkgsProblem {
|
|||
|
||||
{}
|
||||
",
|
||||
structure::relative_dir_for_package(package_name).display(),
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_dir_for_package(package_name),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
line,
|
||||
indent_definition(*column, definition.clone()),
|
||||
),
|
||||
|
@ -270,9 +271,9 @@ impl fmt::Display for NixpkgsProblem {
|
|||
|
||||
{package_name} = callPackage {} {{ /* ... */ }};
|
||||
",
|
||||
structure::relative_dir_for_package(package_name).display(),
|
||||
structure::relative_dir_for_package(package_name),
|
||||
create_path_expr(file, expected_path),
|
||||
file.display(), line,
|
||||
file, line,
|
||||
create_path_expr(file, actual_path),
|
||||
},
|
||||
NixpkgsProblem::NonSyntacticCallPackage { package_name, file, line, column, definition } => {
|
||||
|
@ -287,9 +288,9 @@ impl fmt::Display for NixpkgsProblem {
|
|||
|
||||
{}
|
||||
",
|
||||
structure::relative_dir_for_package(package_name).display(),
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_dir_for_package(package_name),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
line,
|
||||
indent_definition(*column, definition.clone()),
|
||||
)
|
||||
|
@ -298,58 +299,58 @@ impl fmt::Display for NixpkgsProblem {
|
|||
write!(
|
||||
f,
|
||||
"pkgs.{package_name}: This attribute defined by {} is not a derivation",
|
||||
relative_package_file.display()
|
||||
relative_package_file,
|
||||
),
|
||||
NixpkgsProblem::OutsideSymlink { relative_package_dir, subpath } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Path {} is a symlink pointing to a path outside the directory of that package.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
),
|
||||
NixpkgsProblem::UnresolvableSymlink { relative_package_dir, subpath, io_error } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: Path {} is a symlink which cannot be resolved: {io_error}.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
),
|
||||
NixpkgsProblem::PathInterpolation { relative_package_dir, subpath, line, text } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: File {} at line {line} contains the path expression \"{}\", which is not yet supported and may point outside the directory of that package.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
text
|
||||
),
|
||||
NixpkgsProblem::SearchPath { relative_package_dir, subpath, line, text } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: File {} at line {line} contains the nix search path expression \"{}\" which may point outside the directory of that package.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
text
|
||||
),
|
||||
NixpkgsProblem::OutsidePathReference { relative_package_dir, subpath, line, text } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: File {} at line {line} contains the path expression \"{}\" which may point outside the directory of that package.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
text,
|
||||
),
|
||||
NixpkgsProblem::UnresolvablePathReference { relative_package_dir, subpath, line, text, io_error } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: File {} at line {line} contains the path expression \"{}\" which cannot be resolved: {io_error}.",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
relative_package_dir,
|
||||
subpath,
|
||||
text,
|
||||
),
|
||||
NixpkgsProblem::MovedOutOfByNameEmptyArg { package_name, call_package_path, file } => {
|
||||
let call_package_arg =
|
||||
if let Some(path) = &call_package_path {
|
||||
format!("./{}", path.display())
|
||||
format!("./{}", path)
|
||||
} else {
|
||||
"...".into()
|
||||
};
|
||||
|
@ -359,14 +360,14 @@ impl fmt::Display for NixpkgsProblem {
|
|||
- Attribute `pkgs.{package_name}` was previously defined in {}, but is now manually defined as `callPackage {call_package_arg} {{ /* ... */ }}` in {}.
|
||||
Please move the package back and remove the manual `callPackage`.
|
||||
",
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
)
|
||||
},
|
||||
NixpkgsProblem::MovedOutOfByNameNonEmptyArg { package_name, call_package_path, file } => {
|
||||
let call_package_arg =
|
||||
if let Some(path) = &call_package_path {
|
||||
format!("./{}", path.display())
|
||||
format!("./{}", path)
|
||||
} else {
|
||||
"...".into()
|
||||
};
|
||||
|
@ -378,14 +379,14 @@ impl fmt::Display for NixpkgsProblem {
|
|||
- Attribute `pkgs.{package_name}` was previously defined in {}, but is now manually defined as `callPackage {call_package_arg} {{ ... }}` in {}.
|
||||
While the manual `callPackage` is still needed, it's not necessary to move the package files.
|
||||
",
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
)
|
||||
},
|
||||
NixpkgsProblem::NewPackageNotUsingByNameEmptyArg { package_name, call_package_path, file } => {
|
||||
let call_package_arg =
|
||||
if let Some(path) = &call_package_path {
|
||||
format!("./{}", path.display())
|
||||
format!("./{}", path)
|
||||
} else {
|
||||
"...".into()
|
||||
};
|
||||
|
@ -397,14 +398,14 @@ impl fmt::Display for NixpkgsProblem {
|
|||
See `pkgs/by-name/README.md` for more details.
|
||||
Since the second `callPackage` argument is `{{ }}`, no manual `callPackage` in {} is needed anymore.
|
||||
",
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
)
|
||||
},
|
||||
NixpkgsProblem::NewPackageNotUsingByNameNonEmptyArg { package_name, call_package_path, file } => {
|
||||
let call_package_arg =
|
||||
if let Some(path) = &call_package_path {
|
||||
format!("./{}", path.display())
|
||||
format!("./{}", path)
|
||||
} else {
|
||||
"...".into()
|
||||
};
|
||||
|
@ -416,8 +417,8 @@ impl fmt::Display for NixpkgsProblem {
|
|||
See `pkgs/by-name/README.md` for more details.
|
||||
Since the second `callPackage` argument is not `{{ }}`, the manual `callPackage` in {} is still needed.
|
||||
",
|
||||
structure::relative_file_for_package(package_name).display(),
|
||||
file.display(),
|
||||
structure::relative_file_for_package(package_name),
|
||||
file,
|
||||
)
|
||||
},
|
||||
NixpkgsProblem::InternalCallPackageUsed { attr_name } =>
|
||||
|
@ -448,14 +449,13 @@ fn indent_definition(column: usize, definition: String) -> String {
|
|||
}
|
||||
|
||||
/// Creates a Nix path expression that when put into Nix file `from_file`, would point to the `to_file`.
|
||||
fn create_path_expr(from_file: impl AsRef<Path>, to_file: impl AsRef<Path>) -> String {
|
||||
// These `expect` calls should never trigger because we only call this function with
|
||||
// relative paths that have a parent. That's why we `expect` them!
|
||||
let from = RelativePath::from_path(&from_file)
|
||||
.expect("a relative path")
|
||||
.parent()
|
||||
.expect("a parent for this path");
|
||||
let to = RelativePath::from_path(&to_file).expect("a path");
|
||||
let rel = from.relative(to);
|
||||
fn create_path_expr(
|
||||
from_file: impl AsRef<RelativePath>,
|
||||
to_file: impl AsRef<RelativePath>,
|
||||
) -> String {
|
||||
// This `expect` calls should never trigger because we only call this function with files.
|
||||
// That's why we `expect` them!
|
||||
let from = from_file.as_ref().parent().expect("a parent for this path");
|
||||
let rel = from.relative(to_file);
|
||||
format!("./{rel}")
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use crate::nix_file::CallPackageArgumentInfo;
|
||||
use crate::nixpkgs_problem::NixpkgsProblem;
|
||||
use crate::validation::{self, Validation, Validation::Success};
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// The ratchet value for the entirety of Nixpkgs.
|
||||
#[derive(Default)]
|
||||
|
@ -146,7 +146,7 @@ impl ToNixpkgsProblem for ManualDefinition {
|
|||
pub enum UsesByName {}
|
||||
|
||||
impl ToNixpkgsProblem for UsesByName {
|
||||
type ToContext = (CallPackageArgumentInfo, PathBuf);
|
||||
type ToContext = (CallPackageArgumentInfo, RelativePathBuf);
|
||||
|
||||
fn to_nixpkgs_problem(
|
||||
name: &str,
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::nixpkgs_problem::NixpkgsProblem;
|
|||
use crate::utils;
|
||||
use crate::validation::{self, ResultIteratorExt, Validation::Success};
|
||||
use crate::NixFileStore;
|
||||
use relative_path::RelativePath;
|
||||
|
||||
use anyhow::Context;
|
||||
use rowan::ast::AstNode;
|
||||
|
@ -12,14 +13,14 @@ use std::path::Path;
|
|||
/// Both symlinks and Nix path expressions are checked.
|
||||
pub fn check_references(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
relative_package_dir: &RelativePath,
|
||||
absolute_package_dir: &Path,
|
||||
) -> validation::Result<()> {
|
||||
// The first subpath to check is the package directory itself, which we can represent as an
|
||||
// empty path, since the absolute package directory gets prepended to this.
|
||||
// We don't use `./.` to keep the error messages cleaner
|
||||
// (there's no canonicalisation going on underneath)
|
||||
let subpath = Path::new("");
|
||||
let subpath = RelativePath::new("");
|
||||
check_path(
|
||||
nix_file_store,
|
||||
relative_package_dir,
|
||||
|
@ -29,7 +30,7 @@ pub fn check_references(
|
|||
.with_context(|| {
|
||||
format!(
|
||||
"While checking the references in package directory {}",
|
||||
relative_package_dir.display()
|
||||
relative_package_dir
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -41,11 +42,11 @@ pub fn check_references(
|
|||
/// The absolute package directory gets prepended before doing anything with it though.
|
||||
fn check_path(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
relative_package_dir: &RelativePath,
|
||||
absolute_package_dir: &Path,
|
||||
subpath: &Path,
|
||||
subpath: &RelativePath,
|
||||
) -> validation::Result<()> {
|
||||
let path = absolute_package_dir.join(subpath);
|
||||
let path = subpath.to_path(absolute_package_dir);
|
||||
|
||||
Ok(if path.is_symlink() {
|
||||
// Check whether the symlink resolves to outside the package directory
|
||||
|
@ -55,8 +56,8 @@ fn check_path(
|
|||
// entire directory recursively anyways
|
||||
if let Err(_prefix_error) = target.strip_prefix(absolute_package_dir) {
|
||||
NixpkgsProblem::OutsideSymlink {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
|
@ -64,8 +65,8 @@ fn check_path(
|
|||
}
|
||||
}
|
||||
Err(io_error) => NixpkgsProblem::UnresolvableSymlink {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
io_error: io_error.to_string(),
|
||||
}
|
||||
.into(),
|
||||
|
@ -80,11 +81,12 @@ fn check_path(
|
|||
nix_file_store,
|
||||
relative_package_dir,
|
||||
absolute_package_dir,
|
||||
&subpath.join(entry.file_name()),
|
||||
// TODO: The relative_path crate doesn't seem to support OsStr
|
||||
&subpath.join(entry.file_name().to_string_lossy().to_string()),
|
||||
)
|
||||
})
|
||||
.collect_vec()
|
||||
.with_context(|| format!("Error while recursing into {}", subpath.display()))?,
|
||||
.with_context(|| format!("Error while recursing into {}", subpath))?,
|
||||
)
|
||||
} else if path.is_file() {
|
||||
// Only check Nix files
|
||||
|
@ -96,7 +98,7 @@ fn check_path(
|
|||
absolute_package_dir,
|
||||
subpath,
|
||||
)
|
||||
.with_context(|| format!("Error while checking Nix file {}", subpath.display()))?
|
||||
.with_context(|| format!("Error while checking Nix file {}", subpath))?
|
||||
} else {
|
||||
Success(())
|
||||
}
|
||||
|
@ -105,7 +107,7 @@ fn check_path(
|
|||
}
|
||||
} else {
|
||||
// This should never happen, git doesn't support other file types
|
||||
anyhow::bail!("Unsupported file type for path {}", subpath.display());
|
||||
anyhow::bail!("Unsupported file type for path {}", subpath);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -113,11 +115,11 @@ fn check_path(
|
|||
/// directory
|
||||
fn check_nix_file(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
relative_package_dir: &RelativePath,
|
||||
absolute_package_dir: &Path,
|
||||
subpath: &Path,
|
||||
subpath: &RelativePath,
|
||||
) -> validation::Result<()> {
|
||||
let path = absolute_package_dir.join(subpath);
|
||||
let path = subpath.to_path(absolute_package_dir);
|
||||
|
||||
let nix_file = nix_file_store.get(&path)?;
|
||||
|
||||
|
@ -135,29 +137,29 @@ fn check_nix_file(
|
|||
|
||||
match nix_file.static_resolve_path(path, absolute_package_dir) {
|
||||
ResolvedPath::Interpolated => NixpkgsProblem::PathInterpolation {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into(),
|
||||
ResolvedPath::SearchPath => NixpkgsProblem::SearchPath {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into(),
|
||||
ResolvedPath::Outside => NixpkgsProblem::OutsidePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into(),
|
||||
ResolvedPath::Unresolvable(e) => NixpkgsProblem::UnresolvablePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
relative_package_dir: relative_package_dir.to_owned(),
|
||||
subpath: subpath.to_owned(),
|
||||
line,
|
||||
text,
|
||||
io_error: e.to_string(),
|
||||
|
|
|
@ -7,8 +7,9 @@ use crate::NixFileStore;
|
|||
use itertools::concat;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use relative_path::RelativePathBuf;
|
||||
use std::fs::DirEntry;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
|
||||
lazy_static! {
|
||||
static ref SHARD_NAME_REGEX: Regex = Regex::new(r"^[a-z0-9_-]{1,2}$").unwrap();
|
||||
|
@ -21,15 +22,15 @@ pub fn shard_for_package(package_name: &str) -> String {
|
|||
package_name.to_lowercase().chars().take(2).collect()
|
||||
}
|
||||
|
||||
pub fn relative_dir_for_shard(shard_name: &str) -> PathBuf {
|
||||
PathBuf::from(format!("{BASE_SUBPATH}/{shard_name}"))
|
||||
pub fn relative_dir_for_shard(shard_name: &str) -> RelativePathBuf {
|
||||
RelativePathBuf::from(format!("{BASE_SUBPATH}/{shard_name}"))
|
||||
}
|
||||
|
||||
pub fn relative_dir_for_package(package_name: &str) -> PathBuf {
|
||||
pub fn relative_dir_for_package(package_name: &str) -> RelativePathBuf {
|
||||
relative_dir_for_shard(&shard_for_package(package_name)).join(package_name)
|
||||
}
|
||||
|
||||
pub fn relative_file_for_package(package_name: &str) -> PathBuf {
|
||||
pub fn relative_file_for_package(package_name: &str) -> RelativePathBuf {
|
||||
relative_dir_for_package(package_name).join(PACKAGE_NIX_FILENAME)
|
||||
}
|
||||
|
||||
|
@ -120,7 +121,8 @@ fn check_package(
|
|||
) -> validation::Result<String> {
|
||||
let package_path = package_entry.path();
|
||||
let package_name = package_entry.file_name().to_string_lossy().into_owned();
|
||||
let relative_package_dir = PathBuf::from(format!("{BASE_SUBPATH}/{shard_name}/{package_name}"));
|
||||
let relative_package_dir =
|
||||
RelativePathBuf::from(format!("{BASE_SUBPATH}/{shard_name}/{package_name}"));
|
||||
|
||||
Ok(if !package_path.is_dir() {
|
||||
NixpkgsProblem::PackageNonDir {
|
||||
|
@ -174,7 +176,7 @@ fn check_package(
|
|||
let result = result.and(references::check_references(
|
||||
nix_file_store,
|
||||
&relative_package_dir,
|
||||
&path.join(&relative_package_dir),
|
||||
&relative_package_dir.to_path(path),
|
||||
)?);
|
||||
|
||||
result.map(|_| package_name.clone())
|
||||
|
|
Loading…
Reference in a new issue