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