Add the ability to ignore packages
The previous idea was to use virtual packages in the users configuration to satisfy dependencies by mapping them to existing installed packages. Using virtual packages for it doesn't work as expected and trying to make it work would break other functionalities of virtual packages, like the version satisfaction checks for `provides` and the ability to replace virtual packages with real packages. The virtual package functionality should be used exclusively for virtual packages. This allows users to specify packages packages that should be ignored. Ignored packages in dependencies are always satisfied without installing the package, while updating or installing a package that depends on an ignored package. This does NOT ignore the shlib checks, ignoring a package that provides required shared libraries will abort the transaction as if there was no package that provides the required shared library.
This commit is contained in:
parent
9f52a7837f
commit
d1667fd931
@ -58,6 +58,8 @@ check_pkg_rundeps(struct xbps_handle *xhp, const char *pkgname, void *arg)
|
||||
array = xbps_dictionary_get(pkg_propsd, "run_depends");
|
||||
for (unsigned int i = 0; i < xbps_array_count(array); i++) {
|
||||
xbps_array_get_cstring_nocopy(array, i, &reqpkg);
|
||||
if (xbps_pkg_is_ignored(xhp, reqpkg))
|
||||
continue;
|
||||
if (xbps_pkg_is_installed(xhp, reqpkg) <= 0) {
|
||||
xbps_error_printf("%s: dependency not satisfied: %s\n",
|
||||
pkgname, reqpkg);
|
||||
|
@ -56,6 +56,10 @@ Sets the default cache directory to store downloaded binary packages from
|
||||
remote repositories, as well as its signatures.
|
||||
If path starts with '/' it's an absolute path, otherwise it will be relative to
|
||||
.Ar rootdir .
|
||||
.It Sy ignorepkg=pkgname
|
||||
Declares a ignored package.
|
||||
If a package depends on an ignored package the dependency is always satisfied,
|
||||
without installing the ignored package.
|
||||
.It Sy include=path/file.conf
|
||||
Imports settings from the specified configuration file.
|
||||
.Em NOTE
|
||||
|
@ -512,6 +512,7 @@ struct xbps_handle {
|
||||
* @private
|
||||
*/
|
||||
xbps_array_t preserved_files;
|
||||
xbps_array_t ignored_pkgs;
|
||||
/**
|
||||
* @var repositories
|
||||
*
|
||||
@ -1843,6 +1844,17 @@ bool xbps_verify_file_signature(struct xbps_repo *repo, const char *fname);
|
||||
*/
|
||||
int xbps_pkg_is_installed(struct xbps_handle *xhp, const char *pkg);
|
||||
|
||||
/**
|
||||
* Checks if a package is currently ignored by matching \a pkg.
|
||||
* To be ignored, the pkg must be ignored by the users configuration.
|
||||
*
|
||||
* @param[in] xhp The pointer to an xbps_handle struct.
|
||||
* @param[in] pkg Package name, version pattern or exact pkg to match.
|
||||
*
|
||||
* @return True if the package is ignored, false otherwise.
|
||||
*/
|
||||
bool xbps_pkg_is_ignored(struct xbps_handle *xhp, const char *pkg);
|
||||
|
||||
/**
|
||||
* Returns true if binary package exists in cachedir or in a local repository,
|
||||
* false otherwise.
|
||||
|
@ -141,6 +141,17 @@ store_repo(struct xbps_handle *xhp, const char *repo)
|
||||
return xbps_repo_store(xhp, repo);
|
||||
}
|
||||
|
||||
static void
|
||||
store_ignored_pkg(struct xbps_handle *xhp, const char *pkgname)
|
||||
{
|
||||
if (xhp->ignored_pkgs == NULL) {
|
||||
xhp->ignored_pkgs = xbps_array_create();
|
||||
assert(xhp->ignored_pkgs);
|
||||
}
|
||||
xbps_array_add_cstring(xhp->ignored_pkgs, pkgname);
|
||||
xbps_dbg_printf(xhp, "Added ignored package: %s\n", pkgname);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_option(char *buf, char **k, char **v)
|
||||
{
|
||||
@ -153,6 +164,7 @@ parse_option(char *buf, char **k, char **v)
|
||||
"repository",
|
||||
"virtualpkg",
|
||||
"include",
|
||||
"ignorepkg",
|
||||
"preserve",
|
||||
"bestmatching",
|
||||
"architecture"
|
||||
@ -264,6 +276,8 @@ parse_file(struct xbps_handle *xhp, const char *cwd, const char *path, bool nest
|
||||
xbps_dbg_printf(xhp, "%s: added repository %s\n", path, v);
|
||||
} else if (strcmp(k, "virtualpkg") == 0) {
|
||||
store_vars(xhp, &xhp->vpkgd, k, path, nlines, v);
|
||||
} else if (strcmp(k, "ignorepkg") == 0) {
|
||||
store_ignored_pkg(xhp, v);
|
||||
} else if (strcmp(k, "preserve") == 0) {
|
||||
store_preserved_file(xhp, v);
|
||||
} else if (strcmp(k, "bestmatching") == 0) {
|
||||
|
@ -161,6 +161,14 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
rv = ENXIO;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Pass 0: check if required dependency is ignored.
|
||||
*/
|
||||
if (xbps_pkg_is_ignored(xhp, pkgname)) {
|
||||
xbps_dbg_printf_append(xhp, "%s ignored.\n", pkgname);
|
||||
free(pkgname);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Pass 1: check if required dependency is provided as virtual
|
||||
* package via "provides", if true ignore dependency.
|
||||
|
22
lib/util.c
22
lib/util.c
@ -86,6 +86,28 @@ xbps_pkg_is_installed(struct xbps_handle *xhp, const char *pkg)
|
||||
return 0; /* not fully installed */
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_pkg_is_ignored(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
char *pkgname;
|
||||
bool rv = false;
|
||||
|
||||
assert(xhp);
|
||||
assert(pkg);
|
||||
|
||||
if (!xhp->ignored_pkgs)
|
||||
return false;
|
||||
|
||||
if ((pkgname = xbps_pkgpattern_name(pkg)) != NULL ||
|
||||
(pkgname = xbps_pkg_name(pkg)) != NULL) {
|
||||
rv = xbps_match_string_in_array(xhp->ignored_pkgs, pkgname);
|
||||
free(pkgname);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return xbps_match_string_in_array(xhp->ignored_pkgs, pkg);
|
||||
}
|
||||
|
||||
const char *
|
||||
xbps_pkg_version(const char *pkg)
|
||||
{
|
||||
|
@ -24,3 +24,4 @@ atf_test_program{name="update_itself"}
|
||||
atf_test_program{name="cyclic_deps"}
|
||||
atf_test_program{name="conflicts"}
|
||||
atf_test_program{name="downgrade_hold"}
|
||||
atf_test_program{name="ignore"}
|
||||
|
@ -7,7 +7,7 @@ TESTSHELL+= replace_test installmode_test obsoletefiles_test
|
||||
TESTSHELL+= issue31_test scripts_test incorrect_deps_test
|
||||
TESTSHELL+= vpkg_test install_test preserve_files_test configure_test
|
||||
TESTSHELL+= update_shlibs update_hold update_repolock cyclic_deps conflicts
|
||||
TESTSHELL+= update_itself downgrade_hold
|
||||
TESTSHELL+= update_itself downgrade_hold ignore
|
||||
EXTRA_FILES = Kyuafile
|
||||
|
||||
include $(TOPDIR)/mk/test.mk
|
||||
|
70
tests/xbps/libxbps/shell/ignore.sh
Normal file
70
tests/xbps/libxbps/shell/ignore.sh
Normal file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env atf-sh
|
||||
|
||||
atf_test_case install_with_ignored_dep
|
||||
|
||||
install_with_ignored_dep_head() {
|
||||
atf_set "descr" "Tests for pkg install: with ignored dependency"
|
||||
}
|
||||
|
||||
install_with_ignored_dep_body() {
|
||||
mkdir -p repo pkg_A pkg_B
|
||||
cd repo
|
||||
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
echo "ignorepkg=B" > ignore.conf
|
||||
out=$(xbps-install -r root -C ignore.conf --repository=$PWD/repo -n A)
|
||||
set -- $out
|
||||
exp="$1 $2 $3 $4"
|
||||
atf_check_equal "$exp" "A-1.0_1 install noarch $PWD/repo"
|
||||
xbps-install -r root -C ignore.conf --repository=$PWD/repo -yd A
|
||||
atf_check_equal $? 0
|
||||
xbps-query -r root A
|
||||
atf_check_equal $? 0
|
||||
xbps-query -r root B
|
||||
atf_check_equal $? 2
|
||||
}
|
||||
|
||||
atf_test_case update_with_ignored_dep
|
||||
|
||||
update_with_ignored_dep_head() {
|
||||
atf_set "descr" "Tests for pkg update: with ignored dependency"
|
||||
}
|
||||
|
||||
update_with_ignored_dep_body() {
|
||||
mkdir -p repo pkg_A pkg_B
|
||||
cd repo
|
||||
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n B-1.0_1 -s "B pkg" ../pkg_B
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
echo "ignorepkg=B" > ignore.conf
|
||||
xbps-install -r root -C ignore.conf --repository=$PWD/repo -yd A
|
||||
atf_check_equal $? 0
|
||||
cd repo
|
||||
xbps-create -A noarch -n A-1.1_1 -s "A pkg" ../pkg_A
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
out=$(xbps-install -r root -C ignore.conf --repository=$PWD/repo -un)
|
||||
set -- $out
|
||||
exp="$1 $2 $3 $4"
|
||||
atf_check_equal "$exp" "A-1.1_1 update noarch $PWD/repo"
|
||||
xbps-install -r root --repository=$PWD/repo -yuvd
|
||||
atf_check_equal $? 0
|
||||
out=$(xbps-query -r root -p pkgver A)
|
||||
atf_check_equal $out A-1.1_1
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case install_with_ignored_dep
|
||||
atf_add_test_case update_with_ignored_dep
|
||||
}
|
Loading…
Reference in New Issue
Block a user