alpm_srcinfo/lints.rs
1//! Linter helper functions.
2//!
3//! If you find yourself adding a new linting error and it's not just a one-off but rather used in
4//! multiple places, please add a new function in this module.
5//!
6//! All of these linter functions are designed to be used in the context of
7//! [`SourceInfoV1::from_raw`](crate::SourceInfoV1::from_raw) and the functions that're called
8//! inside it. They're passed the `errors` vector that aggregates all lints/errors during the
9//! conversion from the raw to the structured data format.
10use alpm_types::Architecture;
11
12use crate::error::{SourceInfoError, lint};
13
14/// Creates a parse error for unsafe checksums.
15///
16/// Checksums that are considered cryptographically unsafe are marked as such on the
17/// [`alpm_types::Checksum`] struct.
18pub fn unsafe_checksum(errors: &mut Vec<SourceInfoError>, line: usize, digest: &str) {
19 errors.push(lint(
20 Some(line),
21 format!(
22 "Found cryptographically unsafe checksum type \"{digest}\". Its use is discouraged!"
23 ),
24 ));
25}
26
27/// Creates a lint error for architecture specific properties when that architecture doesn't exist
28/// for a given `PackageBuild` or `Package`.
29///
30/// # Examples
31///
32/// Parsing the following SRCINFO data triggers the creation of this lint, because an assignment for
33/// `depends_aarch64` is present while no `arch = aarch64` assignment exists:
34///
35/// ```ini
36/// pkgbase = example
37/// pkgver = 0.1.0
38/// pkgrel = 1
39/// arch = x86_64
40/// depends_aarch64 = glibc
41/// pkgname = example
42/// ```
43pub fn missing_architecture_for_property(
44 errors: &mut Vec<SourceInfoError>,
45 line: usize,
46 architecture: Architecture,
47) {
48 errors.push(lint(
49 Some(line),
50 format!(
51 "Found keyword specific to \"{architecture}\", but there is no \"arch = {architecture}\" assignment"
52 ),
53 ));
54}
55
56/// Creates a lint error for when an architecture is specified multiple times.
57///
58/// # Examples
59///
60/// ```ini
61/// pkgbase = example
62/// pkgver = 0.1.0
63/// pkgrel = 1
64/// arch = x86_64
65/// arch = x86_64
66/// pkgname = example
67/// ```
68pub fn duplicate_architecture(
69 errors: &mut Vec<SourceInfoError>,
70 line: usize,
71 architecture: Architecture,
72) {
73 errors.push(lint(
74 Some(line),
75 format!("Found duplicate architecture declaration: {architecture}"),
76 ));
77}
78
79/// Creates a lint error for when a license isn't compliant with the SPDX format.
80///
81/// Take a look at [`alpm_types::License`] for more information about this format.
82pub fn non_spdx_license(errors: &mut Vec<SourceInfoError>, line: usize, license: String) {
83 errors.push(lint(
84 Some(line),
85 format!("Found license declaration that's either not in the SPDX format or not supported by SPDX: {license}"),
86 ));
87}
88
89/// Creates a lint error for a package property that is both set and unset.
90///
91/// In SRCINFO data, the overriding of a default keyword assignment in a `pkgbase` section works by
92/// assigning the keyword a new value in a `pkgname` section. Keyword overriding does not require to
93/// first unset a keyword (by assigning it an empty value).
94///
95/// # Examples
96///
97/// Parsing the following example SRCINFO data triggers the lint error, because a default set in the
98/// `pkgbase` section is first explicitly unset and then explicitly set again in a `pkgname`
99/// section. However, simply doing the latter is enough to override the keyword assignment!
100///
101/// ```ini
102/// pkgbase = example
103/// pkgver = 0.1.0
104/// pkgrel = 1
105/// depends = glibc
106///
107/// pkgname = example
108/// # this is not needed!
109/// depends =
110/// depends = gcc-libs
111/// ```
112///
113/// The following example also triggers this lint error and suggests an error in the software that
114/// created the SRCINFO data. While representing legal notation, first setting and then unsetting a
115/// keyword is no useful behavior, as both setting and unsetting of the keyword can simply be
116/// removed.
117///
118/// ```ini
119/// pkgbase = example
120/// pkgver = 0.1.0
121/// pkgrel = 1
122/// depends = glibc
123///
124/// pkgname = example
125/// depends = gcc-libs
126/// # this unsets the previous override for this package!
127/// depends =
128/// ```
129pub fn reassigned_cleared_property(errors: &mut Vec<SourceInfoError>, line: usize) {
130 errors.push(lint(
131 Some(line),
132 "This keyword is set and unset for this package. A keyword should either only be unset or overridden.",
133 ));
134}