Skip to main content

rust_apt/
depcache.rs

1//! Dependency Extension data for the cache.
2//!
3//! The following was taken from libapt-pkg documentation.
4//!
5//! This class stores the cache data and a set of extension structures for
6//! monitoring the current state of all the packages. It also generates and
7//! caches the 'install' state of many things. This refers to the state of the
8//! package after an install has been run.
9//!
10//! The StateCache::State field can be -1,0,1,2 which is <,=,>,no current.
11//! StateCache::Mode is which of the 3 fields is active.
12//!
13//! This structure is important to support the readonly status of the cache
14//! file. When the data is saved the cache will be refreshed from our
15//! internal rep and written to disk. Then the actual persistent data
16//! files will be put on the disk.
17//!
18//! Each dependency is compared against 3 target versions to produce to
19//! 3 dependency results.
20//!   Now - Compared using the Currently install version
21//!   Install - Compared using the install version (final state)
22//!   CVer - (Candidate Version) Compared using the Candidate Version
23//! The candidate and now results are used to decide whether a package
24//! should be automatically installed or if it should be left alone.
25//!
26//! Remember, the Candidate Version is selected based on the distribution
27//! settings for the Package. The Install Version is selected based on the
28//! state (Delete, Keep, Install) field and can be either the Current Version
29//! or the Candidate version.
30//!
31//! The Candidate version is what is shown the 'Install Version' field.
32
33use cxx::UniquePtr;
34
35use crate::Package;
36use crate::error::AptErrors;
37use crate::progress::OperationProgress;
38use crate::raw::PkgDepCache;
39use crate::util::DiskSpace;
40
41/// Dependency Extension data for the cache.
42pub struct DepCache {
43	pub(crate) ptr: UniquePtr<PkgDepCache>,
44}
45
46impl DepCache {
47	pub fn new(ptr: UniquePtr<PkgDepCache>) -> DepCache { DepCache { ptr } }
48
49	/// Clear any marked changes in the DepCache.
50	pub fn clear_marked(&self) -> Result<(), AptErrors> {
51		Ok(self.init(OperationProgress::quiet().pin().as_mut())?)
52	}
53
54	/// True if APT is currently ignoring the package's candidate due to phased
55	/// updates.
56	pub fn phasing_applied(&self, pkg: &Package<'_>) -> bool { self.ptr.phasing_applied(pkg) }
57
58	/// The amount of space required for installing/removing the packages."
59	///
60	/// i.e. the Installed-Size of all packages marked for installation"
61	/// minus the Installed-Size of all packages for removal."
62	pub fn disk_size(&self) -> DiskSpace {
63		let size = self.ptr.disk_size();
64		if size < 0 {
65			return DiskSpace::Free(-size as u64);
66		}
67		DiskSpace::Require(size as u64)
68	}
69}
70
71#[cxx::bridge]
72pub(crate) mod raw {
73	impl UniquePtr<PkgDepCache> {}
74	unsafe extern "C++" {
75		include!("rust-apt/apt-pkg-c/depcache.h");
76
77		type PkgDepCache;
78		/// An action group is a group of actions that are currently being
79		/// performed.
80		///
81		/// While an active group is active, certain routine
82		/// clean-up actions that would normally be performed after every
83		/// cache operation are delayed until the action group is
84		/// completed. This is necessary primarily to avoid inefficiencies
85		/// when modifying a large number of packages at once.
86		///
87		/// This struct represents an active action group. Creating an
88		/// instance will create an action group; destroying one will
89		/// destroy the corresponding action group.
90		///
91		/// The following operations are suppressed by this class:
92		///
93		///   - Keeping the Marked and Garbage flags up to date.
94		///
95		/// Here is an example of creating and releasing an ActionGroup.
96		///
97		/// ```
98		/// use rust_apt::new_cache;
99		///
100		/// let cache = new_cache!().unwrap();
101		/// let mut action_group = unsafe { cache.depcache().action_group() };
102		///
103		/// // The C++ deconstructor will be run when the action group leaves scope.
104		/// // You can also call it explicitly.
105		/// action_group.pin_mut().release();
106		/// ```
107		type ActionGroup;
108		type PkgIterator = crate::iterators::PkgIterator;
109		type VerIterator = crate::iterators::VerIterator;
110		type DepIterator = crate::iterators::DepIterator;
111		type OperationProgress<'a> = crate::progress::OperationProgress<'a>;
112
113		/// Clear any marked changes in the DepCache.
114		pub fn init(self: &PkgDepCache, callback: Pin<&mut OperationProgress>) -> Result<()>;
115
116		/// Autoinstall every broken package and run the problem resolver
117		/// Returns false if the problem resolver fails.
118		pub fn fix_broken(self: &PkgDepCache) -> bool;
119		/// Return a new [`ActionGroup`] of the current DepCache
120		///
121		/// ActionGroup will be released once it leaves scope
122		/// or ['ActionGroup::release'] is called
123		///
124		/// # Safety
125		///
126		/// The returned UniquePtr cannot outlive the cache.
127		unsafe fn action_group(self: &PkgDepCache) -> UniquePtr<ActionGroup>;
128
129		/// This will release the [`ActionGroup`] which will trigger a
130		/// MarkAndSweep
131		pub fn release(self: Pin<&mut ActionGroup>);
132
133		/// Perform an Upgrade.
134		///
135		/// ## mark_auto:
136		///   * [0] = Remove and install new packages if necessary.
137		///   * [1] = New packages will be installed but nothing will be
138		///     removed.
139		///   * [3] = Neither remove or install new packages.
140		pub fn upgrade(
141			self: &PkgDepCache,
142			progress: Pin<&mut OperationProgress>,
143			upgrade_mode: i32,
144		) -> Result<()>;
145
146		/// Check if the package is upgradable.
147		pub fn is_upgradable(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
148
149		/// True if APT is currently ignoring the package's candidate due to
150		/// phased updates.
151		pub fn phasing_applied(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
152
153		/// Is the Package auto installed? Packages marked as auto installed are
154		/// usually dependencies.
155		pub fn is_auto_installed(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
156
157		/// Is the Package able to be auto removed?
158		pub fn is_garbage(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
159
160		/// Is the Package marked NewInstall.
161		pub fn marked_new_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
162
163		/// Is the Package marked for install?
164		pub fn marked_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
165
166		/// Is the Package marked for upgrade?
167		pub fn marked_upgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
168
169		/// Is the Package marked to be purged?
170		pub fn marked_purge(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
171
172		/// Is the Package marked for removal?
173		pub fn marked_delete(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
174
175		/// Is the Package held?
176		pub fn marked_held(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
177
178		/// Is the Package marked for keep?
179		pub fn marked_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
180
181		/// Is the Package marked for downgrade?
182		pub fn marked_downgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
183
184		/// Is the Package marked for reinstall?
185		pub fn marked_reinstall(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
186
187		/// # Mark a package as automatically installed.
188		///
189		/// ## mark_auto:
190		///   * [true] = Mark the package as automatically installed.
191		///   * [false] = Mark the package as manually installed.
192		pub fn mark_auto(self: &PkgDepCache, pkg: &PkgIterator, mark_auto: bool);
193
194		/// # Mark a package for keep.
195		///
196		/// ## Returns:
197		///   * [true] if the mark was successful
198		///   * [false] if the mark was unsuccessful
199		///
200		/// This means that the package will not be changed from its current
201		/// version. This will not stop a reinstall, but will stop removal,
202		/// upgrades and downgrades
203		///
204		/// We don't believe that there is any reason to unmark packages for
205		/// keep. If someone has a reason, and would like it implemented, please
206		/// put in a feature request.
207		pub fn mark_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
208
209		/// # Mark a package for removal.
210		///
211		/// ## Returns:
212		///   * [true] if the mark was successful
213		///   * [false] if the mark was unsuccessful
214		///
215		/// ## purge:
216		///   * [true] = Configuration files will be removed along with the
217		///     package.
218		///   * [false] = Only the package will be removed.
219		pub fn mark_delete(self: &PkgDepCache, pkg: &PkgIterator, purge: bool) -> bool;
220
221		/// # Mark a package for installation.
222		///
223		/// ## auto_inst:
224		///   * [true] = Additionally mark the dependencies for this package.
225		///   * [false] = Mark only this package.
226		///
227		/// ## from_user:
228		///   * [true] = The package will be marked manually installed.
229		///   * [false] = The package will be unmarked automatically installed.
230		///
231		/// ## Returns:
232		///   * [true] if the mark was successful
233		///   * [false] if the mark was unsuccessful
234		///
235		/// If a package is already installed, at the latest version,
236		/// and you mark that package for install you will get true,
237		/// but the package will not be altered.
238		/// `pkg.marked_install()` will be false
239		pub fn mark_install(
240			self: &PkgDepCache,
241			pkg: &PkgIterator,
242			auto_inst: bool,
243			from_user: bool,
244		) -> bool;
245
246		/// Set a version to be the candidate of it's package.
247		pub fn set_candidate_version(self: &PkgDepCache, ver: &VerIterator);
248
249		/// Get a pointer to the version that is set to be installed.
250		///
251		/// # Safety
252		///
253		/// If there is no candidate the inner pointer will be null.
254		/// This will cause segfaults if methods are used on a Null Version.
255		///
256		/// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
257		/// is recommended.
258		///
259		/// The returned UniquePtr cannot outlive the cache.
260		unsafe fn candidate_version(
261			self: &PkgDepCache,
262			pkg: &PkgIterator,
263		) -> UniquePtr<VerIterator>;
264
265		/// Get a pointer to the version that is installed.
266		///
267		/// # Safety
268		///
269		/// If there is no version the inner pointer will be null.
270		/// This will cause segfaults if methods are used on a Null Version.
271		///
272		/// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
273		/// is recommended.
274		///
275		/// The returned UniquePtr cannot outlive the cache.
276		unsafe fn install_version(self: &PkgDepCache, pkg: &PkgIterator) -> UniquePtr<VerIterator>;
277
278		/// Returns the state of the dependency as u8
279		pub fn dep_state(self: &PkgDepCache, dep: &DepIterator) -> u8;
280
281		/// Checks if the dependency is important.
282		///
283		/// Depends, PreDepends, Conflicts, Obsoletes, Breaks
284		/// will return [true].
285		///
286		/// Suggests, Recommends will return [true] if they are
287		/// configured to be installed.
288		pub fn is_important_dep(self: &PkgDepCache, dep: &DepIterator) -> bool;
289
290		/// # Mark a package for reinstallation.
291		///
292		/// ## Returns:
293		///   * [true] if the mark was successful
294		///   * [false] if the mark was unsuccessful
295		///
296		/// ## reinstall:
297		///   * [true] = The package will be marked for reinstall.
298		///   * [false] = The package will be unmarked for reinstall.
299		pub fn mark_reinstall(self: &PkgDepCache, pkg: &PkgIterator, reinstall: bool);
300
301		/// Is the installed Package broken?
302		pub fn is_now_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
303
304		/// Is the Package to be installed broken?
305		pub fn is_inst_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
306
307		/// The number of packages marked for installation.
308		pub fn install_count(self: &PkgDepCache) -> u32;
309
310		/// The number of packages marked for removal.
311		pub fn delete_count(self: &PkgDepCache) -> u32;
312
313		/// The number of packages marked for keep.
314		pub fn keep_count(self: &PkgDepCache) -> u32;
315
316		/// The number of packages with broken dependencies in the cache.
317		pub fn broken_count(self: &PkgDepCache) -> u32;
318
319		/// The size of all packages to be downloaded.
320		pub fn download_size(self: &PkgDepCache) -> u64;
321
322		/// The amount of space required for installing/removing the packages,"
323		///
324		/// i.e. the Installed-Size of all packages marked for installation"
325		/// minus the Installed-Size of all packages for removal."
326		pub fn disk_size(self: &PkgDepCache) -> i64;
327	}
328}