diff --git a/install3/misc.c b/install3/misc.c index e3d238e..ded4de0 100644 --- a/install3/misc.c +++ b/install3/misc.c @@ -16,11 +16,15 @@ #include "ictx.h" -int i3_is_pkg_installed(struct poldek_ts *ts, struct pkg *pkg, int *cmprc) +int i3_is_pkg_installed(struct poldek_ts *ts, struct pkg *pkg, int *cmprc) { tn_array *dbpkgs = NULL; - int n; - + int n = 0, freshen = 0; + freshen = ts->getop(ts, POLDEK_OP_FRESHEN) + || poldek_ts_issetf(ts, POLDEK_TS_UPGRADE) + || poldek_ts_issetf(ts, POLDEK_TS_DOWNGRADE) + || poldek_ts_issetf(ts, POLDEK_TS_UPGRADEDIST); + n = pkgdb_search(ts->db, &dbpkgs, PMTAG_NAME, pkg->name, NULL, PKG_LDNEVR); n_assert(n >= 0); @@ -30,17 +34,25 @@ int i3_is_pkg_installed(struct poldek_ts *ts, struct pkg *pkg, int *cmprc) } if (poldek_conf_MULTILIB) { /* filter out different architectures */ - int i; tn_array *arr = n_array_clone(dbpkgs); //DBGF("pkg = %s\n", pkg_id(pkg)); //pkgs_array_dump(dbpkgs, "before_multilib"); - for (i=0; i < n_array_size(dbpkgs); i++) { + for (unsigned int i=0; i < n_array_size(dbpkgs); i++) { struct pkg *dbpkg = n_array_nth(dbpkgs, i); - if (pkg_is_kind_of(dbpkg, pkg)) - n_array_push(arr, pkg_link(dbpkg)); + + msgn(4, "from pkg %s.%s => to pkg %s-%s-%s.%s freshen:%d kind:%d up_arch:%d", + pkg_snprintf_s(dbpkg), pkg_arch(dbpkg), pkg->name, pkg->ver, pkg->rel, pkg_arch(pkg), + freshen, pkg_is_kind_of(dbpkg, pkg), pkg_is_arch_compat(dbpkg, pkg)); + + // if freshen (upgrade) preffer same arch but + // change from/to noarch depends on which pkg is noarch + // add package if pkg_is_kind_of (have same name and color) + if (pkg_is_kind_of(dbpkg, pkg) + && !(freshen && !pkg_is_arch_compat(dbpkg, pkg))) + n_array_push(arr, pkg_link(dbpkg)); } - + n_array_cfree(&dbpkgs); dbpkgs = arr; n = n_array_size(arr); diff --git a/libpoldek.sym b/libpoldek.sym index 6c2a356..26e05d5 100644 --- a/libpoldek.sym +++ b/libpoldek.sym @@ -71,6 +71,7 @@ pkg_id_snprintf pkg_idevr_snprintf pkg_is_colored_like pkg_is_kind_of +pkg_is_arch_compat pkg_link pkg_localpath pkg_match_req diff --git a/pkg.h b/pkg.h index 8a1d0b2..77acf0a 100644 --- a/pkg.h +++ b/pkg.h @@ -43,6 +43,8 @@ struct pkgdir; /* defined in pkgdir/pkgdir.h */ ((pkg)->flags & color) #endif /* POLDEK_PKG_DAG_COLOURS */ +#define pkg_is_noarch(pkg) (0 == strcmp(pkg_arch((pkg)), "noarch")) + #define pkg_set_prereqed(pkg) ((pkg)->flags |= PKG_ORDER_PREREQ) #define pkg_clr_prereqed(pkg) ((pkg)->flags &= ~PKG_ORDER_PREREQ) #define pkg_is_prereqed(pkg) ((pkg)->flags & PKG_ORDER_PREREQ) diff --git a/pkgcmp.c b/pkgcmp.c index f123e03..7bf34d4 100644 --- a/pkgcmp.c +++ b/pkgcmp.c @@ -88,7 +88,19 @@ int pkg_is_colored_like(const struct pkg *candidate, const struct pkg *pkg) return 1; } -int pkg_eq_capreq(const struct pkg *pkg, const struct capreq *cr) +/* ret : 1 if pkg is cappable to upgrade arch<=>arch, arch<=>noarch */ +int pkg_is_arch_compat(const struct pkg *candidate, const struct pkg *pkg) +{ + // if upgrade preffer same arch but + // change from/to noarch depends on which pkg is noarch + + int cmp_arch = pkg_cmp_arch(candidate, pkg); + return ( cmp_arch == 0 + || (cmp_arch > 0 && pkg_is_noarch(candidate)) + || (cmp_arch < 0 && pkg_is_noarch(pkg))); +} + +int pkg_eq_capreq(const struct pkg *pkg, const struct capreq *cr) { return strcmp(pkg->name, capreq_name(cr)) == 0 && strcmp(pkg->ver, capreq_ver(cr)) == 0 && diff --git a/pkgcmp.h b/pkgcmp.h index 6b1b75a..980f675 100644 --- a/pkgcmp.h +++ b/pkgcmp.h @@ -17,6 +17,9 @@ int pkg_is_colored_like(const struct pkg *candidate, const struct pkg *pkg); /* same name && arch */ int pkg_is_kind_of(const struct pkg *candidate, const struct pkg *pkg); +/* ret : 0 if pkg is cappable to upgrade arch<=>arch, arch<=>noarch */ +int pkg_is_arch_compat(const struct pkg *candidate, const struct pkg *pkg); + /* strncmp(p1->name, p2->name, strlen(p2->name)) */ extern__inline int pkg_ncmp_name(const struct pkg *p1, const struct pkg *p2); @@ -27,7 +30,7 @@ int pkg_cmp_name(const struct pkg *p1, const struct pkg *p2); extern__inline int pkg_cmp_id(const struct pkg *p1, const struct pkg *p2); -/* versions only */ +/* versions only (+epoch) */ int pkg_cmp_ver(const struct pkg *p1, const struct pkg *p2); /* EVR only */ int pkg_cmp_evr(const struct pkg *p1, const struct pkg *p2); diff --git a/upgrade-dist.c b/upgrade-dist.c index 458b764..00f34fc 100644 --- a/upgrade-dist.c +++ b/upgrade-dist.c @@ -64,8 +64,18 @@ int process_pkg(const struct pkg *dbpkg, struct poldek_ts *ts, if (!ts->getop(ts, POLDEK_OP_MULTILIB)) break; - - if (pkg_is_kind_of(pkg, dbpkg)) + + if (0 != strcmp(dbpkg->name, pkg->name)) + { + pkg = NULL; + break; + } + + msgn(4, "UPGRADE-DIST from pkg %s.%s => to pkg %s-%s-%s.%s kind:%d up_arch:%d", + pkg_snprintf_s(dbpkg), pkg_arch(dbpkg), pkg->name, pkg->ver, pkg->rel, pkg_arch(pkg), + pkg_is_kind_of(dbpkg, pkg), pkg_is_arch_compat(dbpkg, pkg)); + + if (pkg_cmp_evr(pkg, dbpkg) > 0 && pkg_is_kind_of(pkg, dbpkg) && pkg_is_arch_compat(pkg, dbpkg)) break; i++;