alpm_srcinfo/source_info/
lints.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Linter helper functions.
//!
//! If you find yourself adding a new linting error and it's not just a one-off but rather used in
//! multiple places, please add a new function in this module.
//!
//! All of these linter functions are designed to be used in the context of
//! [`SourceInfo::from_raw`](super::SourceInfo::from_raw) and the functions that're called inside
//! it. They're passed the `errors` vector that aggregates all lints/errors during the conversion
//! from the raw to the structured data format.
use alpm_types::Architecture;

use crate::error::{SourceInfoError, lint};

/// Creates a parse error for unsafe checksums.
///
/// Checksums that are considered cryptographically unsafe are marked as such on the
/// [`alpm_types::Checksum`] struct.
pub fn unsafe_checksum(errors: &mut Vec<SourceInfoError>, line: usize, digest: &str) {
    errors.push(lint(
        Some(line),
        format!(
            "Found cryptographically unsafe checksum type \"{digest}\". Its use is discouraged!"
        ),
    ));
}

/// Creates a lint error for architecture specific properties when that architecture doesn't exist
/// for a given `PackageBuild` or `Package`.
///
/// # Examples
///
/// Parsing the following SRCINFO data triggers the creation of this lint, because an assignment for
/// `depends_aarch64` is present while no `arch = aarch64` assignment exists:
///
/// ```ini
/// pkgbase = example
///   pkgver = 0.1.0
///   pkgrel = 1
///   arch = x86_64
///   depends_aarch64 = glibc
/// pkgname = example
/// ```
pub fn missing_architecture_for_property(
    errors: &mut Vec<SourceInfoError>,
    line: usize,
    architecture: Architecture,
) {
    errors.push(lint(
        Some(line),
        format!(
            "Found keyword specific to \"{architecture}\", but there is no \"arch = {architecture}\" assignment"
        ),
    ));
}

/// Creates a lint error for when an architecture is specified multiple times.
///
/// # Examples
///
/// ```ini
/// pkgbase = example
///   pkgver = 0.1.0
///   pkgrel = 1
///   arch = x86_64
///   arch = x86_64
/// pkgname = example
/// ```
pub fn duplicate_architecture(
    errors: &mut Vec<SourceInfoError>,
    line: usize,
    architecture: Architecture,
) {
    errors.push(lint(
        Some(line),
        format!("Found duplicate architecture declaration: {architecture}"),
    ));
}

/// Creates a lint error for when a license isn't compliant with the SPDX format.
///
/// Take a look at [`alpm_types::License`] for more information about this format.
pub fn non_spdx_license(errors: &mut Vec<SourceInfoError>, line: usize, license: String) {
    errors.push(lint(
        Some(line),
        format!("Found license declaration that's either not in the SPDX format or not supported by SPDX: {license}"),
    ));
}

/// Creates a lint error for a package property that is both set and unset.
///
/// In SRCINFO data, the overriding of a default keyword assignment in a `pkgbase` section works by
/// assigning the keyword a new value in a `pkgname` section. Keyword overriding does not require to
/// first unset a keyword (by assigning it an empty value).
///
/// # Examples
///
/// Parsing the following example SRCINFO data triggers the lint error, because a default set in the
/// `pkgbase` section is first explicitly unset and then explicitly set again in a `pkgname`
/// section. However, simply doing the latter is enough to override the keyword assignment!
///
/// ```ini
/// pkgbase = example
///   pkgver = 0.1.0
///   pkgrel = 1
///   depends = glibc
///
/// pkgname = example
///   # this is not needed!
///   depends =
///   depends = gcc-libs
/// ```
///
/// The following example also triggers this lint error and suggests an error in the software that
/// created the SRCINFO data. While representing legal notation, first setting and then unsetting a
/// keyword is no useful behavior, as both setting and unsetting of the keyword can simply be
/// removed.
///
/// ```ini
/// pkgbase = example
///   pkgver = 0.1.0
///   pkgrel = 1
///   depends = glibc
///
/// pkgname = example
///   depends = gcc-libs
///   # this unsets the previous override for this package!
///   depends =
/// ```
pub fn reassigned_cleared_property(errors: &mut Vec<SourceInfoError>, line: usize) {
    errors.push(lint(
        Some(line),
        "This keyword is set and unset for this package. A keyword should either only be unset or overridden.",
    ));
}