diff --git a/bin/xbps-create/main.c b/bin/xbps-create/main.c index 1ff0640cf..7ff90df9c 100644 --- a/bin/xbps-create/main.c +++ b/bin/xbps-create/main.c @@ -784,7 +784,7 @@ process_archive(struct archive *ar, int main(int argc, char **argv) { - const char *shortopts = "A:B:C:c:D:F:G:H:hl:M:m:n:P:pqr:R:S:s:t:V"; + const char *shortopts = "A:B:C:c:D:F:G:H:hl:M:m:n:P:pqr:R:S:s:t:a:V"; const struct option longopts[] = { { "architecture", required_argument, NULL, 'A' }, { "built-with", required_argument, NULL, 'B' }, @@ -813,6 +813,7 @@ main(int argc, char **argv) { "compression", required_argument, NULL, '3' }, { "alternatives", required_argument, NULL, '4' }, { "changelog", required_argument, NULL, 'c'}, + { "abi", required_argument, NULL, 'a'}, { NULL, 0, NULL, 0 } }; struct archive *ar; @@ -823,7 +824,7 @@ main(int argc, char **argv) const char *provides, *pkgver, *replaces, *reverts, *desc, *ldesc; const char *arch, *config_files, *mutable_files, *version, *changelog; const char *buildopts, *shlib_provides, *shlib_requires, *alternatives; - const char *compression, *tags = NULL, *srcrevs = NULL; + const char *compression, *tags, *srcrevs, *abi; char pkgname[XBPS_NAME_SIZE], *binpkg, *tname, *p, cwd[PATH_MAX-1]; bool quiet = false, preserve = false; int c, pkg_fd; @@ -833,6 +834,7 @@ main(int argc, char **argv) provides = pkgver = replaces = reverts = desc = ldesc = bwith = NULL; buildopts = config_files = mutable_files = shlib_provides = NULL; alternatives = shlib_requires = changelog = NULL; + tags = srcrevs = abi = NULL; while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { if (optarg && strcmp(optarg, "") == 0) @@ -920,6 +922,9 @@ main(int argc, char **argv) case '4': alternatives = optarg; break; + case 'a': + abi = optarg; + break; case '?': default: usage(true); @@ -997,6 +1002,9 @@ main(int argc, char **argv) if (changelog) xbps_dictionary_set_cstring_nocopy(pkg_propsd, "changelog", changelog); + if (abi) + xbps_dictionary_set_cstring_nocopy(pkg_propsd, + "abi", abi); /* Optional arrays */ process_array("run_depends", deps); diff --git a/bin/xbps-rindex/index-add.c b/bin/xbps-rindex/index-add.c index 13123a867..dabb00b16 100644 --- a/bin/xbps-rindex/index-add.c +++ b/bin/xbps-rindex/index-add.c @@ -203,7 +203,8 @@ index_add(struct xbps_handle *xhp, int args, int argmax, char **argv, bool force xbps_dictionary_t idx, idxmeta, idxstage, binpkgd, curpkgd; struct xbps_repo *repo = NULL, *stage = NULL; struct stat st; - char *tmprepodir = NULL, *repodir = NULL, *rlockfname = NULL; + char *tmprepodir = NULL, *repodir = NULL, *rlockfname = NULL, *repo_abi = NULL; + bool new_repo = false; int rv = 0, ret = 0, rlockfd = -1; assert(argv); @@ -230,9 +231,11 @@ index_add(struct xbps_handle *xhp, int args, int argmax, char **argv, bool force if (repo) { idx = xbps_dictionary_copy_mutable(repo->idx); idxmeta = xbps_dictionary_copy_mutable(repo->idxmeta); + xbps_dictionary_get_cstring(idx, "abi", &repo_abi); } else { idx = xbps_dictionary_create(); idxmeta = NULL; + new_repo = true; } stage = xbps_repo_stage_open(xhp, repodir); if (stage == NULL && errno != ENOENT) { @@ -251,7 +254,7 @@ index_add(struct xbps_handle *xhp, int args, int argmax, char **argv, bool force * Process all packages specified in argv. */ for (int i = args; i < argmax; i++) { - const char *arch = NULL, *pkg = argv[i]; + const char *arch = NULL, *abi = NULL, *pkg = argv[i]; char *pkgver = NULL; char sha256[XBPS_SHA256_SIZE]; char pkgname[XBPS_NAME_SIZE]; @@ -277,6 +280,34 @@ index_add(struct xbps_handle *xhp, int args, int argmax, char **argv, bool force if (!xbps_pkg_name(pkgname, sizeof(pkgname), pkgver)) { abort(); } + /* + * If creating a new index and package has abi field, + * set abi for repo. Otherwise, check if repo and package + * have the same abi value. + */ + xbps_dictionary_get_cstring_nocopy(binpkgd, "abi", &abi); + if (new_repo) { + if (abi) { + xbps_dictionary_set_cstring(idx, "abi", abi); + repo_abi = strdup(abi); + assert(repo_abi); + } + new_repo = false; + } else { + if (abi && repo_abi) { + if (strcmp(abi, repo_abi)) { + fprintf(stderr, "index: ignoring %s, unmatched abi (%s)\n", pkgver, abi); + xbps_object_release(binpkgd); + free(pkgver); + continue; + } + } else if ((abi && !repo_abi) || (!abi && repo_abi)) { + fprintf(stderr, "index: ignoring %s, unmatched abi (%s)\n", pkgver, abi ? abi : "empty"); + xbps_object_release(binpkgd); + free(pkgver); + continue; + } + } /* * Check if this package exists already in the index, but first * checking the version. If current package version is greater @@ -397,8 +428,8 @@ index_add(struct xbps_handle *xhp, int args, int argmax, char **argv, bool force xbps_repo_unlock(rlockfd, rlockfname); - if (tmprepodir) - free(tmprepodir); + free(tmprepodir); + free(repo_abi); return rv; } diff --git a/tests/xbps/xbps-create/basic_test.sh b/tests/xbps/xbps-create/basic_test.sh index a98b21f37..c7880be98 100644 --- a/tests/xbps/xbps-create/basic_test.sh +++ b/tests/xbps/xbps-create/basic_test.sh @@ -179,6 +179,25 @@ reject_fifo_file_body() { atf_check_equal $? 1 } +atf_test_case set_abi + +set_abi_head() { + atf_set "descr" "xbps-create(1): create package with abi field" +} + +set_abi_body() { + mkdir -p repo pkg_A/usr/include/gsm + touch -f pkg_A/usr/include/gsm/gsm.h + cd repo + xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" -a 1 ../pkg_A + atf_check_equal $? 0 + cd .. + xbps-rindex -d -a repo/*.xbps + atf_check_equal $? 0 + rv="$(xbps-query -r root --repository=repo -p abi foo)" + atf_check_equal $rv 1 +} + atf_init_test_cases() { atf_add_test_case hardlinks_size atf_add_test_case symlink_relative_target @@ -187,4 +206,5 @@ atf_init_test_cases() { atf_add_test_case restore_mtime atf_add_test_case reproducible_pkg atf_add_test_case reject_fifo_file + atf_add_test_case set_abi } diff --git a/tests/xbps/xbps-rindex/add_test.sh b/tests/xbps/xbps-rindex/add_test.sh index 37e5c141f..759c71316 100644 --- a/tests/xbps/xbps-rindex/add_test.sh +++ b/tests/xbps/xbps-rindex/add_test.sh @@ -167,9 +167,81 @@ stage_resolve_bug_body() { atf_check_equal $? 1 } +atf_test_case abi_mismatch + +abi_mismatch_head() { + atf_set "descr" "xbps-rindex(1) -a: don't index package with different abi" +} + +abi_mismatch_body() { + mkdir -p some_repo pkg_A pkg_B + touch pkg_A/file00 pkg_B/file01 + cd some_repo + xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n bar-1.1_1 -s "foo pkg" -a 1 ../pkg_B + atf_check_equal $? 0 + + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + n="$(xbps-query -r root --repository=some_repo -s "" | wc -l)" + atf_check_equal $n 1 +} + +atf_test_case abi_mismatch_2 + +abi_mismatch_2_head() { + atf_set "descr" "xbps-rindex(1) -a: don't index package with different abi" +} + +abi_mismatch_2_body() { + mkdir -p some_repo pkg_A pkg_B + touch pkg_A/file00 pkg_B/file01 + cd some_repo + xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" -a 2 ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n bar-1.1_1 -s "foo pkg" -a 1 ../pkg_B + atf_check_equal $? 0 + + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + n="$(xbps-query -r root --repository=some_repo -s "" | wc -l)" + atf_check_equal $n 1 +} + +atf_test_case abi_match + +abi_match_head() { + atf_set "descr" "xbps-rindex(1) -a: index packages with matching abi" +} + +abi_match_body() { + mkdir -p some_repo pkg_A pkg_B + touch pkg_A/file00 pkg_B/file01 + cd some_repo + xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" -a 1 ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n bar-1.1_1 -s "foo pkg" -a 1 ../pkg_B + atf_check_equal $? 0 + + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + n="$(xbps-query -r root --repository=some_repo -s "" | wc -l)" + atf_check_equal $n 2 +} + atf_init_test_cases() { atf_add_test_case update atf_add_test_case revert atf_add_test_case stage atf_add_test_case stage_resolve_bug + atf_add_test_case abi_mismatch + atf_add_test_case abi_mismatch_2 + atf_add_test_case abi_match }