Skip to content

Commit 1a6cd11

Browse files
authored
Include wiki links in error output (#200)
2 parents df4fef0 + e36256d commit 1a6cd11

File tree

37 files changed

+168
-65
lines changed

37 files changed

+168
-65
lines changed

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ mod tests {
201201
test_nixpkgs(
202202
"case_sensitive",
203203
path,
204-
"- pkgs/by-name/fo: Duplicate case-sensitive package directories \"foO\" and \"foo\".\n\
204+
"- pkgs/by-name/fo: Duplicate case-sensitive package directories \"foO\" and \"foo\". (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-111)\n\
205205
This PR introduces the problems listed above. Please fix them before merging, \
206206
otherwise the base branch would break.\n",
207207
);

src/problem/mod.rs

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use std::fmt;
2+
13
use derive_enum_from_into::EnumFrom;
2-
use derive_more::Display;
34
use relative_path::RelativePath;
45

56
pub mod npv_100;
@@ -36,7 +37,9 @@ pub mod npv_161;
3637
pub mod npv_162;
3738
pub mod npv_163;
3839

39-
#[derive(Clone, Display, EnumFrom)]
40+
const WIKI_BASE_URL: &str = "https://github.com/NixOS/nixpkgs-vet/wiki";
41+
42+
#[derive(Clone, EnumFrom)]
4043
pub enum Problem {
4144
/// NPV-100: attribute is not defined but it should be defined automatically
4245
ByNameUndefinedAttribute(npv_100::ByNameUndefinedAttribute),
@@ -133,6 +136,86 @@ pub enum Problem {
133136
),
134137
}
135138

139+
impl Problem {
140+
/// Returns the NPV error code for this problem (e.g. "NPV-100").
141+
pub fn npv_code(&self) -> &'static str {
142+
match self {
143+
Self::ByNameUndefinedAttribute(..) => "NPV-100",
144+
Self::ByNameNonDerivation(..) => "NPV-101",
145+
Self::ByNameInternalCallPackageUsed(..) => "NPV-102",
146+
Self::ByNameCannotDetermineAttributeLocation(..) => "NPV-103",
147+
Self::ByNameOverrideOfNonSyntacticCallPackage(..) => "NPV-104",
148+
Self::ByNameOverrideOfNonTopLevelPackage(..) => "NPV-105",
149+
Self::ByNameOverrideContainsWrongCallPackagePath(..) => "NPV-106",
150+
Self::ByNameOverrideContainsEmptyArgument(..) => "NPV-107",
151+
Self::ByNameOverrideContainsEmptyPath(..) => "NPV-108",
152+
Self::ByNameShardIsNotDirectory(..) => "NPV-109",
153+
Self::ByNameShardIsInvalid(..) => "NPV-110",
154+
Self::ByNameShardIsCaseSensitiveDuplicate(..) => "NPV-111",
155+
Self::NixEvalError(..) => "NPV-120",
156+
Self::NixFileContainsPathInterpolation(..) => "NPV-121",
157+
Self::NixFileContainsSearchPath(..) => "NPV-122",
158+
Self::NixFileContainsPathOutsideDirectory(..) => "NPV-123",
159+
Self::NixFileContainsUnresolvablePath(..) => "NPV-124",
160+
Self::PackageContainsSymlinkPointingOutside(..) => "NPV-125",
161+
Self::PackageContainsUnresolvableSymlink(..) => "NPV-126",
162+
Self::NixFileContainsAbsolutePath(..) => "NPV-127",
163+
Self::NixFileContainsHomeRelativePath(..) => "NPV-128",
164+
Self::PackageDirectoryIsNotDirectory(..) => "NPV-140",
165+
Self::InvalidPackageDirectoryName(..) => "NPV-141",
166+
Self::PackageInWrongShard(..) => "NPV-142",
167+
Self::PackageNixMissing(..) => "NPV-143",
168+
Self::PackageNixIsNotFile(..) => "NPV-144",
169+
Self::TopLevelPackageMovedOutOfByName(..) => "NPV-160",
170+
Self::TopLevelPackageMovedOutOfByNameWithCustomArguments(..) => "NPV-161",
171+
Self::NewTopLevelPackageShouldBeByName(..) => "NPV-162",
172+
Self::NewTopLevelPackageShouldBeByNameWithCustomArgument(..) => "NPV-163",
173+
}
174+
}
175+
176+
/// Returns the wiki URL for this problem's documentation.
177+
pub fn wiki_url(&self) -> String {
178+
format!("{WIKI_BASE_URL}/{}", self.npv_code())
179+
}
180+
}
181+
182+
impl fmt::Display for Problem {
183+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
184+
match self {
185+
Self::ByNameUndefinedAttribute(inner) => inner.fmt(f),
186+
Self::ByNameNonDerivation(inner) => inner.fmt(f),
187+
Self::ByNameInternalCallPackageUsed(inner) => inner.fmt(f),
188+
Self::ByNameCannotDetermineAttributeLocation(inner) => inner.fmt(f),
189+
Self::ByNameOverrideOfNonSyntacticCallPackage(inner) => inner.fmt(f),
190+
Self::ByNameOverrideOfNonTopLevelPackage(inner) => inner.fmt(f),
191+
Self::ByNameOverrideContainsWrongCallPackagePath(inner) => inner.fmt(f),
192+
Self::ByNameOverrideContainsEmptyArgument(inner) => inner.fmt(f),
193+
Self::ByNameOverrideContainsEmptyPath(inner) => inner.fmt(f),
194+
Self::ByNameShardIsNotDirectory(inner) => inner.fmt(f),
195+
Self::ByNameShardIsInvalid(inner) => inner.fmt(f),
196+
Self::ByNameShardIsCaseSensitiveDuplicate(inner) => inner.fmt(f),
197+
Self::NixEvalError(inner) => inner.fmt(f),
198+
Self::NixFileContainsPathInterpolation(inner) => inner.fmt(f),
199+
Self::NixFileContainsSearchPath(inner) => inner.fmt(f),
200+
Self::NixFileContainsPathOutsideDirectory(inner) => inner.fmt(f),
201+
Self::NixFileContainsUnresolvablePath(inner) => inner.fmt(f),
202+
Self::PackageContainsSymlinkPointingOutside(inner) => inner.fmt(f),
203+
Self::PackageContainsUnresolvableSymlink(inner) => inner.fmt(f),
204+
Self::NixFileContainsAbsolutePath(inner) => inner.fmt(f),
205+
Self::NixFileContainsHomeRelativePath(inner) => inner.fmt(f),
206+
Self::PackageDirectoryIsNotDirectory(inner) => inner.fmt(f),
207+
Self::InvalidPackageDirectoryName(inner) => inner.fmt(f),
208+
Self::PackageInWrongShard(inner) => inner.fmt(f),
209+
Self::PackageNixMissing(inner) => inner.fmt(f),
210+
Self::PackageNixIsNotFile(inner) => inner.fmt(f),
211+
Self::TopLevelPackageMovedOutOfByName(inner) => inner.fmt(f),
212+
Self::TopLevelPackageMovedOutOfByNameWithCustomArguments(inner) => inner.fmt(f),
213+
Self::NewTopLevelPackageShouldBeByName(inner) => inner.fmt(f),
214+
Self::NewTopLevelPackageShouldBeByNameWithCustomArgument(inner) => inner.fmt(f),
215+
}
216+
}
217+
}
218+
136219
fn indent_definition(column: usize, definition: &str) -> String {
137220
// The entire code should be indented 4 spaces
138221
textwrap::indent(

src/status.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,33 @@ impl Status {
4242
// These all respect the NO_COLOR environment variable even if `use_color` is true.
4343
let maybe_green = |s: &str| if use_color { s.green() } else { s.into() };
4444
let maybe_yellow = |s: &str| if use_color { s.yellow() } else { s.into() };
45-
let maybe_red = |s: &str| if use_color { s.red() } else { s.into() };
46-
47-
// If there are errors, print them all out first in red.
45+
// Print each error with its wiki link.
4846
if let Some(errors) = self.errors() {
4947
for error in errors {
50-
let error = format!("{error}\n");
51-
fmt::Display::fmt(&maybe_red(&error), f)?;
48+
let code = error.npv_code();
49+
let url = error.wiki_url();
50+
51+
if use_color {
52+
let error_str = format!("{error}");
53+
// OSC 8 hyperlink: \e]8;;URL\e\\TEXT\e]8;;\e\\
54+
let link = format!("\x1b]8;;{url}\x1b\\{code}\x1b]8;;\x1b\\");
55+
56+
// Most errors follow "- {path}: {message}". When we can identify
57+
// that pattern, make the path bold and the message red. Otherwise
58+
// fall back to coloring the entire error red.
59+
if let Some(rest) = error_str.strip_prefix("- ")
60+
&& let Some((location, message)) = rest.split_once(": ")
61+
&& !location.contains('\n')
62+
{
63+
writeln!(f, "- {}: {} ({})", location.bold(), message.red(), link)?;
64+
continue;
65+
}
66+
67+
// Fallback for messages that don't match the simple pattern.
68+
writeln!(f, "{} ({})", error_str.red(), link)?;
69+
} else {
70+
writeln!(f, "{error} ({url})")?;
71+
}
5272
}
5373
}
5474

tests/alt-callPackage/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
However, in this PR, a different `callPackage` is used. See the definition in pkgs/top-level/all-packages.nix:5:
66

77
foo = self.alt.callPackage ({ }: self.someDrv) { };
8-
8+
(https://github.com/NixOS/nixpkgs-vet/wiki/NPV-105)
99
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

tests/base-still-broken/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
- pkgs/by-name/bar: This is a file, but it should be a directory.
1+
- pkgs/by-name/bar: This is a file, but it should be a directory. (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-109)
22
The base branch is broken and still has above problems with this PR, which need to be fixed first.
33
Consider reverting the PR that introduced these problems in order to prevent more failures of unrelated PRs.

tests/broken-autocall/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
- pkgs.foo: This attribute is not defined but it should be defined automatically as pkgs/by-name/fo/foo/package.nix
1+
- pkgs.foo: This attribute is not defined but it should be defined automatically as pkgs/by-name/fo/foo/package.nix (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-100)
22
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

tests/by-name-failure/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
trace: This should be on stderr!
22
@REDACTED@error: This is an error!@REDACTED@
3-
- Nix evaluation failed for some package in `pkgs/by-name`, see error above
3+
- Nix evaluation failed for some package in `pkgs/by-name`, see error above (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-120)
44
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

tests/by-name-numprefix/expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
- pkgs/by-name/10: Invalid directory name "10", must be at most 2 ASCII characters, starting with a-z or "_", consisting of a-z, 0-9, "-" or "_".
2-
- pkgs/by-name/10/10foo: Invalid package directory name "10foo", must start with a letter (a-z, A-Z) or "_", followed by ASCII characters a-z, A-Z, 0-9, "-" or "_".
1+
- pkgs/by-name/10: Invalid directory name "10", must be at most 2 ASCII characters, starting with a-z or "_", consisting of a-z, 0-9, "-" or "_". (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-110)
2+
- pkgs/by-name/10/10foo: Invalid package directory name "10foo", must start with a letter (a-z, A-Z) or "_", followed by ASCII characters a-z, A-Z, 0-9, "-" or "_". (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-141)
33
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

tests/incorrect-shard/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
- pkgs/by-name/aa/FOO: Incorrect directory location, should be pkgs/by-name/fo/FOO instead.
1+
- pkgs/by-name/aa/FOO: Incorrect directory location, should be pkgs/by-name/fo/FOO instead. (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-142)
22
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

tests/internalCallPackage/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
- pkgs.foo: This attribute is defined using `_internalCallByNamePackageFile`, which is an internal function not intended for manual use.
1+
- pkgs.foo: This attribute is defined using `_internalCallByNamePackageFile`, which is an internal function not intended for manual use. (https://github.com/NixOS/nixpkgs-vet/wiki/NPV-102)
22
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

0 commit comments

Comments
 (0)