Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
add: repect provides/requires
Baptiste Daroussin committed 3 years ago
commit 98597cae6bbb2f1f81b1d634d7fa2a8a90c1d42e
parent 9ca5e55
5 files changed +151 -1
modified libpkg/pkg_add.c
@@ -1098,6 +1098,86 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
		}
	}

+
	tll_foreach(pkg->shlibs_required, s) {
+
		struct pkg *founddep = NULL;
+
		if (pkgdb_is_shlib_provided(db, s->item))
+
			continue;
+

+
		if (fromstdin) {
+
			pkg_emit_error("Missing shlib dependency: %s", s->item);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
			continue;
+
		}
+
		tll_foreach(localpkgs, p) {
+
			tll_foreach(p->item->shlibs_provided, sp) {
+
				if (strcmp(sp->item, s->item) == 0) {
+
					founddep = p->item;
+
					break;
+
				}
+
			}
+
			if (founddep != NULL)
+
				break;
+
		}
+
		if (founddep == NULL) {
+
			pkg_emit_error("Missing shlib dependency: %s", s->item);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
			continue;
+
		}
+
		if ((flags & PKG_ADD_UPGRADE) == 0 &&
+
				access(founddep->repopath, F_OK) == 0) {
+
			ret = pkg_add(db, founddep->repopath, PKG_ADD_AUTOMATIC, location);
+

+
			if (ret != EPKG_OK)
+
				goto cleanup;
+
		} else {
+
			pkg_emit_missing_dep(pkg, dep);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
		}
+
	}
+

+
	tll_foreach(pkg->requires, s) {
+
		struct pkg *founddep = NULL;
+
		if (pkgdb_is_provided(db, s->item))
+
			continue;
+

+
		if (fromstdin) {
+
			pkg_emit_error("Missing require dependency: %s", s->item);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
			continue;
+
		}
+
		tll_foreach(localpkgs, p) {
+
			tll_foreach(p->item->provides, sp) {
+
				if (strcmp(sp->item, s->item) == 0) {
+
					founddep = p->item;
+
					break;
+
				}
+
			}
+
			if (founddep != NULL)
+
				break;
+
		}
+
		if (founddep == NULL) {
+
			pkg_emit_error("Missing require dependency: %s", s->item);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
			continue;
+
		}
+
		if ((flags & PKG_ADD_UPGRADE) == 0 &&
+
				access(founddep->repopath, F_OK) == 0) {
+
			ret = pkg_add(db, founddep->repopath, PKG_ADD_AUTOMATIC, location);
+

+
			if (ret != EPKG_OK)
+
				goto cleanup;
+
		} else {
+
			pkg_emit_missing_dep(pkg, dep);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
		}
+
	}
+

	retcode = EPKG_OK;
cleanup:
	tll_free_and_free(localpkgs, pkg_free);
modified libpkg/pkg_manifest.c
@@ -1048,7 +1048,7 @@ pkg_emit_object(struct pkg *pkg, short flags)
	if (seq)
		ucl_object_insert_key(top, seq, "groups", 6, false);

-
	pkg_debug(4, "Emitting shibs_required");
+
	pkg_debug(4, "Emitting shibs_required %zu\n", tll_length(pkg->shlibs_required));
	seq = NULL;
	tll_foreach(pkg->shlibs_required, s) {
		if (seq == NULL)
modified libpkg/pkgdb.c
@@ -3029,3 +3029,53 @@ pkgdb_is_dir_used(struct pkgdb *db, struct pkg *p, const char *dir, int64_t *res

	return (EPKG_OK);
}
+

+
bool
+
pkgdb_is_shlib_provided(struct pkgdb *db, const char *req)
+
{
+
	sqlite3_stmt *stmt;
+
	int ret;
+
	bool found = false;
+

+
	const char *sql = ""
+
		"select package_id from pkg_shlibs_provided INNER JOIN shlibs "
+
		"on pkg_shlibs_provided.shlib_id = shlibs.id "
+
		"where shlibs.name=?1" ;
+

+
	stmt = prepare_sql(db->sqlite, sql);
+
	if (stmt == NULL)
+
		return (false);
+

+
	sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
+
	ret = sqlite3_step(stmt);
+
	if (ret == SQLITE_ROW)
+
		found = true;
+

+
	sqlite3_finalize(stmt);
+
	return (found);
+
}
+

+
bool
+
pkgdb_is_provided(struct pkgdb *db, const char *req)
+
{
+
	sqlite3_stmt *stmt;
+
	int ret;
+
	bool found = false;
+

+
	const char *sql = ""
+
		"select package_id from pkg_provides INNER JOIN provides "
+
		"on pkg_provides.provide_id = provides.id "
+
		"where provides.provide = ?1" ;
+

+
	stmt = prepare_sql(db->sqlite, sql);
+
	if (stmt == NULL)
+
		return (false);
+

+
	sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
+
	ret = sqlite3_step(stmt);
+
	if (ret == SQLITE_ROW)
+
		found = true;
+

+
	sqlite3_finalize(stmt);
+
	return (found);
+
}
modified libpkg/private/pkgdb.h
@@ -182,4 +182,7 @@ void pkgdb_nfs_corruption(sqlite3 *s);
bool pkgdb_file_exists(struct pkgdb *db, const char *path);
struct sqlite3_stmt *prepare_sql(sqlite3 *s, const char *sql);

+
bool pkgdb_is_provided(struct pkgdb *db, const char *req);
+
bool pkgdb_is_shlib_provided(struct pkgdb *db, const char *req);
+

#endif
modified tests/frontend/add.sh
@@ -14,6 +14,7 @@ tests_init \
		add_no_version \
		add_no_version_multi \
		add_deps_multi \
+
		add_require \
		add_wrong_version

initialize_pkg() {
@@ -274,6 +275,22 @@ EOF
		pkg add final-1.pkg
}

+
add_require_body() {
+
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
+
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg final final 1
+
	cat << EOF >> final.ucl
+
requires: [functionA]
+
EOF
+
	cat << EOF >> test.ucl
+
provides: [functionA]
+
EOF
+

+
	atf_check -o ignore -s exit:0 pkg create -M test.ucl
+
	atf_check  -s exit:0 pkg create -M final.ucl
+
	atf_check -o match:".*test-1.*" -e ignore -s exit:0 \
+
		pkg add final-1.pkg
+
}
+

add_wrong_version_body() {
	for p in test final ; do
		atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg ${p} ${p} 1