[pacman-dev] [PATCH v2 2/2] Add --ignore-depends option
Andrew Gregory
andrew.gregory.8 at gmail.com
Mon Sep 8 12:07:53 EDT 2014
On 08/06/14 at 09:55pm, Florian Pritz wrote:
> This allows to ignore specific dependencies.
>
> TODO: documentation
>
> Signed-off-by: Florian Pritz <bluewind at xinu.at>
> ---
> lib/libalpm/alpm.h | 11 ++++++++
> lib/libalpm/deps.c | 8 ++++--
> lib/libalpm/handle.c | 62 ++++++++++++++++++++++++++++++++++++++++++
> lib/libalpm/handle.h | 1 +
> src/pacman/conf.c | 2 ++
> src/pacman/conf.h | 4 ++-
> src/pacman/pacman.c | 4 +++
> test/pacman/tests/TESTS | 1 +
> test/pacman/tests/ignoredep.py | 20 ++++++++++++++
> 9 files changed, 110 insertions(+), 3 deletions(-)
> create mode 100644 test/pacman/tests/ignoredep.py
>
> diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
> index db1e0cd..d5b2c4c 100644
> --- a/lib/libalpm/alpm.h
> +++ b/lib/libalpm/alpm.h
> @@ -857,6 +857,17 @@ int alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
> int alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp);
> /** @} */
>
> +/** @name Accessors to the list of ignored dependencies.
> + * These functions modify the list of dependencies that
> + * should be ignored by a sysupgrade.
> + * @{
> + */
> +alpm_list_t *alpm_option_get_ignoredeps(alpm_handle_t *handle);
> +int alpm_option_add_ignoredep(alpm_handle_t *handle, const char *dep);
> +int alpm_option_set_ignoredeps(alpm_handle_t *handle, alpm_list_t *ignoredeps);
> +int alpm_option_remove_ignoredep(alpm_handle_t *handle, const char *dep);
> +/** @} */
> +
> /** Returns the targeted architecture. */
> const char *alpm_option_get_arch(alpm_handle_t *handle);
> /** Sets the targeted architecture. */
> diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
> index 5c76da7..44f9ebc 100644
> --- a/lib/libalpm/deps.c
> +++ b/lib/libalpm/deps.c
> @@ -338,8 +338,10 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
> }
> /* 1. we check the upgrade list */
> /* 2. we check database for untouched satisfying packages */
> + /* 3. we check the dependency ignore list */
> if(!find_dep_satisfier(upgrade, depend) &&
> - !find_dep_satisfier(dblist, depend)) {
> + !find_dep_satisfier(dblist, depend) &&
> + !_alpm_depcmp_provides(depend, handle->ignoredep)) {
> /* Unsatisfied dependency in the upgrade list */
> alpm_depmissing_t *miss;
> char *missdepstring = alpm_dep_compute_string(depend);
> @@ -368,9 +370,11 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
> /* we won't break this depend, if it is already broken, we ignore it */
> /* 1. check upgrade list for satisfiers */
> /* 2. check dblist for satisfiers */
> + /* 3. we check the dependency ignore list */
> if(causingpkg &&
> !find_dep_satisfier(upgrade, depend) &&
> - !find_dep_satisfier(dblist, depend)) {
> + !find_dep_satisfier(dblist, depend) &&
> + !_alpm_depcmp_provides(depend, handle->ignoredep)) {
> alpm_depmissing_t *miss;
> char *missdepstring = alpm_dep_compute_string(depend);
> _alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
> diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
> index 0842d51..e90a6b7 100644
> --- a/lib/libalpm/handle.c
> +++ b/lib/libalpm/handle.c
> @@ -37,6 +37,7 @@
> #include "delta.h"
> #include "trans.h"
> #include "alpm.h"
> +#include "deps.h"
>
> alpm_handle_t *_alpm_handle_new(void)
> {
> @@ -86,6 +87,7 @@ void _alpm_handle_free(alpm_handle_t *handle)
> FREELIST(handle->noextract);
> FREELIST(handle->ignorepkg);
> FREELIST(handle->ignoregroup);
> + FREELIST(handle->ignoredep);
You need to use alpm_list_free_inner with _alpm_dep_free and
alpm_list_free, not FREELIST.
> FREE(handle);
> }
>
> @@ -234,6 +236,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
> return handle->ignoregroup;
> }
>
> +alpm_list_t SYMEXPORT *alpm_option_get_ignoredeps(alpm_handle_t *handle)
> +{
> + CHECK_HANDLE(handle, return NULL);
> + return handle->ignoredep;
> +}
> +
Using strings with add/set/remove but returning depend_t from
get_ignoredepends is confusing. Can we make them consistent?
> const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
> {
> CHECK_HANDLE(handle, return NULL);
> @@ -552,6 +560,60 @@ int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *
> return 0;
> }
>
> +int SYMEXPORT alpm_option_add_ignoredep(alpm_handle_t *handle, const char *dep)
> +{
> + CHECK_HANDLE(handle, return -1);
> +
> + alpm_depend_t *provider = _alpm_splitdep(dep);
> + if (!provider) {
> + _alpm_log(handle, ALPM_LOG_WARNING, "Invalid format for dependency ignore entry. Skipping '%s'\n", dep);
> + return 1;
> + }
> +
> + handle->ignoredep = alpm_list_add(handle->ignoredep, provider);
> + return 0;
> +}
> +
> +int SYMEXPORT alpm_option_set_ignoredeps(alpm_handle_t *handle, alpm_list_t *ignoredeps)
> +{
> + CHECK_HANDLE(handle, return -1);
> + if(handle->ignoredep) {
> + alpm_list_free(handle->ignoredep);
> + }
> + for (alpm_list_t *i = ignoredeps; i; i = i->next) {
> + alpm_option_add_ignoredep(handle, i->data);
This should check for failure and abort like set_cachedirs.
> + }
> + return 0;
> +}
> +
> +static int ignoredep_cmp(const void *data, const void *dep)
> +{
> + alpm_depend_t *dep1 = ((alpm_list_t*)data)->data;
> + alpm_depend_t *dep2 = _alpm_splitdep(dep);
Do the splitdep in remove_ignoredep so it only has to be done once.
The resulting depend_t also needs to be free'd.
> +
> + if (!dep2) {
> + return -1;
> + }
> +
> + if (strcmp(dep1->name, dep2->name) && strcmp(dep1->version, dep2->version)) {
> + return 0;
> + }
> +
> + return -1;
> +}
> +
> +int SYMEXPORT alpm_option_remove_ignoredep(alpm_handle_t *handle, const char *dep)
> +{
> + alpm_pkg_t *vdata = NULL;
> + CHECK_HANDLE(handle, return -1);
> + handle->ignoredep = alpm_list_remove(handle->ignoredep, dep, &ignoredep_cmp, (void **)&vdata);
> + if(vdata != NULL) {
> + alpm_pkg_free(vdata);
vdata needs to be a depend_t, not a package.
> + return 1;
> + }
> + return 0;
> +}
> +
> int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
> {
> CHECK_HANDLE(handle, return -1);
> diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
> index 85c64f6..f164e1c 100644
> --- a/lib/libalpm/handle.h
> +++ b/lib/libalpm/handle.h
> @@ -83,6 +83,7 @@ struct __alpm_handle_t {
> alpm_list_t *noextract; /* List of files NOT to extract */
> alpm_list_t *ignorepkg; /* List of packages to ignore */
> alpm_list_t *ignoregroup; /* List of groups to ignore */
> + alpm_list_t *ignoredep; /* List of packages to ignore dependencies on */
>
> /* options */
> char *arch; /* Architecture of packages we should allow */
> diff --git a/src/pacman/conf.c b/src/pacman/conf.c
> index 0e483f7..0d7a605 100644
> --- a/src/pacman/conf.c
> +++ b/src/pacman/conf.c
> @@ -134,6 +134,7 @@ int config_free(config_t *oldconfig)
> FREELIST(oldconfig->holdpkg);
> FREELIST(oldconfig->ignorepkg);
> FREELIST(oldconfig->ignoregrp);
> + FREELIST(oldconfig->ignoredep);
> FREELIST(oldconfig->noupgrade);
> FREELIST(oldconfig->noextract);
> free(oldconfig->configfile);
> @@ -738,6 +739,7 @@ static int setup_libalpm(void)
>
> alpm_option_set_ignorepkgs(handle, config->ignorepkg);
> alpm_option_set_ignoregroups(handle, config->ignoregrp);
> + alpm_option_set_ignoredeps(handle, config->ignoredep);
> alpm_option_set_noupgrades(handle, config->noupgrade);
> alpm_option_set_noextracts(handle, config->noextract);
>
> diff --git a/src/pacman/conf.h b/src/pacman/conf.h
> index e8cac50..0e5c86f 100644
> --- a/src/pacman/conf.h
> +++ b/src/pacman/conf.h
> @@ -101,6 +101,7 @@ typedef struct __config_t {
> alpm_list_t *holdpkg;
> alpm_list_t *ignorepkg;
> alpm_list_t *ignoregrp;
> + alpm_list_t *ignoredep;
> alpm_list_t *noupgrade;
> alpm_list_t *noextract;
> char *xfercommand;
> @@ -176,7 +177,8 @@ enum {
> OP_UNNEEDED,
> OP_VERBOSE,
> OP_DOWNLOADONLY,
> - OP_REFRESH
> + OP_REFRESH,
> + OP_IGNOREDEP
> };
>
> /* clean method */
> diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> index 12a4f7a..95dbe6f 100644
> --- a/src/pacman/pacman.c
> +++ b/src/pacman/pacman.c
> @@ -707,6 +707,9 @@ static int parsearg_upgrade(int opt)
> case OP_IGNOREGROUP:
> parsearg_util_addlist(&(config->ignoregrp));
> break;
> + case OP_IGNOREDEP:
> + parsearg_util_addlist(&(config->ignoredep));
> + break;
Why is this limited to -S and -U? -dd applies to all transactions.
> default: return 1;
> }
> return 0;
> @@ -855,6 +858,7 @@ static int parseargs(int argc, char *argv[])
> {"noconfirm", no_argument, 0, OP_NOCONFIRM},
> {"config", required_argument, 0, OP_CONFIG},
> {"ignore", required_argument, 0, OP_IGNORE},
> + {"ignore-depends", required_argument, 0, OP_IGNOREDEP},
> {"debug", optional_argument, 0, OP_DEBUG},
> {"force", no_argument, 0, OP_FORCE},
> {"noprogressbar", no_argument, 0, OP_NOPROGRESSBAR},
> diff --git a/test/pacman/tests/TESTS b/test/pacman/tests/TESTS
> index 1b5a81f..59b46ce 100644
> --- a/test/pacman/tests/TESTS
> +++ b/test/pacman/tests/TESTS
> @@ -57,6 +57,7 @@ TESTS += test/pacman/tests/ignore005.py
> TESTS += test/pacman/tests/ignore006.py
> TESTS += test/pacman/tests/ignore007.py
> TESTS += test/pacman/tests/ignore008.py
> +TESTS += test/pacman/tests/ignoredep.py
> TESTS += test/pacman/tests/ldconfig001.py
> TESTS += test/pacman/tests/ldconfig002.py
> TESTS += test/pacman/tests/ldconfig003.py
> diff --git a/test/pacman/tests/ignoredep.py b/test/pacman/tests/ignoredep.py
> new file mode 100644
> index 0000000..d66ec09
> --- /dev/null
> +++ b/test/pacman/tests/ignoredep.py
> @@ -0,0 +1,20 @@
> +self.description = "Update a package using --ignore-depends"
> +
> +lp1 = pmpkg("pkg1", "1.0-1")
> +
> +lp2 = pmpkg("pkg2", "1.0-1")
> +lp2.depends = ["pkg1=1.0"]
> +
> +sp1 = pmpkg("pkg1", "2.0-1")
> +
> +for p in lp1, lp2:
> + self.addpkg2db("local", p);
> +
> +self.addpkg2db("sync", sp1);
> +
> +self.args = "-Su --ignore-depends pkg1=1.0"
> +
> +self.addrule("PACMAN_RETCODE=0")
> +self.addrule("PKG_VERSION=pkg1|2.0-1")
> +self.addrule("PKG_EXIST=pkg2")
> +self.addrule("PKG_EXIST=pkg1")
> --
> 2.0.4
More information about the pacman-dev
mailing list