Skip to content

Commit

Permalink
Revert "Backout support for provides/requires for pkg add"
Browse files Browse the repository at this point in the history
This reverts commit 537d39e.
  • Loading branch information
bapt committed Feb 26, 2025
1 parent bf05f1f commit 1ca498b
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 55 deletions.
171 changes: 116 additions & 55 deletions libpkg/pkg_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,45 +1071,21 @@ pkg_extract_finalize(struct pkg *pkg, tempdirs_t *tempdirs)
return (EPKG_OK);
}

static char *
pkg_globmatch(char *pattern, const char *name)
static bool
should_append_pkg(pkg_chain_t *localpkgs, struct pkg *p)
{
glob_t g;
int i;
char *buf, *buf2;
char *path = NULL;

if (glob(pattern, 0, NULL, &g) == GLOB_NOMATCH) {
globfree(&g);

return (NULL);
}

for (i = 0; i < g.gl_pathc; i++) {
/* the version starts here */
buf = strrchr(g.gl_pathv[i], '-');
if (buf == NULL)
continue;
buf2 = strrchr(g.gl_pathv[i], '/');
if (buf2 == NULL)
buf2 = g.gl_pathv[i];
else
buf2++;
/* ensure we have match the proper name */
if (strncmp(buf2, name, buf - buf2) != 0)
continue;
if (path == NULL) {
path = g.gl_pathv[i];
continue;
/* only keep the highest version is we fine one */
tll_foreach(*localpkgs, lp) {
if (strcmp(lp->item->name, p->name) == 0) {
if (pkg_version_cmp(lp->item->version, p->version) == -1) {
tll_remove_and_free(*localpkgs, lp, pkg_free);
return (true);
}
return (false);
}
if (pkg_version_cmp(path, g.gl_pathv[i]) == 1)
path = g.gl_pathv[i];
}
if (path)
path = xstrdup(path);
globfree(&g);

return (path);
/* none found we should append */
return (true);
}

static int
Expand All @@ -1120,10 +1096,14 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
int ret, retcode;
struct pkg_dep *dep = NULL;
char bd[MAXPATHLEN];
char dpath[MAXPATHLEN], *ppath;
char dpath[MAXPATHLEN], *ppath, *basedir = NULL;
const char *ext = NULL;
struct pkg *pkg_inst = NULL;
bool fromstdin;
pkg_chain_t localpkgs = tll_init();
struct pkghash *lpkgs = NULL;
struct pkghash *provides = NULL;
struct pkghash *shlibs_provides = NULL;

arch = pkg->abi != NULL ? pkg->abi : pkg->altabi;

Expand Down Expand Up @@ -1183,9 +1163,39 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,

retcode = EPKG_FATAL;
pkg_emit_add_deps_begin(pkg);
if (!fromstdin) {
glob_t g;
char *pattern;

xasprintf(&pattern, "%s/*%s" , bd, ext);
if (glob(pattern, 0, NULL, &g) == 0) {
for (int i = 0; i <g.gl_pathc; i++) {
struct pkg *p = NULL;
if (pkg_open(&p, g.gl_pathv[i],
PKG_OPEN_MANIFEST_COMPACT) == EPKG_OK) {
if (should_append_pkg(&localpkgs, p)) {
p->repopath = xstrdup(g.gl_pathv[i]);
tll_push_back(localpkgs, p);
}
}
}
}
globfree(&g);
free(pattern);
tll_foreach(localpkgs, p) {
pkghash_safe_add(lpkgs, p->item->name, xstrdup(p->item->repopath), NULL);
tll_foreach(p->item->shlibs_provided, sp) {
pkghash_safe_add(shlibs_provides, sp->item, xstrdup(p->item->repopath), free);
}
tll_foreach(p->item->provides, sp) {
pkghash_safe_add(provides, sp->item, xstrdup(p->item->repopath), free);
}
}
tll_free_and_free(localpkgs, pkg_free);
}

while (pkg_deps(pkg, &dep) == EPKG_OK) {
dpath[0] = '\0';
pkghash_entry *founddep = NULL;

if (pkg_is_installed(db, dep->name) == EPKG_OK)
continue;
Expand All @@ -1197,28 +1207,76 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
continue;
}

if (dep->version != NULL && dep->version[0] != '\0') {
snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", bd,
dep->name, dep->version, ext);
if ((founddep = pkghash_get(lpkgs, dep->name)) == NULL) {
pkg_emit_missing_dep(pkg, dep);
if ((flags & PKG_ADD_FORCE_MISSING) == 0)
goto cleanup;
continue;
}

if (strlen(dpath) == 0 || access(dpath, F_OK) != 0) {
snprintf(dpath, sizeof(dpath), "%s/%s-*%s", bd,
dep->name, ext);
ppath = pkg_globmatch(dpath, dep->name);
if (ppath == NULL) {
pkg_emit_missing_dep(pkg, dep);
if ((flags & PKG_ADD_FORCE_MISSING) == 0)
goto cleanup;
continue;
}
strlcpy(dpath, ppath, sizeof(dpath));
free(ppath);
if ((flags & PKG_ADD_UPGRADE) == 0 &&
access(founddep->value, F_OK) == 0) {
ret = pkg_add(db, founddep->value, 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->shlibs_required, s) {
pkghash_entry *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;
}
if ((founddep = pkghash_get(shlibs_provides, s->item)) == 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->value, F_OK) == 0) {
ret = pkg_add(db, founddep->value, 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) {
pkghash_entry *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;
}
if ((founddep = pkghash_get(provides, s->item)) == 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(dpath, F_OK) == 0) {
ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, location);
access(founddep->value, F_OK) == 0) {
ret = pkg_add(db, founddep->value, PKG_ADD_AUTOMATIC, location);

if (ret != EPKG_OK)
goto cleanup;
Expand All @@ -1231,6 +1289,9 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,

retcode = EPKG_OK;
cleanup:
pkghash_destroy(lpkgs);
pkghash_destroy(provides);
pkghash_destroy(shlibs_provides);
pkg_emit_add_deps_finished(pkg);

return (retcode);
Expand Down
50 changes: 50 additions & 0 deletions libpkg/pkgdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3018,3 +3018,53 @@ pkgdb_debug(int level, sqlite3_stmt *stmt)
dbg(level, "running: '%s'", str);
sqlite3_free(str);
}

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);
}
3 changes: 3 additions & 0 deletions libpkg/private/pkgdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,7 @@ bool pkgdb_file_exists(struct pkgdb *db, const char *path);
struct sqlite3_stmt *prepare_sql(sqlite3 *s, const char *sql);
void pkgdb_debug(int level, sqlite3_stmt *stmt);

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

#endif
37 changes: 37 additions & 0 deletions tests/frontend/add.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ tests_init \
add_stdin_missing \
add_no_version \
add_no_version_multi \
add_deps_multi \
add_require \
add_wrong_version

initialize_pkg() {
Expand Down Expand Up @@ -254,6 +256,41 @@ EOF
pkg add final-1.pkg
}

add_deps_multi_body() {
atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 2
atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg final final 1

cat << EOF >> final.ucl
deps {
test {
origin = "test";
},
}
EOF
atf_check -o ignore -s exit:0 pkg create -M test.ucl
atf_check -o ignore -s exit:0 pkg create -M final.ucl
atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
atf_check -o ignore -s exit:0 pkg create -M test.ucl
atf_check -o "match:.*test-2.*" -e ignore -s exit:0 \
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
Expand Down

0 comments on commit 1ca498b

Please sign in to comment.