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 for install?
152 pub fn marked_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
153
154 /// Is the Package marked for upgrade?
155 pub fn marked_upgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
156
157 /// Is the Package marked to be purged?
158 pub fn marked_purge(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
159
160 /// Is the Package marked for removal?
161 pub fn marked_delete(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
162
163 /// Is the Package marked for keep?
164 pub fn marked_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
165
166 /// Is the Package marked for downgrade?
167 pub fn marked_downgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
168
169 /// Is the Package marked for reinstall?
170 pub fn marked_reinstall(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
171
172 /// # Mark a package as automatically installed.
173 ///
174 /// ## mark_auto:
175 /// * [true] = Mark the package as automatically installed.
176 /// * [false] = Mark the package as manually installed.
177 pub fn mark_auto(self: &PkgDepCache, pkg: &PkgIterator, mark_auto: bool);
178
179 /// # Mark a package for keep.
180 ///
181 /// ## Returns:
182 /// * [true] if the mark was successful
183 /// * [false] if the mark was unsuccessful
184 ///
185 /// This means that the package will not be changed from its current
186 /// version. This will not stop a reinstall, but will stop removal,
187 /// upgrades and downgrades
188 ///
189 /// We don't believe that there is any reason to unmark packages for
190 /// keep. If someone has a reason, and would like it implemented, please
191 /// put in a feature request.
192 pub fn mark_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
193
194 /// # Mark a package for removal.
195 ///
196 /// ## Returns:
197 /// * [true] if the mark was successful
198 /// * [false] if the mark was unsuccessful
199 ///
200 /// ## purge:
201 /// * [true] = Configuration files will be removed along with the
202 /// package.
203 /// * [false] = Only the package will be removed.
204 pub fn mark_delete(self: &PkgDepCache, pkg: &PkgIterator, purge: bool) -> bool;
205
206 /// # Mark a package for installation.
207 ///
208 /// ## auto_inst:
209 /// * [true] = Additionally mark the dependencies for this package.
210 /// * [false] = Mark only this package.
211 ///
212 /// ## from_user:
213 /// * [true] = The package will be marked manually installed.
214 /// * [false] = The package will be unmarked automatically installed.
215 ///
216 /// ## Returns:
217 /// * [true] if the mark was successful
218 /// * [false] if the mark was unsuccessful
219 ///
220 /// If a package is already installed, at the latest version,
221 /// and you mark that package for install you will get true,
222 /// but the package will not be altered.
223 /// `pkg.marked_install()` will be false
224 pub fn mark_install(
225 self: &PkgDepCache,
226 pkg: &PkgIterator,
227 auto_inst: bool,
228 from_user: bool,
229 ) -> bool;
230
231 /// Set a version to be the candidate of it's package.
232 pub fn set_candidate_version(self: &PkgDepCache, ver: &VerIterator);
233
234 /// Get a pointer to the version that is set to be installed.
235 ///
236 /// # Safety
237 ///
238 /// If there is no candidate the inner pointer will be null.
239 /// This will cause segfaults if methods are used on a Null Version.
240 ///
241 /// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
242 /// is recommended.
243 ///
244 /// The returned UniquePtr cannot outlive the cache.
245 unsafe fn candidate_version(
246 self: &PkgDepCache,
247 pkg: &PkgIterator,
248 ) -> UniquePtr<VerIterator>;
249
250 /// Get a pointer to the version that is installed.
251 ///
252 /// # Safety
253 ///
254 /// If there is no version the inner pointer will be null.
255 /// This will cause segfaults if methods are used on a Null Version.
256 ///
257 /// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
258 /// is recommended.
259 ///
260 /// The returned UniquePtr cannot outlive the cache.
261 unsafe fn install_version(self: &PkgDepCache, pkg: &PkgIterator) -> UniquePtr<VerIterator>;
262
263 /// Returns the state of the dependency as u8
264 pub fn dep_state(self: &PkgDepCache, dep: &DepIterator) -> u8;
265
266 /// Checks if the dependency is important.
267 ///
268 /// Depends, PreDepends, Conflicts, Obsoletes, Breaks
269 /// will return [true].
270 ///
271 /// Suggests, Recommends will return [true] if they are
272 /// configured to be installed.
273 pub fn is_important_dep(self: &PkgDepCache, dep: &DepIterator) -> bool;
274
275 /// # Mark a package for reinstallation.
276 ///
277 /// ## Returns:
278 /// * [true] if the mark was successful
279 /// * [false] if the mark was unsuccessful
280 ///
281 /// ## reinstall:
282 /// * [true] = The package will be marked for reinstall.
283 /// * [false] = The package will be unmarked for reinstall.
284 pub fn mark_reinstall(self: &PkgDepCache, pkg: &PkgIterator, reinstall: bool);
285
286 /// Is the installed Package broken?
287 pub fn is_now_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
288
289 /// Is the Package to be installed broken?
290 pub fn is_inst_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
291
292 /// The number of packages marked for installation.
293 pub fn install_count(self: &PkgDepCache) -> u32;
294
295 /// The number of packages marked for removal.
296 pub fn delete_count(self: &PkgDepCache) -> u32;
297
298 /// The number of packages marked for keep.
299 pub fn keep_count(self: &PkgDepCache) -> u32;
300
301 /// The number of packages with broken dependencies in the cache.
302 pub fn broken_count(self: &PkgDepCache) -> u32;
303
304 /// The size of all packages to be downloaded.
305 pub fn download_size(self: &PkgDepCache) -> u64;
306
307 /// The amount of space required for installing/removing the packages,"
308 ///
309 /// i.e. the Installed-Size of all packages marked for installation"
310 /// minus the Installed-Size of all packages for removal."
311 pub fn disk_size(self: &PkgDepCache) -> i64;
312 }
313}