1pub const REPORT_SCHEMA_VERSION: u32 = 1;
2pub const REPORT_SCHEMA_ID: &str = "cargo-allow.report.v1";
3pub const RECEIPT_SCHEMA_VERSION: u32 = 1;
4pub const RECEIPT_SCHEMA_ID: &str = "cargo-allow.receipt.v1";
5pub const WORKLIST_SCHEMA_VERSION: u32 = 1;
6pub const WORKLIST_SCHEMA_ID: &str = "cargo-allow.worklist.v1";
7pub const LIST_SCHEMA_VERSION: u32 = 1;
8pub const LIST_SCHEMA_ID: &str = "cargo-allow.list.v1";
9pub const EXPLAIN_SCHEMA_VERSION: u32 = 1;
10pub const EXPLAIN_SCHEMA_ID: &str = "cargo-allow.explain.v1";
11pub const PRUNE_SCHEMA_VERSION: u32 = 1;
12pub const PRUNE_SCHEMA_ID: &str = "cargo-allow.prune.v1";
13pub const DOCTOR_SCHEMA_VERSION: u32 = 1;
14pub const DOCTOR_SCHEMA_ID: &str = "cargo-allow.doctor.v1";
15pub const PROPOSE_SCHEMA_VERSION: u32 = 1;
16pub const PROPOSE_SCHEMA_ID: &str = "cargo-allow.propose.v1";
17pub const ADD_SCHEMA_VERSION: u32 = 1;
18pub const ADD_SCHEMA_ID: &str = "cargo-allow.add.v1";
19pub const MIGRATE_SCHEMA_VERSION: u32 = 1;
20pub const MIGRATE_SCHEMA_ID: &str = "cargo-allow.migrate.v1";
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct ArtifactContract {
24 pub name: &'static str,
25 pub schema_id: &'static str,
26 pub schema_version: u32,
27 pub inventory_scanner: &'static str,
28 pub fixed_command: Option<&'static str>,
29}
30
31pub const ARTIFACT_STATUS_PASSED: &str = "passed";
32pub const ARTIFACT_STATUS_FAILED: &str = "failed";
33pub const ARTIFACT_STATUSES: &[&str] = &[ARTIFACT_STATUS_PASSED, ARTIFACT_STATUS_FAILED];
34
35pub const REPORT_COMMAND_AUDIT: &str = "audit";
36pub const REPORT_COMMAND_CHECK: &str = "check";
37pub const REPORT_COMMAND_DIFF: &str = "diff";
38pub const REPORT_COMMANDS: &[&str] = &[
39 REPORT_COMMAND_AUDIT,
40 REPORT_COMMAND_CHECK,
41 REPORT_COMMAND_DIFF,
42];
43pub const RECEIPT_COMMAND_CHECK: &str = "check";
44
45pub const INVENTORY_SCOPE_SOURCE_TREE: &str = "source_tree";
46pub const INVENTORY_SCANNER_SOURCE_SYNTAX: &str = "source_syntax";
47pub const INVENTORY_SCANNER_POLICY_MIGRATION: &str = "policy_migration";
48pub const INVENTORY_SOURCE_UNKNOWN: &str = "unknown";
49
50pub(crate) const ADD_ARTIFACT: ArtifactContract = ArtifactContract {
51 name: "add",
52 schema_id: ADD_SCHEMA_ID,
53 schema_version: ADD_SCHEMA_VERSION,
54 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
55 fixed_command: Some("add"),
56};
57
58pub(crate) const DOCTOR_ARTIFACT: ArtifactContract = ArtifactContract {
59 name: "doctor",
60 schema_id: DOCTOR_SCHEMA_ID,
61 schema_version: DOCTOR_SCHEMA_VERSION,
62 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
63 fixed_command: Some("doctor"),
64};
65
66pub(crate) const EXPLAIN_ARTIFACT: ArtifactContract = ArtifactContract {
67 name: "explain",
68 schema_id: EXPLAIN_SCHEMA_ID,
69 schema_version: EXPLAIN_SCHEMA_VERSION,
70 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
71 fixed_command: Some("explain"),
72};
73
74pub(crate) const LIST_ARTIFACT: ArtifactContract = ArtifactContract {
75 name: "list",
76 schema_id: LIST_SCHEMA_ID,
77 schema_version: LIST_SCHEMA_VERSION,
78 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
79 fixed_command: Some("list"),
80};
81
82pub(crate) const MIGRATE_ARTIFACT: ArtifactContract = ArtifactContract {
83 name: "migrate",
84 schema_id: MIGRATE_SCHEMA_ID,
85 schema_version: MIGRATE_SCHEMA_VERSION,
86 inventory_scanner: INVENTORY_SCANNER_POLICY_MIGRATION,
87 fixed_command: Some("migrate"),
88};
89
90pub(crate) const PROPOSE_ARTIFACT: ArtifactContract = ArtifactContract {
91 name: "propose",
92 schema_id: PROPOSE_SCHEMA_ID,
93 schema_version: PROPOSE_SCHEMA_VERSION,
94 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
95 fixed_command: Some("propose"),
96};
97
98pub(crate) const PRUNE_ARTIFACT: ArtifactContract = ArtifactContract {
99 name: "prune",
100 schema_id: PRUNE_SCHEMA_ID,
101 schema_version: PRUNE_SCHEMA_VERSION,
102 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
103 fixed_command: Some("prune"),
104};
105
106pub(crate) const RECEIPT_ARTIFACT: ArtifactContract = ArtifactContract {
107 name: "receipt",
108 schema_id: RECEIPT_SCHEMA_ID,
109 schema_version: RECEIPT_SCHEMA_VERSION,
110 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
111 fixed_command: Some(RECEIPT_COMMAND_CHECK),
112};
113
114pub(crate) const REPORT_ARTIFACT: ArtifactContract = ArtifactContract {
115 name: "report",
116 schema_id: REPORT_SCHEMA_ID,
117 schema_version: REPORT_SCHEMA_VERSION,
118 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
119 fixed_command: None,
120};
121
122pub(crate) const WORKLIST_ARTIFACT: ArtifactContract = ArtifactContract {
123 name: "worklist",
124 schema_id: WORKLIST_SCHEMA_ID,
125 schema_version: WORKLIST_SCHEMA_VERSION,
126 inventory_scanner: INVENTORY_SCANNER_SOURCE_SYNTAX,
127 fixed_command: Some("worklist"),
128};
129
130pub const ARTIFACT_CONTRACTS: &[ArtifactContract] = &[
131 ADD_ARTIFACT,
132 DOCTOR_ARTIFACT,
133 EXPLAIN_ARTIFACT,
134 LIST_ARTIFACT,
135 MIGRATE_ARTIFACT,
136 PROPOSE_ARTIFACT,
137 PRUNE_ARTIFACT,
138 RECEIPT_ARTIFACT,
139 REPORT_ARTIFACT,
140 WORKLIST_ARTIFACT,
141];
142
143pub fn artifact_contract_for_schema_id(schema_id: &str) -> Option<ArtifactContract> {
144 ARTIFACT_CONTRACTS
145 .iter()
146 .copied()
147 .find(|contract| contract.schema_id == schema_id)
148}
149
150pub const CLAIM_BOUNDARY: &[&str] = &[
151 "source_tree_inventory",
152 "source_syntax_only",
153 "cargo_metadata_not_invoked",
154 "cargo_commands_not_invoked",
155 "rustc_not_invoked",
156 "clippy_not_invoked",
157 "build_scripts_not_executed",
158 "proc_macros_not_executed",
159 "macro_expansion_not_analyzed",
160 "macro_token_tree_contents_not_analyzed",
161 "type_information_not_analyzed",
162 "mir_not_analyzed",
163 "build_output_not_analyzed",
164 "control_flow_not_analyzed",
165 "data_flow_not_analyzed",
166 "external_evidence_tools_not_invoked",
167 "repository_code_not_executed",
168];
169
170pub const SCANNER_LIMITATIONS: &[&str] = &[
171 "cargo_metadata_not_invoked",
172 "cargo_commands_not_invoked",
173 "rustc_not_invoked",
174 "clippy_not_invoked",
175 "build_scripts_not_executed",
176 "proc_macros_not_executed",
177 "macro_expansion_not_analyzed",
178 "macro_token_tree_contents_not_analyzed",
179 "type_information_not_analyzed",
180 "mir_not_analyzed",
181 "build_output_not_analyzed",
182 "control_flow_not_analyzed",
183 "data_flow_not_analyzed",
184 "external_evidence_tools_not_invoked",
185 "repository_code_not_executed",
186];
187
188pub const CLAIM_BOUNDARY_TEXT: &str = "Claim boundary: scanned source-tree/source syntax only; cargo-allow did not invoke Cargo metadata, Cargo commands, rustc, Clippy, build scripts, proc macros, external evidence tools, or repository code. Macro expansion, macro token-tree contents, type information, MIR, build output, control flow, and data flow were not analyzed.";
189
190#[derive(Debug, Clone, Copy)]
191pub struct InventoryContext<'a> {
192 pub scope: &'a str,
193 pub scanner: &'a str,
194 pub source: &'a str,
195 pub root: Option<&'a str>,
196 pub files_scanned: Option<usize>,
197}
198
199impl<'a> InventoryContext<'a> {
200 pub const fn new(
201 scope: &'a str,
202 scanner: &'a str,
203 source: &'a str,
204 root: Option<&'a str>,
205 files_scanned: Option<usize>,
206 ) -> Self {
207 Self {
208 scope,
209 scanner,
210 source,
211 root,
212 files_scanned,
213 }
214 }
215
216 pub const fn source_syntax(
217 source: &'a str,
218 root: Option<&'a str>,
219 files_scanned: Option<usize>,
220 ) -> Self {
221 Self::new(
222 INVENTORY_SCOPE_SOURCE_TREE,
223 INVENTORY_SCANNER_SOURCE_SYNTAX,
224 source,
225 root,
226 files_scanned,
227 )
228 }
229
230 pub const fn unknown_source_syntax() -> InventoryContext<'static> {
231 InventoryContext::source_syntax(INVENTORY_SOURCE_UNKNOWN, None, None)
232 }
233
234 pub const fn policy_migration(
235 source: &'a str,
236 root: Option<&'a str>,
237 files_scanned: Option<usize>,
238 ) -> Self {
239 Self::new(
240 INVENTORY_SCOPE_SOURCE_TREE,
241 INVENTORY_SCANNER_POLICY_MIGRATION,
242 source,
243 root,
244 files_scanned,
245 )
246 }
247}
248
249impl<'a> Default for InventoryContext<'a> {
250 fn default() -> Self {
251 Self::unknown_source_syntax()
252 }
253}
254
255#[derive(Debug, Clone, Copy, Default)]
256pub struct ReportContext<'a> {
257 pub inventory: InventoryContext<'a>,
258 pub baseline_debt_entries: Option<usize>,
259 pub policy_missing_evidence_entries: Option<usize>,
260 pub broken_evidence_links: Option<usize>,
261 pub weak_evidence_references: Option<usize>,
262}
263
264impl<'a> ReportContext<'a> {
265 pub const fn source_syntax(
266 inventory_source: &'a str,
267 source_tree_root: Option<&'a str>,
268 inventory_files: Option<usize>,
269 baseline_debt_entries: Option<usize>,
270 ) -> Self {
271 Self {
272 inventory: InventoryContext::source_syntax(
273 inventory_source,
274 source_tree_root,
275 inventory_files,
276 ),
277 baseline_debt_entries,
278 policy_missing_evidence_entries: None,
279 broken_evidence_links: None,
280 weak_evidence_references: None,
281 }
282 }
283}
284
285impl<'a> From<ReportContext<'a>> for InventoryContext<'a> {
286 fn from(context: ReportContext<'a>) -> Self {
287 context.inventory
288 }
289}