Skip to main content

provenant/parsers/
mod.rs

1mod about;
2#[cfg(test)]
3mod about_scan_test;
4#[cfg(test)]
5mod about_test;
6mod alpine;
7#[cfg(test)]
8mod alpine_scan_test;
9mod arch;
10#[cfg(test)]
11mod arch_scan_test;
12#[cfg(test)]
13mod arch_test;
14mod autotools;
15#[cfg(test)]
16mod autotools_test;
17mod bazel;
18#[cfg(test)]
19mod bazel_module_test;
20#[cfg(test)]
21mod bazel_test;
22mod bower;
23#[cfg(test)]
24mod bower_scan_test;
25#[cfg(test)]
26mod bower_test;
27mod buck;
28#[cfg(test)]
29mod buck_test;
30mod bun_lock;
31#[cfg(test)]
32mod bun_lock_test;
33mod bun_lockb;
34#[cfg(test)]
35mod bun_lockb_test;
36mod cargo;
37mod cargo_lock;
38#[cfg(test)]
39mod cargo_lock_test;
40#[cfg(test)]
41mod cargo_scan_test;
42#[cfg(test)]
43mod cargo_test;
44mod chef;
45#[cfg(test)]
46mod chef_scan_test;
47#[cfg(test)]
48mod chef_test;
49mod clojure;
50#[cfg(test)]
51mod clojure_test;
52#[cfg(test)]
53mod cocoapods_scan_test;
54mod compiled_binary;
55mod composer;
56#[cfg(test)]
57mod composer_scan_test;
58#[cfg(test)]
59mod composer_test;
60mod conan;
61mod conan_data;
62#[cfg(test)]
63mod conan_data_test;
64#[cfg(test)]
65mod conan_scan_test;
66#[cfg(test)]
67mod conan_test;
68mod conda;
69mod conda_meta_json;
70#[cfg(test)]
71mod conda_meta_json_test;
72#[cfg(test)]
73mod conda_scan_test;
74#[cfg(test)]
75mod conda_test;
76mod cpan;
77mod cpan_dist_ini;
78#[cfg(test)]
79mod cpan_dist_ini_test;
80mod cpan_makefile_pl;
81#[cfg(test)]
82mod cpan_makefile_pl_test;
83#[cfg(test)]
84mod cpan_scan_test;
85#[cfg(test)]
86mod cpan_test;
87mod cran;
88#[cfg(test)]
89mod cran_scan_test;
90#[cfg(test)]
91mod cran_test;
92mod dart;
93#[cfg(test)]
94mod dart_scan_test;
95#[cfg(test)]
96mod dart_test;
97mod debian;
98#[cfg(test)]
99mod debian_scan_test;
100#[cfg(test)]
101mod debian_test;
102mod deno;
103mod deno_lock;
104#[cfg(test)]
105mod deno_lock_test;
106#[cfg(test)]
107mod deno_scan_test;
108#[cfg(test)]
109mod deno_test;
110mod docker;
111#[cfg(test)]
112mod docker_scan_test;
113#[cfg(test)]
114mod docker_test;
115mod freebsd;
116#[cfg(test)]
117mod freebsd_scan_test;
118#[cfg(test)]
119mod freebsd_test;
120mod gitmodules;
121#[cfg(test)]
122mod gitmodules_scan_test;
123mod go;
124mod go_mod_graph;
125#[cfg(test)]
126mod go_scan_test;
127#[cfg(test)]
128mod go_test;
129#[cfg(test)]
130mod go_work_test;
131#[cfg(all(test, feature = "golden-tests"))]
132pub(crate) mod golden_test_utils;
133mod gradle;
134mod gradle_lock;
135#[cfg(test)]
136mod gradle_lock_test;
137mod gradle_module;
138#[cfg(test)]
139mod gradle_module_scan_test;
140#[cfg(test)]
141mod gradle_module_test;
142#[cfg(test)]
143mod gradle_scan_test;
144mod hackage;
145#[cfg(test)]
146mod hackage_scan_test;
147#[cfg(test)]
148mod hackage_test;
149mod haxe;
150#[cfg(test)]
151mod haxe_scan_test;
152#[cfg(test)]
153mod haxe_test;
154mod helm;
155#[cfg(test)]
156mod helm_scan_test;
157#[cfg(test)]
158mod helm_test;
159mod hex_lock;
160#[cfg(test)]
161mod hex_lock_test;
162mod license_normalization;
163mod maven;
164#[cfg(test)]
165mod maven_scan_test;
166#[cfg(test)]
167mod maven_test;
168mod meson;
169#[cfg(test)]
170mod meson_test;
171pub mod metadata;
172mod microsoft_update_manifest;
173#[cfg(test)]
174mod microsoft_update_manifest_test;
175mod misc;
176#[cfg(test)]
177mod misc_test;
178mod nix;
179#[cfg(test)]
180mod nix_scan_test;
181#[cfg(test)]
182mod nix_test;
183mod npm;
184mod npm_lock;
185#[cfg(test)]
186mod npm_lock_test;
187#[cfg(test)]
188mod npm_scan_test;
189#[cfg(test)]
190mod npm_test;
191mod npm_workspace;
192#[cfg(test)]
193mod npm_workspace_test;
194mod nuget;
195#[cfg(test)]
196mod nuget_scan_test;
197#[cfg(test)]
198mod nuget_test;
199mod opam;
200#[cfg(test)]
201mod opam_scan_test;
202mod os_release;
203#[cfg(test)]
204mod os_release_test;
205#[cfg(test)]
206mod osgi_test;
207mod pep508;
208mod pip_inspect_deplock;
209#[cfg(test)]
210mod pip_inspect_deplock_test;
211mod pipfile_lock;
212#[cfg(test)]
213mod pipfile_lock_test;
214mod pixi;
215#[cfg(test)]
216mod pixi_scan_test;
217#[cfg(test)]
218mod pixi_test;
219mod pnpm_lock;
220#[cfg(test)]
221mod pnpm_lock_test;
222mod podfile;
223mod podfile_lock;
224#[cfg(test)]
225mod podfile_lock_test;
226mod podspec;
227mod podspec_json;
228#[cfg(test)]
229mod podspec_json_test;
230mod poetry_lock;
231#[cfg(test)]
232mod poetry_lock_test;
233mod pylock_toml;
234#[cfg(test)]
235mod pylock_toml_test;
236mod python;
237#[cfg(test)]
238mod python_scan_test;
239#[cfg(test)]
240mod python_test;
241mod readme;
242#[cfg(test)]
243mod readme_test;
244mod requirements_txt;
245#[cfg(test)]
246mod requirements_txt_test;
247pub(crate) mod rfc822;
248mod rpm_db;
249#[cfg(test)]
250mod rpm_db_scan_test;
251mod rpm_license_files;
252#[cfg(test)]
253mod rpm_license_files_test;
254mod rpm_mariner_manifest;
255#[cfg(test)]
256mod rpm_mariner_manifest_test;
257mod rpm_parser;
258#[cfg(test)]
259mod rpm_scan_test;
260mod rpm_specfile;
261#[cfg(test)]
262mod rpm_specfile_test;
263mod rpm_yumdb;
264mod ruby;
265#[cfg(test)]
266mod ruby_scan_test;
267#[cfg(test)]
268mod ruby_test;
269mod sbt;
270#[cfg(test)]
271mod sbt_test;
272#[cfg(test)]
273mod scan_test_utils;
274mod swift_manifest_json;
275#[cfg(test)]
276mod swift_manifest_json_test;
277mod swift_resolved;
278#[cfg(test)]
279mod swift_resolved_test;
280#[cfg(test)]
281mod swift_scan_test;
282mod swift_show_dependencies;
283#[cfg(test)]
284mod swift_show_dependencies_test;
285pub mod utils;
286mod uv_lock;
287#[cfg(test)]
288mod uv_lock_test;
289mod vcpkg;
290#[cfg(test)]
291mod vcpkg_scan_test;
292#[cfg(test)]
293mod vcpkg_test;
294mod yarn_lock;
295#[cfg(test)]
296mod yarn_lock_test;
297
298#[cfg(all(test, feature = "golden-tests"))]
299mod golden_test;
300
301use std::cell::RefCell;
302use std::path::Path;
303
304use crate::models::{PackageData, PackageType};
305use crate::parsers::license_normalization::finalize_package_declared_license_references;
306
307thread_local! {
308    static PARSER_DIAGNOSTIC_STACK: RefCell<Vec<Vec<String>>> = const { RefCell::new(Vec::new()) };
309}
310
311#[derive(Debug, Default)]
312pub struct ParsePackagesResult {
313    pub packages: Vec<PackageData>,
314    pub scan_errors: Vec<String>,
315}
316
317pub(crate) fn capture_parser_diagnostics<F>(extract: F) -> ParsePackagesResult
318where
319    F: FnOnce() -> Vec<PackageData>,
320{
321    PARSER_DIAGNOSTIC_STACK.with(|stack| {
322        stack.borrow_mut().push(Vec::new());
323    });
324
325    let packages = extract()
326        .into_iter()
327        .map(|mut package| {
328            finalize_package_declared_license_references(&mut package);
329            package
330        })
331        .collect();
332    let scan_errors =
333        PARSER_DIAGNOSTIC_STACK.with(|stack| stack.borrow_mut().pop().unwrap_or_default());
334
335    ParsePackagesResult {
336        packages,
337        scan_errors,
338    }
339}
340
341pub(crate) fn record_parser_diagnostic(message: String) -> bool {
342    PARSER_DIAGNOSTIC_STACK.with(|stack| {
343        let mut stack = stack.borrow_mut();
344        let Some(active) = stack.last_mut() else {
345            return false;
346        };
347        active.push(message);
348        true
349    })
350}
351
352#[macro_export]
353macro_rules! parser_warn {
354    ($($arg:tt)*) => {{
355        let message = format!($($arg)*);
356        if !$crate::parsers::record_parser_diagnostic(message.clone()) {
357            log::warn!("{message}");
358        }
359    }};
360}
361
362/// Package parser trait for extracting metadata from package manifest files.
363///
364/// Each parser implementation handles a specific package manager/ecosystem
365/// (npm, Maven, Python, Cargo, etc.) and extracts standardized metadata into
366/// `PackageData` structures compatible with ScanCode Toolkit JSON output format.
367///
368/// # Implementation Guide
369///
370/// Implementors must provide:
371/// - `PACKAGE_TYPE`: Package URL (purl) type identifier (e.g., "npm", "pypi", "maven")
372/// - `is_match()`: Returns true if the given file path matches this parser's expected format
373/// - `extract_packages()`: Parses the file and returns all extracted package metadata
374///
375/// # Error Handling
376///
377/// Parsers should handle errors gracefully by returning default/empty `PackageData`
378/// and logging warnings with [`crate::parser_warn!`] rather than panicking. Scanner
379/// dispatch captures those warnings and attaches them to `FileInfo.scan_errors` so
380/// CI output and serialized scan results stay aligned.
381/// This allows the scan to continue processing other files even when individual
382/// files fail to parse.
383///
384/// # Example
385///
386/// ```ignore
387/// use provenant::models::{PackageData, PackageType};
388/// use provenant::parsers::PackageParser;
389/// use std::path::Path;
390///
391/// pub struct MyParser;
392///
393/// impl PackageParser for MyParser {
394///     const PACKAGE_TYPE: PackageType = PackageType::Npm;
395///
396///     fn is_match(path: &Path) -> bool {
397///         path.file_name().is_some_and(|name| name == "package.json")
398///     }
399///
400///     fn extract_packages(path: &Path) -> Vec<PackageData> {
401///         vec![PackageData::default()]
402///     }
403/// }
404/// ```
405pub trait PackageParser {
406    /// Package URL type identifier for this parser (e.g., PackageType::Npm, PackageType::Pypi).
407    const PACKAGE_TYPE: PackageType;
408
409    /// Extracts all packages from the given file path.
410    ///
411    /// Returns a vector of `PackageData` structures containing all extracted metadata
412    /// including name, version, dependencies, licenses, etc. Most parsers return a
413    /// single-element vector, but some (e.g., Bazel BUILD, Buck BUCK, Debian control)
414    /// can contain multiple packages in a single file.
415    ///
416    /// On parse errors, returns a vector with a default `PackageData` with minimal or
417    /// no fields populated.
418    fn extract_packages(path: &Path) -> Vec<PackageData>;
419
420    /// Checks if the given file path matches this parser's expected format.
421    ///
422    /// Returns true if the file should be handled by this parser based on filename,
423    /// extension, or path patterns. Used by the scanner to route files to appropriate parsers.
424    fn is_match(path: &Path) -> bool;
425
426    /// Returns the first package from [`extract_packages()`](Self::extract_packages),
427    /// or a default [`PackageData`] if the file contains no packages.
428    fn extract_first_package(path: &Path) -> PackageData {
429        Self::extract_packages(path)
430            .into_iter()
431            .map(|mut package| {
432                finalize_package_declared_license_references(&mut package);
433                package
434            })
435            .next()
436            .unwrap_or_default()
437    }
438}
439
440pub use self::about::AboutFileParser;
441pub use self::alpine::{AlpineApkParser, AlpineApkbuildParser, AlpineInstalledParser};
442pub use self::arch::{ArchPkginfoParser, ArchSrcinfoParser};
443pub use self::autotools::AutotoolsConfigureParser;
444pub use self::bazel::{BazelBuildParser, BazelModuleParser};
445pub use self::bower::BowerJsonParser;
446pub use self::buck::{BuckBuildParser, BuckMetadataBzlParser};
447pub use self::bun_lock::BunLockParser;
448pub use self::bun_lockb::BunLockbParser;
449pub use self::cargo::CargoParser;
450#[cfg_attr(not(test), allow(unused_imports))]
451pub use self::cargo_lock::CargoLockParser;
452pub use self::chef::{ChefMetadataJsonParser, ChefMetadataRbParser};
453pub use self::clojure::{ClojureDepsEdnParser, ClojureProjectCljParser};
454pub(crate) use self::compiled_binary::try_parse_compiled_bytes;
455pub use self::composer::{ComposerJsonParser, ComposerLockParser};
456pub use self::conan::{ConanFilePyParser, ConanLockParser, ConanfileTxtParser};
457pub use self::conan_data::ConanDataParser;
458pub use self::conda::{CondaEnvironmentYmlParser, CondaMetaYamlParser};
459pub use self::conda_meta_json::CondaMetaJsonParser;
460pub use self::cpan::{CpanManifestParser, CpanMetaJsonParser, CpanMetaYmlParser};
461pub use self::cpan_dist_ini::CpanDistIniParser;
462pub use self::cpan_makefile_pl::CpanMakefilePlParser;
463pub use self::cran::CranParser;
464pub use self::dart::{PubspecLockParser, PubspecYamlParser};
465pub use self::debian::{
466    DebianControlInExtractedDebParser, DebianControlParser, DebianCopyrightParser, DebianDebParser,
467    DebianDebianTarParser, DebianDistrolessInstalledParser, DebianDscParser,
468    DebianInstalledListParser, DebianInstalledMd5sumsParser, DebianInstalledParser,
469    DebianMd5sumInPackageParser, DebianOrigTarParser,
470};
471pub use self::deno::DenoParser;
472pub use self::deno_lock::DenoLockParser;
473pub use self::docker::DockerfileParser;
474pub use self::freebsd::FreebsdCompactManifestParser;
475pub use self::gitmodules::GitmodulesParser;
476pub use self::go::{GoModParser, GoSumParser, GoWorkParser, GodepsParser};
477pub use self::go_mod_graph::GoModGraphParser;
478pub use self::gradle::GradleParser;
479pub use self::gradle_lock::GradleLockfileParser;
480pub use self::gradle_module::GradleModuleParser;
481pub use self::hackage::{HackageCabalParser, HackageCabalProjectParser, HackageStackYamlParser};
482pub use self::haxe::HaxeParser;
483pub use self::helm::{HelmChartLockParser, HelmChartYamlParser};
484pub use self::hex_lock::HexLockParser;
485pub use self::maven::MavenParser;
486pub use self::meson::MesonParser;
487pub use self::microsoft_update_manifest::MicrosoftUpdateManifestParser;
488pub use self::misc::{
489    AndroidApkRecognizer, AndroidLibraryRecognizer, AppleDmgRecognizer, Axis2MarRecognizer,
490    Axis2ModuleXmlRecognizer, CabArchiveRecognizer, ChromeCrxRecognizer, InstallShieldRecognizer,
491    IosIpaRecognizer, IsoImageRecognizer, IvyXmlRecognizer, JBossSarRecognizer,
492    JBossServiceXmlRecognizer, JavaEarAppXmlRecognizer, JavaEarRecognizer, JavaJarRecognizer,
493    JavaWarRecognizer, JavaWarWebXmlRecognizer, MeteorPackageRecognizer, MozillaXpiRecognizer,
494    NsisRecognizer, SharArchiveRecognizer, SquashfsRecognizer,
495};
496pub use self::nix::{NixDefaultParser, NixFlakeLockParser, NixFlakeParser};
497pub use self::npm::NpmParser;
498pub use self::npm_lock::NpmLockParser;
499pub use self::npm_workspace::NpmWorkspaceParser;
500pub use self::nuget::{
501    CentralPackageManagementPropsParser, DirectoryBuildPropsParser, DotNetDepsJsonParser,
502    NupkgParser, NuspecParser, PackageReferenceProjectParser, PackagesConfigParser,
503    PackagesLockParser, ProjectJsonParser, ProjectLockJsonParser,
504};
505pub use self::opam::OpamParser;
506pub use self::os_release::OsReleaseParser;
507pub use self::pip_inspect_deplock::PipInspectDeplockParser;
508pub use self::pipfile_lock::PipfileLockParser;
509pub use self::pixi::{PixiLockParser, PixiTomlParser};
510pub use self::pnpm_lock::PnpmLockParser;
511pub use self::podfile::PodfileParser;
512pub use self::podfile_lock::PodfileLockParser;
513pub use self::podspec::PodspecParser;
514pub use self::podspec_json::PodspecJsonParser;
515pub use self::poetry_lock::PoetryLockParser;
516pub use self::pylock_toml::PylockTomlParser;
517pub use self::python::PythonParser;
518pub use self::readme::ReadmeParser;
519pub use self::requirements_txt::RequirementsTxtParser;
520pub use self::rpm_db::{RpmBdbDatabaseParser, RpmNdbDatabaseParser, RpmSqliteDatabaseParser};
521pub use self::rpm_license_files::RpmLicenseFilesParser;
522pub use self::rpm_mariner_manifest::RpmMarinerManifestParser;
523pub use self::rpm_parser::RpmParser;
524pub use self::rpm_specfile::RpmSpecfileParser;
525pub use self::rpm_yumdb::RpmYumdbParser;
526pub use self::ruby::{
527    GemArchiveParser, GemMetadataExtractedParser, GemfileLockParser, GemfileParser, GemspecParser,
528};
529pub use self::sbt::SbtParser;
530pub use self::swift_manifest_json::SwiftManifestJsonParser;
531pub use self::swift_resolved::SwiftPackageResolvedParser;
532pub use self::swift_show_dependencies::SwiftShowDependenciesParser;
533pub use self::uv_lock::UvLockParser;
534pub use self::vcpkg::VcpkgManifestParser;
535pub use self::yarn_lock::YarnLockParser;
536
537/// Registers all parsers and recognizers, generating dispatch functions.
538///
539/// Parsers are tried first, then recognizers. This ordering is important because
540/// recognizers match broadly by file extension (e.g., `.jar`) and would shadow
541/// more specific parsers if checked first.
542macro_rules! register_package_handlers {
543    (
544        parsers: [$($parser:ty),* $(,)?],
545        recognizers: [$($recognizer:ty),* $(,)?] $(,)?
546    ) => {
547        pub fn try_parse_file(path: &Path) -> Option<ParsePackagesResult> {
548            $(
549                if <$parser>::is_match(path) {
550                    return Some(capture_parser_diagnostics(|| <$parser>::extract_packages(path)));
551                }
552            )*
553            $(
554                if <$recognizer>::is_match(path) {
555                    return Some(capture_parser_diagnostics(|| <$recognizer>::extract_packages(path)));
556                }
557            )*
558            None
559        }
560
561        // Used by the parser-golden maintenance tool in `xtask`.
562        // Scanner runtime dispatch goes through `try_parse_file()`.
563        #[allow(dead_code)]
564        pub fn parse_by_type_name(type_name: &str, path: &Path) -> Option<PackageData> {
565            match type_name {
566                $(
567                    stringify!($parser) => Some(<$parser>::extract_first_package(path)),
568                )*
569                $(
570                    stringify!($recognizer) => Some(<$recognizer>::extract_first_package(path)),
571                )*
572                _ => None
573            }
574        }
575
576        // Used by the parser-golden maintenance tool in `xtask` and by
577        // `tests/scanner_integration.rs` to verify parser registration.
578        #[allow(dead_code)]
579        pub fn list_parser_types() -> Vec<&'static str> {
580            vec![
581                $(
582                    stringify!($parser),
583                )*
584                $(
585                    stringify!($recognizer),
586                )*
587            ]
588        }
589    };
590}
591
592register_package_handlers! {
593    parsers: [
594        AboutFileParser,
595        AlpineApkParser,
596        AlpineApkbuildParser,
597        AlpineInstalledParser,
598        ArchPkginfoParser,
599        ArchSrcinfoParser,
600        AutotoolsConfigureParser,
601        BazelBuildParser,
602        BazelModuleParser,
603        BowerJsonParser,
604        BunLockParser,
605        BunLockbParser,
606        BuckBuildParser,
607        BuckMetadataBzlParser,
608        CargoLockParser,
609        CargoParser,
610        ChefMetadataJsonParser,
611        ChefMetadataRbParser,
612        ClojureDepsEdnParser,
613        ClojureProjectCljParser,
614        ComposerJsonParser,
615        ComposerLockParser,
616        ConanDataParser,
617        ConanFilePyParser,
618        ConanfileTxtParser,
619        ConanLockParser,
620        CondaEnvironmentYmlParser,
621        CondaMetaJsonParser,
622        CondaMetaYamlParser,
623        CpanDistIniParser,
624        CpanMakefilePlParser,
625        CpanManifestParser,
626        CpanMetaJsonParser,
627        CpanMetaYmlParser,
628        CranParser,
629        DebianControlInExtractedDebParser,
630        DebianControlParser,
631        DebianCopyrightParser,
632        DebianDebianTarParser,
633        DebianDebParser,
634        DebianDistrolessInstalledParser,
635        DebianDscParser,
636        DebianInstalledListParser,
637        DebianInstalledMd5sumsParser,
638        DebianInstalledParser,
639        DebianMd5sumInPackageParser,
640        DebianOrigTarParser,
641        DenoParser,
642        DenoLockParser,
643        DockerfileParser,
644        FreebsdCompactManifestParser,
645        GemArchiveParser,
646        GemfileLockParser,
647        GemfileParser,
648        GemMetadataExtractedParser,
649        GemspecParser,
650        GitmodulesParser,
651        GodepsParser,
652        GoModParser,
653        GoModGraphParser,
654        GoSumParser,
655        GoWorkParser,
656        GradleLockfileParser,
657        GradleParser,
658        GradleModuleParser,
659        HackageCabalParser,
660        HackageCabalProjectParser,
661        HackageStackYamlParser,
662        HelmChartYamlParser,
663        HelmChartLockParser,
664        HaxeParser,
665        HexLockParser,
666        MavenParser,
667        MesonParser,
668        MicrosoftUpdateManifestParser,
669        NixDefaultParser,
670        NixFlakeLockParser,
671        NixFlakeParser,
672        NpmLockParser,
673        NpmParser,
674        NpmWorkspaceParser,
675        DotNetDepsJsonParser,
676        CentralPackageManagementPropsParser,
677        DirectoryBuildPropsParser,
678        NupkgParser,
679        NuspecParser,
680        PackageReferenceProjectParser,
681        OpamParser,
682        OsReleaseParser,
683        PackagesConfigParser,
684        PackagesLockParser,
685        ProjectJsonParser,
686        ProjectLockJsonParser,
687        PipfileLockParser,
688        PipInspectDeplockParser,
689        PixiTomlParser,
690        PixiLockParser,
691        PnpmLockParser,
692        PodfileLockParser,
693        PodfileParser,
694        PodspecJsonParser,
695        PodspecParser,
696        PoetryLockParser,
697        PylockTomlParser,
698        PubspecLockParser,
699        PubspecYamlParser,
700        PythonParser,
701        UvLockParser,
702        VcpkgManifestParser,
703        ReadmeParser,
704        RequirementsTxtParser,
705        RpmBdbDatabaseParser,
706        RpmLicenseFilesParser,
707        RpmMarinerManifestParser,
708        RpmNdbDatabaseParser,
709        RpmParser,
710        RpmSpecfileParser,
711        RpmSqliteDatabaseParser,
712        RpmYumdbParser,
713        SbtParser,
714        SwiftManifestJsonParser,
715        SwiftPackageResolvedParser,
716        SwiftShowDependenciesParser,
717        YarnLockParser,
718    ],
719    recognizers: [
720        AndroidApkRecognizer,
721        AndroidLibraryRecognizer,
722        AppleDmgRecognizer,
723        Axis2MarRecognizer,
724        Axis2ModuleXmlRecognizer,
725        CabArchiveRecognizer,
726        ChromeCrxRecognizer,
727        InstallShieldRecognizer,
728        IosIpaRecognizer,
729        IsoImageRecognizer,
730        IvyXmlRecognizer,
731        JavaEarAppXmlRecognizer,
732        JavaEarRecognizer,
733        JavaJarRecognizer,
734        JavaWarRecognizer,
735        JavaWarWebXmlRecognizer,
736        JBossSarRecognizer,
737        JBossServiceXmlRecognizer,
738        MeteorPackageRecognizer,
739        MozillaXpiRecognizer,
740        NsisRecognizer,
741        SharArchiveRecognizer,
742        SquashfsRecognizer,
743    ],
744}