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}