Skip to content

Commit 171377f

Browse files
authored
fix: fix oma why wrong judge (#576)
* fix: fix `oma why` wrong judge * fix(why): deduplicate items * Improve `tree.rs` style
1 parent 6f5d722 commit 171377f

File tree

3 files changed

+88
-47
lines changed

3 files changed

+88
-47
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ oma-repo-verify = { path = "./oma-repo-verify", default-features = false }
6666
oma-mirror = { path = "./oma-mirror", optional = true }
6767
apt-auth-config = { path = "./apt-auth-config" }
6868
oma-tum = { path = "./oma-tum", optional = true }
69+
debversion = "0.4"
6970

7071
# i18n
7172
i18n-embed = { version = "0.16.0", features = ["fluent-system", "desktop-requester"]}

src/subcommand/tree.rs

Lines changed: 86 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
22
cmp::Ordering,
3+
collections::HashSet,
34
fmt::Display,
45
io::{Write, stdout},
56
path::PathBuf,
@@ -12,10 +13,10 @@ use dialoguer::console::style;
1213
use oma_pm::{
1314
apt::{AptConfig, OmaApt, OmaAptArgs},
1415
matches::{GetArchMethod, PackagesMatcher},
15-
oma_apt::{Package, Version},
16+
oma_apt::{BaseDep, Package, Version},
1617
pkginfo::OmaDepType,
1718
};
18-
use tracing::debug;
19+
use tracing::{debug, trace};
1920

2021
use crate::{
2122
CliExecuter, config::Config, error::OutputError, fl, table::oma_display_with_normal_output,
@@ -138,8 +139,14 @@ impl CliExecuter for Tree {
138139

139140
let matcher = PackagesMatcher::builder()
140141
.cache(&apt.cache)
141-
.native_arch(GetArchMethod::SpecifySysroot(&sysroot))
142-
.build();
142+
.native_arch(GetArchMethod::SpecifySysroot(&sysroot));
143+
144+
let matcher = if invert {
145+
let matcher = matcher.filter_candidate(false);
146+
matcher.build()
147+
} else {
148+
matcher.build()
149+
};
143150

144151
let (pkgs, no_result) =
145152
matcher.match_pkgs_and_versions(packages.iter().map(|x| x.as_str()))?;
@@ -164,6 +171,9 @@ impl CliExecuter for Tree {
164171
limit,
165172
)
166173
} else {
174+
if !p.version_raw.is_installed() {
175+
continue;
176+
}
167177
reverse_dep_tree(
168178
PkgWrapper {
169179
package: Package::new(&apt.cache, p.raw_pkg),
@@ -267,6 +277,7 @@ fn reverse_dep_tree<'a>(
267277
limit: u8,
268278
) -> TermTree<PkgWrapper<'a>> {
269279
let pkg_clone = pkg.package.clone();
280+
let pkg_installed = pkg_clone.installed().unwrap();
270281
let rdep = pkg_clone.rdepends();
271282

272283
let mut res = TermTree::new(pkg);
@@ -279,68 +290,54 @@ fn reverse_dep_tree<'a>(
279290
let t = t.into();
280291
match t {
281292
OmaDepType::Depends | OmaDepType::PreDepends | OmaDepType::Recommends => {
293+
let mut added = HashSet::new();
282294
for deps in deps_group {
283295
for dep in deps.iter() {
284-
let Some(pkg) = apt.cache.get(dep.name()) else {
285-
debug!(
296+
let Some(dep_pkg) = apt.cache.get(dep.name()) else {
297+
trace!(
286298
"dep {} does not exist on apt cache, will continue",
287299
dep.name()
288300
);
289301
continue;
290302
};
291303

292-
let Some(installed_version) = pkg.installed() else {
293-
debug!("pkg {} is not installed, will continue", pkg.name());
304+
let Some(dep_installed) = dep_pkg.installed() else {
305+
trace!("pkg {} is not installed, will continue", dep_pkg.name());
294306
continue;
295307
};
296308

297-
let require_ver = Version::new(unsafe { dep.parent_ver() }, &apt.cache);
298-
299-
let push = if let Some(t) = dep.comp_type() {
300-
let mut push = None;
301-
let t = match t {
302-
">" | ">>" => vec![Ordering::Greater],
303-
"<" | "<<" => vec![Ordering::Less],
304-
">=" => vec![Ordering::Greater, Ordering::Equal],
305-
"<=" => vec![Ordering::Less, Ordering::Equal],
306-
"=" | "==" => vec![Ordering::Equal],
307-
"!=" => {
308-
push = Some(require_ver != installed_version);
309-
vec![]
310-
}
311-
"" => {
312-
push = Some(true);
313-
vec![]
314-
}
315-
x => unreachable!("unsupported comp type {x}"),
316-
};
317-
318-
debug!("{} {:?} {}", dep.name(), t, require_ver);
319-
320-
let cmp = &installed_version.cmp(&require_ver);
321-
322-
debug!("{} {installed_version} {cmp:?} {require_ver}", pkg.name());
323-
324-
if push.is_none() && t.contains(cmp) {
325-
push = Some(true)
326-
}
327-
328-
debug!("push = {push:?}");
329-
330-
push.unwrap_or(false)
331-
} else {
332-
true
333-
};
309+
let key = format!("{dep_pkg}-{}", dep_installed.version());
310+
311+
if added.contains(&key) {
312+
continue;
313+
}
314+
315+
let pkg_rev_dep = dep_installed
316+
.depends_map()
317+
.values()
318+
.flatten()
319+
.flat_map(|x| x.iter())
320+
.find(|dep| dep.name() == pkg_clone.name());
321+
322+
if pkg_rev_dep
323+
.is_none_or(|pkg_rev_dep| !is_result(&pkg_installed, pkg_rev_dep))
324+
{
325+
continue;
326+
}
327+
328+
let push = is_result(&dep_installed, dep);
334329

335330
if !push {
336331
continue;
337332
}
338333

334+
added.insert(key);
335+
339336
res.push(reverse_dep_tree(
340337
PkgWrapper {
341-
package: pkg,
338+
package: dep_pkg,
342339
is_recommend: t == OmaDepType::Recommends,
343-
comp_and_version: Some(installed_version.version().to_string()),
340+
comp_and_version: Some(dep_installed.version().to_string()),
344341
},
345342
apt,
346343
depth + 1,
@@ -355,3 +352,45 @@ fn reverse_dep_tree<'a>(
355352

356353
res
357354
}
355+
356+
fn is_result<'a>(pkg_installed: &Version<'a>, dep: &BaseDep<'_>) -> bool {
357+
debug!("{dep:#?}");
358+
359+
let Some(required_ver) = dep.version() else {
360+
// 没有版本要求,说明要求总是符合
361+
return true;
362+
};
363+
364+
let Ok(required_ver) = required_ver.parse::<debversion::Version>() else {
365+
return false;
366+
};
367+
368+
let Ok(installed) = pkg_installed.version().parse::<debversion::Version>() else {
369+
return false;
370+
};
371+
372+
if let Some(t) = dep.comp_type() {
373+
let confirm = match t {
374+
">" | ">>" => |cmp| cmp == Ordering::Greater,
375+
"<" | "<<" => |cmp| cmp == Ordering::Less,
376+
">=" => |cmp| [Ordering::Greater, Ordering::Equal].contains(&cmp),
377+
"<=" => |cmp| [Ordering::Less, Ordering::Equal].contains(&cmp),
378+
"=" | "==" => |cmp| Ordering::Equal == cmp,
379+
"!=" => |cmp| Ordering::Equal != cmp,
380+
"" => |_cmp| true,
381+
x => unreachable!("unsupported comp type {x}"),
382+
};
383+
384+
debug!("{} {t} {required_ver}", dep.name());
385+
386+
let cmp = installed.cmp(&required_ver);
387+
388+
debug!("{} {pkg_installed} {cmp:?} {required_ver}", dep.name());
389+
390+
if !confirm(cmp) {
391+
return false;
392+
}
393+
}
394+
395+
true
396+
}

0 commit comments

Comments
 (0)