arch_toolkit/deps/mod.rs
1//! Dependency parsing and resolution utilities for Arch Linux packages.
2//!
3//! This module provides a comprehensive set of functions and types for working with
4//! Arch Linux package dependencies, including parsing, version comparison, package
5//! querying, dependency resolution, and reverse dependency analysis.
6//!
7//! # Features
8//!
9//! This module is enabled with the `deps` feature flag:
10//!
11//! ```toml
12//! [dependencies]
13//! arch-toolkit = { version = "0.1.2", features = ["deps"] }
14//! ```
15//!
16//! Some functions require the `aur` feature for AUR integration:
17//!
18//! ```toml
19//! [dependencies]
20//! arch-toolkit = { version = "0.1.2", features = ["deps", "aur"] }
21//! ```
22//!
23//! # Overview
24//!
25//! The deps module provides:
26//!
27//! - **Parsing**: Parse dependency specifications, pacman output, .SRCINFO files, and PKGBUILD files
28//! - **Version Comparison**: Compare package versions using pacman-compatible algorithms
29//! - **Package Querying**: Query installed packages, upgradable packages, and package versions
30//! - **Dependency Resolution**: Resolve dependencies for packages from official repos, AUR, or local packages
31//! - **Reverse Dependency Analysis**: Find all packages that depend on a given package
32//!
33//! All functions gracefully degrade when pacman is unavailable, returning empty sets or `None`
34//! as appropriate rather than failing.
35//!
36//! # Examples
37//!
38//! ## Parsing Dependency Specifications
39//!
40//! ```no_run
41//! use arch_toolkit::deps::parse_dep_spec;
42//!
43//! let spec = parse_dep_spec("python>=3.12");
44//! assert_eq!(spec.name, "python");
45//! assert_eq!(spec.version_req, ">=3.12");
46//! ```
47//!
48//! ## Parsing .SRCINFO Files
49//!
50//! ```no_run
51//! use arch_toolkit::deps::parse_srcinfo;
52//!
53//! let srcinfo_content = r#"
54//! pkgbase = my-package
55//! pkgname = my-package
56//! pkgver = 1.0.0
57//! pkgrel = 1
58//! depends = glibc
59//! depends = python>=3.10
60//! "#;
61//!
62//! let data = parse_srcinfo(srcinfo_content);
63//! assert_eq!(data.pkgname, "my-package");
64//! assert!(data.depends.contains(&"glibc".to_string()));
65//! ```
66//!
67//! ## Parsing PKGBUILD Files
68//!
69//! ```no_run
70//! use arch_toolkit::deps::parse_pkgbuild_deps;
71//!
72//! let pkgbuild = r#"
73//! depends=('glibc' 'python>=3.10')
74//! makedepends=('rust' 'cargo')
75//! "#;
76//!
77//! let (deps, makedeps, checkdeps, optdeps) = parse_pkgbuild_deps(pkgbuild);
78//! assert!(deps.contains(&"glibc".to_string()));
79//! ```
80//!
81//! ## Version Comparison
82//!
83//! ```no_run
84//! use arch_toolkit::deps::version_satisfies;
85//!
86//! assert!(version_satisfies("2.0", ">=1.5"));
87//! assert!(!version_satisfies("1.0", ">=1.5"));
88//! ```
89//!
90//! ## Querying Installed Packages
91//!
92//! ```no_run
93//! use arch_toolkit::deps::get_installed_packages;
94//!
95//! let installed = get_installed_packages().unwrap();
96//! println!("Found {} installed packages", installed.len());
97//! ```
98//!
99//! ## Dependency Resolution
100//!
101//! ```no_run
102//! use arch_toolkit::deps::DependencyResolver;
103//! use arch_toolkit::{PackageRef, PackageSource};
104//!
105//! let resolver = DependencyResolver::new();
106//! let packages = vec![
107//! PackageRef {
108//! name: "firefox".into(),
109//! version: "121.0".into(),
110//! source: PackageSource::Official {
111//! repo: "extra".into(),
112//! arch: "x86_64".into(),
113//! },
114//! },
115//! ];
116//!
117//! let result = resolver.resolve(&packages).unwrap();
118//! println!("Found {} dependencies", result.dependencies.len());
119//! ```
120//!
121//! ## Reverse Dependency Analysis
122//!
123//! ```no_run
124//! use arch_toolkit::deps::ReverseDependencyAnalyzer;
125//! use arch_toolkit::{PackageRef, PackageSource};
126//!
127//! let analyzer = ReverseDependencyAnalyzer::new();
128//! let packages = vec![
129//! PackageRef {
130//! name: "qt5-base".into(),
131//! version: "5.15.10".into(),
132//! source: PackageSource::Official {
133//! repo: "extra".into(),
134//! arch: "x86_64".into(),
135//! },
136//! },
137//! ];
138//!
139//! let report = analyzer.analyze(&packages).unwrap();
140//! println!("{} packages would be affected", report.dependents.len());
141//! ```
142//!
143//! ## Fetching .SRCINFO from AUR (requires `aur` feature)
144//!
145//! ```no_run
146//! # #[cfg(feature = "aur")]
147//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
148//! use arch_toolkit::deps::fetch_srcinfo;
149//! use reqwest::Client;
150//!
151//! let client = Client::new();
152//! let srcinfo = fetch_srcinfo(&client, "yay").await?;
153//! let data = arch_toolkit::deps::parse_srcinfo(&srcinfo);
154//! println!("Package: {}", data.pkgname);
155//! # Ok(())
156//! # }
157//! ```
158//!
159//! # Example Programs
160//!
161//! See the following example programs for more comprehensive usage:
162//!
163//! - [`examples/deps_types_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/deps_types_example.rs) - Comprehensive type usage examples
164//! - [`examples/parse_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/parse_example.rs) - Dependency parsing examples
165//! - [`examples/srcinfo_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/srcinfo_example.rs) - .SRCINFO parsing examples
166//! - [`examples/pkgbuild_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/pkgbuild_example.rs) - PKGBUILD parsing examples
167//! - [`examples/query_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/query_example.rs) - Package querying examples
168//! - [`examples/source_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/source_example.rs) - Source determination examples
169//! - [`examples/version_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/version_example.rs) - Version comparison examples
170//! - [`examples/resolve_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/resolve_example.rs) - Dependency resolution examples
171//! - [`examples/reverse_example.rs`](https://github.com/Firstp1ck/arch-toolkit/blob/main/examples/reverse_example.rs) - Reverse dependency analysis examples
172
173mod parse;
174mod pkgbuild;
175mod query;
176mod resolve;
177mod reverse;
178mod source;
179mod srcinfo;
180mod version;
181
182// Re-export parsing functions
183pub use parse::{parse_dep_spec, parse_pacman_si_conflicts, parse_pacman_si_deps};
184pub use pkgbuild::{parse_pkgbuild_conflicts, parse_pkgbuild_deps};
185pub use query::{
186 get_available_version, get_installed_packages, get_installed_version, get_provided_packages,
187 get_upgradable_packages, is_package_installed_or_provided,
188};
189pub use resolve::{
190 DependencyResolver, batch_fetch_official_deps, determine_status, fetch_package_conflicts,
191};
192pub use reverse::{
193 ReverseDependencyAnalyzer, get_installed_required_by, has_installed_required_by,
194};
195pub use source::{determine_dependency_source, is_system_package};
196pub use srcinfo::{parse_srcinfo, parse_srcinfo_conflicts, parse_srcinfo_deps};
197pub use version::{
198 compare_versions, extract_major_component, is_major_version_bump, version_satisfies,
199};
200
201// AUR integration (requires aur feature)
202#[cfg(feature = "aur")]
203pub use srcinfo::fetch_srcinfo;
204
205// Re-export types from types module
206pub use crate::types::dependency::{
207 DependencyResolution, ResolverConfig, ReverseDependencyReport, ReverseDependencySummary,
208};