Merge pull request #61 from Gottox/revert

Allow automatic downgrading
This commit is contained in:
Enno Boland 2014-09-23 21:11:24 +02:00
commit f7a5d459d7
10 changed files with 153 additions and 6 deletions

7
NEWS
View File

@ -8,6 +8,13 @@ xbps-0.41 (???):
* A performance improvement for xbps_file_hash(), by Enno Boland.
* Added reverts field to package definitions. If defined, a package will
replace all versions specified in this field even if the installed version is
newer. This is helpful when a broken package is released. The maintainer can
downgrade this package and define a reverts field to the broken version. On
the next update xbps-install will automatically replace the broken release by
the new downgraded release.
xbps-0.40 (2014-09-18):
* xbps-install(8): handle xbps_transaction_prepare() returning ENOSPC, to

View File

@ -94,6 +94,8 @@ usage(void)
" -q --quiet Work silently.\n"
" -R --replaces Replaces (blank separated list,\n"
" e.g: 'foo>=1.0 blah<2.0').\n"
" -r --reverts Reverts (blank separated list,\n"
" e.g: '1.0_1 2.0_3').\n"
" -S --long-desc Long description (80 cols per line).\n"
" -s --desc Short description (max 80 characters).\n"
" -t --tags A list of tags/categories (blank separated list).\n"
@ -591,7 +593,7 @@ set_build_date(void)
int
main(int argc, char **argv)
{
const char *shortopts = "A:B:C:D:F:G:H:hl:M:m:n:P:pqR:S:s:t:V";
const char *shortopts = "A:B:C:D:F:G:H:hl:M:m:n:P:pqr:R:S:s:t:V";
const struct option longopts[] = {
{ "architecture", required_argument, NULL, 'A' },
{ "built-with", required_argument, NULL, 'B' },
@ -609,6 +611,7 @@ main(int argc, char **argv)
{ "preserve", no_argument, NULL, 'p' },
{ "quiet", no_argument, NULL, 'q' },
{ "replaces", required_argument, NULL, 'R' },
{ "reverts", required_argument, NULL, 'r' },
{ "long-desc", required_argument, NULL, 'S' },
{ "desc", required_argument, NULL, 's' },
{ "tags", required_argument, NULL, 't' },
@ -624,7 +627,7 @@ main(int argc, char **argv)
struct archive_entry_linkresolver *resolver;
struct stat st;
const char *conflicts, *deps, *homepage, *license, *maint, *bwith;
const char *provides, *pkgver, *replaces, *desc, *ldesc;
const char *provides, *pkgver, *replaces, *reverts, *desc, *ldesc;
const char *arch, *config_files, *mutable_files, *version;
const char *buildopts, *shlib_provides, *shlib_requires;
const char *compression, *tags = NULL, *srcrevs = NULL;
@ -634,8 +637,9 @@ main(int argc, char **argv)
mode_t myumask;
arch = conflicts = deps = homepage = license = maint = compression = NULL;
provides = pkgver = replaces = desc = ldesc = bwith = buildopts = NULL;
config_files = mutable_files = shlib_provides = shlib_requires = NULL;
provides = pkgver = replaces = reverts = desc = ldesc = bwith = NULL;
buildopts = config_files = mutable_files = shlib_provides = NULL;
shlib_requires = NULL;
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
if (optarg && strcmp(optarg, "") == 0)
@ -690,6 +694,9 @@ main(int argc, char **argv)
case 'R':
replaces = optarg;
break;
case 'r':
reverts = optarg;
break;
case 'S':
ldesc = optarg;
break;
@ -794,6 +801,7 @@ main(int argc, char **argv)
process_array("conflicts", conflicts);
process_array("provides", provides);
process_array("replaces", replaces);
process_array("reverts", reverts);
process_array("shlib-provides", shlib_provides);
process_array("shlib-requires", shlib_requires);

View File

@ -58,6 +58,9 @@ Enable quiet operation.
.It Fl R, Fl -replaces Ar list
A list of package patterns this package replaces, separated by whitespaces. Example:
.Ar 'foo>=1.0 blah>=2.0' .
.It Fl r, Fl -reverts Ar list
A list of versions this package reverts, separated by whitespaces. Example:
.Ar '2.0_1 2.1_1' .
.It Fl S, Fl -long-desc Ar string
A long description for this package.
.It Fl s, Fl -desc Ar string

View File

@ -117,6 +117,22 @@ index_add(struct xbps_handle *xhp, int argc, char **argv, bool force)
xbps_dictionary_get_cstring(curpkgd, "pkgver", &opkgver);
xbps_dictionary_get_cstring(curpkgd, "architecture", &oarch);
ret = xbps_cmpver(pkgver, opkgver);
/*
* If the considered package reverts the package in the index,
* consider the current package as the newer one.
*/
if(ret < 0 && xbps_pkg_reverts(binpkgd, opkgver)) {
ret = 1;
}
/*
* If package in the index reverts considered package, consider the
* package in the index as the newer one.
*/
else if (ret > 0 && xbps_pkg_reverts(curpkgd, pkgver)) {
ret = -1;
}
if (ret <= 0) {
/* Same version or index version greater */
fprintf(stderr, "index: skipping `%s' (%s), already registered.\n", pkgver, arch);

View File

@ -48,7 +48,7 @@
*
* This header documents the full API for the XBPS Library.
*/
#define XBPS_API_VERSION "20140913"
#define XBPS_API_VERSION "20140923"
#ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET"
@ -1835,6 +1835,21 @@ bool xbps_pkg_arch_match(struct xbps_handle *xhp,
*/
int xbps_humanize_number(char *buf, int64_t bytes);
/**
* Tests if pkgver is reverted by pkg
*
* The package version is defined by:
* ${NAME}-{${VERSION}_${REVISION}.
*
* the name part is ignored.
*
* @param[in] pkg a package which is a candidate to revert pkgver.
* @param[in] pkgver a package version string
*
* @return true if pkg reverts pkgver, false otherwise.
*/
bool xbps_pkg_reverts(xbps_dictionary_t pkg, const char *pkgver);
/**
* Compares package version strings.
*

View File

@ -117,7 +117,8 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
*/
xbps_dictionary_get_cstring_nocopy(pkg_pkgdb,
"pkgver", &instpkgver);
if (xbps_cmpver(repopkgver, instpkgver) <= 0) {
if (xbps_cmpver(repopkgver, instpkgver) <= 0 &&
!xbps_pkg_reverts(pkg_repod, repopkgver)) {
xbps_dbg_printf(xhp, "[rpool] Skipping `%s' "
"(installed: %s) from repository `%s'\n",
repopkgver, instpkgver, repoloc);

View File

@ -425,3 +425,26 @@ xbps_humanize_number(char *buf, int64_t bytes)
return humanize_number(buf, 7, bytes, "B",
HN_AUTOSCALE, HN_DECIMAL|HN_NOSPACE);
}
/*
* Check if pkg is explicitly marked to replace a specific installed version.
*/
bool
xbps_pkg_reverts(xbps_dictionary_t pkg, const char *pkgver) {
unsigned int i;
xbps_array_t reverts;
const char *version = xbps_pkg_version(pkgver);
const char *revertver;
if ((reverts = xbps_dictionary_get(pkg, "reverts")) == NULL)
return false;
for (i = 0; i < xbps_array_count(reverts); i++) {
xbps_array_get_cstring_nocopy(reverts, i, &revertver);
if (strcmp(version, revertver) == 0) {
return false;
}
}
return false;
}

View File

@ -146,11 +146,42 @@ ATF_TC_BODY(pkgdb_get_pkg_revdeps_test, tc)
ATF_REQUIRE_STREQ(xbps_string_cstring_nocopy(pstr), eout);
}
ATF_TC(pkgdb_pkg_reverts_test);
ATF_TC_HEAD(pkgdb_pkg_reverts_test, tc)
{
atf_tc_set_md_var(tc, "descr", "Test xbps_pkg_reverts()");
}
ATF_TC_BODY(pkgdb_pkg_reverts_test, tc)
{
struct xbps_handle xh;
const char *tcsdir;
xbps_dictionary_t pkgd;
/* get test source dir */
tcsdir = atf_tc_get_config_var(tc, "srcdir");
memset(&xh, 0, sizeof(xh));
strncpy(xh.rootdir, tcsdir, sizeof(xh.rootdir));
strncpy(xh.metadir, tcsdir, sizeof(xh.metadir));
xh.flags = XBPS_FLAG_DEBUG;
ATF_REQUIRE_EQ(xbps_init(&xh), 0);
pkgd = xbps_pkgdb_get_pkg(&xh, "reverts");
ATF_REQUIRE_EQ(xbps_object_type(pkgd), XBPS_TYPE_DICTIONARY);
ATF_REQUIRE_EQ(xbps_pkg_reverts(pkgd, "reverts-0.2_1"), 0);
ATF_REQUIRE_EQ(xbps_pkg_reverts(pkgd, "reverts-0.3_1"), 1);
ATF_REQUIRE_EQ(xbps_pkg_reverts(pkgd, "reverts-0.4_1"), 1);
ATF_REQUIRE_EQ(xbps_pkg_reverts(pkgd, "reverts-0.5_1"), 0);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, pkgdb_get_pkg_test);
ATF_TP_ADD_TC(tp, pkgdb_get_virtualpkg_test);
ATF_TP_ADD_TC(tp, pkgdb_get_pkg_revdeps_test);
ATF_TP_ADD_TC(tp, pkgdb_pkg_reverts_test);
return atf_no_error();
}

View File

@ -94,5 +94,21 @@
<key>state</key>
<string>installed</string>
</dict>
<key>reverts</key>
<dict>
<key>automatic-install</key>
<true/>
<key>pkgver</key>
<string>reverts-0.2_1</string>
<key>reverts</key>
<array>
<string>0.3_1</string>
<string>0.4_1</string>
</array>
<key>short_desc</key>
<string>two descriptionm</string>
<key>state</key>
<string>installed</string>
</dict>
</dict>
</plist>

View File

@ -30,6 +30,33 @@ update_body() {
atf_check_equal $rv 0
}
revert_head() {
atf_set "descr" "xbps-rindex(8) -a: revert version test"
}
revert_body() {
mkdir -p some_repo pkg_A
touch pkg_A/file00
cd some_repo
xbps-create -A noarch -n foo-1.1_1 -s "foo pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
xbps-create -A noarch -n foo-1.0_1 -r "1.1_1" -s "foo pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
cd ..
result="$(xbps-query -r root -C empty.conf --repository=some_repo -o \*)"
expected="foo-1.0_1: /file00 (some_repo)"
rv=0
if [ "$result" != "$expected" ]; then
rv=1
fi
atf_check_equal $rv 0
}
atf_init_test_cases() {
atf_add_test_case update
atf_add_test_case revert
}