Repository navigation
Expand file tree
/
Copy pathlib.rs
More file actions
417 lines (398 loc) · 15.1 KB
/
Copy pathlib.rs
File metadata and controls
417 lines (398 loc) · 15.1 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
//! 旧语言清单的只读迁移观察;清单不表示原生检查器已实现。
use codeguard_core::{CANDIDATE_PLATFORMS, CHECK_CATEGORIES};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashSet};
mod capability_validation;
mod python_suite_rule;
pub use python_suite_rule::{is_required_python_suite_parent, python_suite_rule_sha256};
mod go_package_rule;
pub use go_package_rule::{go_package_rule_sha256, missing_go_package_candidate};
mod cargo_audit;
mod cargo_build;
pub use cargo_audit::{
CargoAuditFinding, CargoAuditObservation, bind_cargo_audit_lockfile, parse_cargo_audit_json,
};
mod cargo_build_diagnostic;
mod cargo_build_parsed;
pub use cargo_build::parse_cargo_build_json;
pub use cargo_build_diagnostic::CargoBuildDiagnostic;
pub use cargo_build_parsed::CargoBuildParsed;
mod cargo_clippy;
mod cargo_module_model;
mod cargo_rustdoc;
mod checker_configuration;
mod checkstyle_command;
mod checkstyle_config;
mod checkstyle_diagnostic;
mod checkstyle_failure;
mod checkstyle_parsed;
mod checkstyle_result;
mod checkstyle_rule_binding;
mod eslint_command;
mod eslint_config_state;
mod eslint_local_candidate;
mod eslint_local_readiness;
mod npm_audit_command;
mod npm_locked_node;
mod rustdoc_finding;
mod rustdoc_parsed;
pub use npm_locked_node::NpmLockedNode;
mod npm_audit_component;
mod npm_audit_config;
pub use npm_audit_command::NpmAuditCommand;
pub use npm_audit_config::inspect_npm_audit_config;
mod grammar_test_corpus;
mod grammar_test_sample;
mod npm_audit_json;
mod npm_audit_observation;
mod source_map;
mod source_mapped_recovery;
mod strict_json;
pub use grammar_test_corpus::parse_grammar_test_corpus;
pub use grammar_test_sample::GrammarTestSample;
mod syntax_precheck_candidate_report;
pub use eslint_config_state::EslintConfigState;
pub use eslint_local_candidate::EslintLocalCandidate;
pub use eslint_local_readiness::inspect_eslint_local_candidate;
pub use npm_audit_component::NpmAuditComponent;
pub use npm_audit_json::parse_npm_audit_json;
pub use npm_audit_observation::NpmAuditObservation;
pub use source_map::{SourceMap, map_syntax_recovery};
pub use source_mapped_recovery::SourceMappedRecovery;
pub use strict_json::parse_unique_json;
pub use syntax_precheck_candidate_report::parse_syntax_precheck_candidate_report;
mod eslint_effective_rule;
pub use eslint_effective_rule::parse_eslint_effective_rule;
mod dart_wasm_compat;
mod eslint_diagnostic;
mod eslint_file_report;
mod eslint_json;
mod eslint_message_report;
mod eslint_parsed;
mod go_candidate;
mod ruby_candidate;
mod ruby_candidate_profile;
mod ruby_candidate_slot;
mod ruby_candidate_tool;
mod grammar_asset_manifest;
mod legacy_dylink_compat;
mod zig_wasm_compat;
pub use dart_wasm_compat::adapt_dart_wasm;
pub use grammar_asset_manifest::{
GrammarAsset, GrammarAssetManifest, bundled_grammar_candidate, bundled_grammar_candidates,
bundled_grammar_metadata, parse_grammar_asset_manifest, verify_grammar_asset,
};
pub use legacy_dylink_compat::adapt_legacy_dylink;
pub use zig_wasm_compat::adapt_zig_wasm;
mod go_list_package;
mod go_list_scope;
mod go_vet;
mod javadoc_output;
mod javadoc_replay_pom;
mod maven_dependency_pom;
mod maven_dependency_tree;
mod maven_javadoc_output;
mod maven_module_model;
mod maven_wrapper_candidate;
mod maven_wrapper_readiness;
mod owasp_dependency_check;
mod owasp_maven_attribution;
mod owasp_maven_pom;
mod p3c_rule_catalog;
mod package_manifest;
mod pip_audit_command;
mod pip_audit_dependency;
mod pip_audit_finding;
mod pip_audit_json;
mod pip_audit_observation;
mod pmd6_command;
mod pmd_xml;
mod python_requirements;
mod python_standard_lock;
mod ruff;
mod ruff_rulepack;
mod ruff_settings;
pub use capability_validation::validate_capability_inventory;
pub use cargo_clippy::{ClippyFinding, ClippyParsed, parse_cargo_clippy_json};
pub use cargo_module_model::CargoModuleModel;
pub use cargo_rustdoc::parse_cargo_rustdoc_json;
pub use checker_configuration::{
CheckerConfiguration, configured_p3c_rulesets, inspect_gradle_unknown, inspect_maven_pom,
inspect_maven_unreadable, inspect_ruff_config, inspect_ruff_missing, inspect_ruff_unknown,
};
pub use checkstyle_command::CheckstyleCommand;
pub use checkstyle_config::checkstyle_comment_config_local_eligible;
pub use checkstyle_config::checkstyle_comment_rule_bindings;
pub use checkstyle_diagnostic::CheckstyleDiagnostic;
pub use checkstyle_failure::checkstyle_native_failure_reason;
pub use checkstyle_parsed::{CheckstyleParsed, parse_checkstyle_xml};
pub use checkstyle_result::{CheckstyleResult, evaluate_checkstyle_report};
pub use checkstyle_rule_binding::CheckstyleRuleBinding;
pub use eslint_command::EslintCommand;
pub use eslint_diagnostic::EslintDiagnostic;
pub use eslint_json::{eslint_report_version_matches, parse_eslint_json};
pub use eslint_parsed::EslintParsed;
pub use go_candidate::{
GoCandidateProfile, GoCandidateSlot, bundled_go_candidate_profile, parse_go_candidate_profile,
};
pub use go_list_scope::{GoListScope, parse_go_list_scope};
pub use go_vet::{GoVetFinding, GoVetParseState, GoVetParsed, parse_go_vet_json};
pub use javadoc_output::{
JavadocDiagnostic, JavadocParseState, JavadocParsed, parse_javadoc_output,
};
pub use javadoc_replay_pom::javadoc_pom_direct_replay_eligible;
pub use maven_dependency_pom::{
dependency_pom_direct_replay_eligible, dependency_pom_project_identity,
};
pub use maven_dependency_tree::{
MavenDependencyNode, MavenDependencyTree, parse_maven_dependency_tree_json,
};
pub use maven_javadoc_output::{
MavenJavadocDiagnostic, MavenJavadocParseState, MavenJavadocParsed, parse_maven_javadoc_output,
};
pub use maven_module_model::MavenModuleModel;
pub use maven_wrapper_candidate::MavenWrapperCandidate;
pub use maven_wrapper_readiness::inspect_maven_wrapper_candidate;
pub use owasp_dependency_check::{
OwaspAdvisoryObservation, OwaspDependencyCheckReport, parse_owasp_dependency_check_json,
};
pub use owasp_maven_attribution::{
OwaspArtifactBindingState, OwaspAttribution, OwaspAttributionState,
attribute_owasp_advisories_to_maven_graph, bind_owasp_advisories_to_artifact_digests,
};
pub use owasp_maven_pom::{OwaspMavenPomPlan, owasp_maven_pom_plan};
pub use p3c_rule_catalog::p3c_rule_in_selected_rulesets;
pub use package_manifest::{PackageDeclaration, parse_package_json};
pub use pip_audit_command::PipAuditCommand;
pub use pip_audit_dependency::PipAuditDependency;
pub use pip_audit_finding::PipAuditFinding;
pub use pip_audit_json::parse_pip_audit_json;
pub use pip_audit_observation::PipAuditObservation;
pub use pmd_xml::{PmdDiagnostic, PmdParseState, PmdParsed, parse_pmd_xml};
pub use pmd6_command::Pmd6Command;
pub use python_requirements::{PythonRequirementsPins, inspect_python_requirements_pins};
pub use python_standard_lock::{bind_pip_audit_lockfile, parse_pylock_package_identities};
pub use ruff::{
RuffDiagnostic, RuffLocation, RuffParseState, RuffParsed, is_ruff_pydocstyle_rule,
parse_ruff_json,
};
pub use ruff_rulepack::{
RuffRuleMapping, RuffRulepack, bundled_ruff_rulepack, parse_ruff_rulepack,
};
pub use ruff_settings::{RuffSettingsObservation, parse_ruff_settings};
pub use rustdoc_finding::RustdocFinding;
pub use rustdoc_parsed::RustdocParsed;
/// 从旧注册表导入的语言元数据。
#[derive(Debug, Deserialize)]
pub struct Language {
/// 规范语言 ID。
pub id: String,
/// 旧版本宣称的状态,仅用于迁移对照。
pub status: String,
/// 文件扩展名,用于后续静态发现。
#[serde(default)]
pub extensions: Vec<String>,
/// 项目清单文件名候选;仅供只读发现,不能证明构建器可执行。
#[serde(default)]
pub markers: Vec<String>,
/// 旧清单登记的原生检查器配置文件名候选;存在不等于检查器已配置。
#[serde(default)]
pub linter_config_files: Vec<String>,
/// 旧清单的 lint 命令声明,不构成新适配器验收。
pub lint: Option<Vec<String>>,
/// 旧清单的格式化命令声明,不能替代 lint。
pub format: Option<Vec<String>>,
}
/// 某语言在候选平台上的六类别能力矩阵。
#[derive(Debug, Serialize)]
pub struct CapabilityRow<'a> {
/// 规范语言 ID。
pub language: &'a str,
/// 仅供迁移对照的旧登记状态。
pub legacy_status: &'a str,
/// 旧 lint 命令是否存在,不能据此宣布 implemented。
pub legacy_lint_declared: bool,
/// 旧 formatter 是否存在,不能据此宣布 lint implemented。
pub legacy_formatter_declared: bool,
/// 平台到类别到能力状态的完整矩阵。
pub platforms: BTreeMap<&'static str, BTreeMap<&'static str, CapabilityCell>>,
}
/// 单一语言、类别、平台的能力声明与理由。
#[derive(Clone, Debug, Serialize)]
pub struct CapabilityCell {
/// implemented、gap 或 not_applicable;本阶段只构造 gap。
pub status: &'static str,
/// 当前缺口原因,不能作为跳过义务的理由。
pub reason: &'static str,
}
/// 为一条旧语言构建保守能力记录;尚无真实验收时所有单元保持 gap。
#[must_use]
pub fn capability_row(language: &Language) -> CapabilityRow<'_> {
let categories: BTreeMap<&'static str, CapabilityCell> = CHECK_CATEGORIES
.iter()
.map(|category| {
(
*category,
CapabilityCell {
status: "gap",
reason: "native_adapter_not_validated",
},
)
})
.collect();
let platforms = CANDIDATE_PLATFORMS
.iter()
.map(|platform| (*platform, categories.clone()))
.collect();
CapabilityRow {
language: &language.id,
legacy_status: &language.status,
legacy_lint_declared: language
.lint
.as_ref()
.is_some_and(|items| !items.is_empty()),
legacy_formatter_declared: language
.format
.as_ref()
.is_some_and(|items| !items.is_empty()),
platforms,
}
}
/// 语言注册表及其基线版本。
#[derive(Debug, Deserialize)]
pub struct LegacyRegistry {
/// 旧注册表语言记录。
pub languages: Vec<Language>,
}
/// 解析编译时固定的旧清单并验证 54 stable/3 planned 身份基线。
pub fn legacy_registry() -> Result<LegacyRegistry, String> {
let raw = include_str!("../../../rulepacks/legacy_languages.json");
parse_legacy_registry(raw)
}
/// 解析指定注册表字节并核对固定身份;供损坏发行清单反例使用。
pub fn parse_legacy_registry(raw: &str) -> Result<LegacyRegistry, String> {
let registry: LegacyRegistry = serde_json::from_str(raw).map_err(|error| error.to_string())?;
let ids: HashSet<&str> = registry
.languages
.iter()
.map(|language| language.id.as_str())
.collect();
let stable = registry
.languages
.iter()
.filter(|language| language.status == "stable")
.count();
let planned = registry
.languages
.iter()
.filter(|language| language.status == "planned")
.count();
if ids.len() != 57 || stable != 54 || planned != 3 {
return Err(format!(
"旧语言清单身份不匹配:unique={}, stable={stable}, planned={planned}",
ids.len()
));
}
for language in ®istry.languages {
let mut seen = HashSet::new();
for candidate in &language.linter_config_files {
if candidate.is_empty()
|| candidate.contains('\\')
|| candidate.contains('*')
|| candidate.contains('?')
|| candidate.chars().any(char::is_control)
|| candidate
.split('/')
.any(|part| part.is_empty() || matches!(part, "." | ".."))
|| !seen.insert(candidate)
{
return Err(format!("{}: 检查器配置文件名无效或重复", language.id));
}
}
}
Ok(registry)
}
#[cfg(test)]
mod tests {
use super::{capability_row, legacy_registry, parse_legacy_registry};
#[test]
fn baseline_has_all_legacy_entries_without_claiming_adapter_coverage() {
let registry = legacy_registry().expect("固定语言清单应可解析");
assert_eq!(registry.languages.len(), 57);
assert!(
registry
.languages
.iter()
.any(|language| language.id == "java")
);
assert!(
registry
.languages
.iter()
.any(|language| language.id == "metal")
);
}
#[test]
fn registry_rejects_broad_or_traversing_checker_config_names() {
let baseline: serde_json::Value =
serde_json::from_str(include_str!("../../../rulepacks/legacy_languages.json")).unwrap();
for bad in ["../.eslintrc", "src/*.xml", ".", "", "config\\lint.xml"] {
let mut changed = baseline.clone();
changed["languages"][0]["linter_config_files"] = serde_json::json!([bad]);
assert!(
parse_legacy_registry(&changed.to_string()).is_err(),
"{bad:?}"
);
}
}
#[test]
fn formatter_only_entries_remain_lint_gaps_on_every_platform() {
let registry = legacy_registry().expect("固定语言清单应可解析");
for id in ["julia", "pascal"] {
let language = registry
.languages
.iter()
.find(|language| language.id == id)
.expect("旧清单必须保留该语言");
let row = capability_row(language);
assert!(!row.legacy_lint_declared);
assert!(row.legacy_formatter_declared);
assert_eq!(row.platforms.len(), 5);
for categories in row.platforms.values() {
assert_eq!(categories.len(), 6);
assert_eq!(categories["lint"].status, "gap");
}
}
}
#[test]
fn corrupt_release_registry_is_not_accepted() {
assert!(parse_legacy_registry("not json").is_err());
assert!(parse_legacy_registry(r#"{"languages":[]}"#).is_err());
}
}
mod cargo_build_finding_identity;
pub use cargo_build_finding_identity::cargo_build_finding_record;
mod eslint_finding_identity;
pub use eslint_finding_identity::{project_eslint_findings, validate_records};
mod go_finding_identity;
pub use go_finding_identity::go_finding_record;
mod rustdoc_finding_identity;
pub use rustdoc_finding_identity::rustdoc_finding_record;
mod kotlin_diagnostic;
mod kotlin_diagnostics;
mod kotlin_parsed;
pub use kotlin_diagnostic::KotlinDiagnostic;
pub use kotlin_diagnostics::parse_kotlin_diagnostics;
pub use kotlin_parsed::KotlinParsed;
mod kotlin_native_observation;
pub use kotlin_native_observation::valid_kotlin_native_observation;
pub use ruby_candidate::{bundled_ruby_candidate_profile, parse_ruby_candidate_profile};
pub use ruby_candidate_profile::RubyCandidateProfile;
pub use ruby_candidate_slot::RubyCandidateSlot;
pub use ruby_candidate_tool::RubyCandidateTool;
mod shellcheck_diagnostic;
mod shellcheck_parsed;
mod shellcheck_json;
pub use shellcheck_diagnostic::ShellCheckDiagnostic;
pub use shellcheck_parsed::ShellCheckParsed;
pub use shellcheck_json::parse_shellcheck_json1;