Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Allow pkg add to work even if no version is specified in dependencies
Baptiste Daroussin committed 10 years ago
commit 1118360e0f9710c6e8be2276bf5dd8b3438f93ea
parent 52f5772
6 files changed +152 -22
modified libpkg/pkg.c
@@ -682,18 +682,17 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve
	assert(pkg != NULL);
	assert(name != NULL && name[0] != '\0');
	assert(origin != NULL && origin[0] != '\0');
-
	assert(version != NULL && version[0] != '\0');

-
	pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s, version: %s", origin, name, version);
+
	pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s", origin, name);
	HASH_FIND_STR(pkg->deps, name, d);
	if (d != NULL) {
		if (developer_mode) {
-
			pkg_emit_error("%s-%s: duplicate dependency listing: %s-%s, fatal (developer mode)",
-
			    pkg->name, pkg->version, name, version);
+
			pkg_emit_error("%s: duplicate dependency listing: %s, fatal (developer mode)",
+
			    pkg->name, name);
			return (EPKG_FATAL);
		} else {
-
			pkg_emit_error("%s-%s: duplicate dependency listing: %s-%s, ignoring",
-
			    pkg->name, pkg->version, name, version);
+
			pkg_emit_error("%s-%s: duplicate dependency listing: %s, ignoring",
+
			    pkg->name, pkg->version, name);
			return (EPKG_OK);
		}
	}
@@ -702,7 +701,8 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve

	d->origin = strdup(origin);
	d->name = strdup(name);
-
	d->version = strdup(version);
+
	if (version != NULL && version[0] != '\0')
+
		d->version = strdup(version);
	d->uid = strdup(name);
	d->locked = locked;

@@ -719,14 +719,14 @@ pkg_addrdep(struct pkg *pkg, const char *name, const char *origin, const char *v
	assert(pkg != NULL);
	assert(name != NULL && name[0] != '\0');
	assert(origin != NULL && origin[0] != '\0');
-
	assert(version != NULL && version[0] != '\0');

-
	pkg_debug(3, "Pkg: add a new reverse dependency origin: %s, name: %s, version: %s", origin, name, version);
+
	pkg_debug(3, "Pkg: add a new reverse dependency origin: %s, name: %s", origin, name);
	pkg_dep_new(&d);

	d->origin = strdup(origin);
	d->name = strdup(name);
-
	d->version = strdup(version);
+
	if (version != NULL && version[0] != '\0')
+
		d->version = strdup(version);
	d->uid = strdup(name);
	d->locked = locked;

modified libpkg/pkg_add.c
@@ -35,6 +35,7 @@
#include <libgen.h>
#include <string.h>
#include <errno.h>
+
#include <glob.h>

#include "pkg.h"
#include "private/event.h"
@@ -331,6 +332,46 @@ cleanup:
	return (retcode);
}

+
static char *
+
pkg_globmatch(char *pattern, const char *name)
+
{
+
	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_matchc; i++) {
+
		/* the version starts here */
+
		buf = strrchr(g.gl_pathv[i], '-');
+
		if (buf == NULL)
+
			continue;
+
		buf2 = strchr(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;
+
		}
+
		if (pkg_version_cmp(path, g.gl_pathv[i]) == '>')
+
			path = g.gl_pathv[i];
+
	}
+
	path = strdup(path);
+
	globfree(&g);
+

+
	return (path);
+
}
+

static int
pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
	const char *path, int flags,
@@ -340,7 +381,7 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
	int	ret, retcode;
	struct pkg_dep	*dep = NULL;
	char	bd[MAXPATHLEN], *basedir;
-
	char	dpath[MAXPATHLEN];
+
	char	dpath[MAXPATHLEN], *ppath;
	const char	*ext;
	struct pkg	*pkg_inst = NULL;

@@ -402,13 +443,21 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
		if (pkg_is_installed(db, dep->name) == EPKG_OK)
			continue;

-
		if (basedir != NULL) {
+
		if (basedir == NULL) {
+
			pkg_emit_missing_dep(pkg, dep);
+
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
+
				goto cleanup;
+
			continue;
+
		}
+

+
		if (dep->version != NULL && dep->version[0] != '\0') {
			snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
				dep->name, dep->version, ext);

			if ((flags & PKG_ADD_UPGRADE) == 0 &&
-
							access(dpath, F_OK) == 0) {
-
				ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys, location);
+
			    access(dpath, F_OK) == 0) {
+
				ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC,
+
				    keys, location);

				if (ret != EPKG_OK)
					goto cleanup;
@@ -418,9 +467,30 @@ pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
					goto cleanup;
			}
		} else {
-
			pkg_emit_missing_dep(pkg, dep);
-
			if ((flags & PKG_ADD_FORCE_MISSING) == 0)
-
				goto cleanup;
+
			snprintf(dpath, sizeof(dpath), "%s/%s-*%s", basedir,
+
			    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;
+
			}
+
			if ((flags & PKG_ADD_UPGRADE) == 0 &&
+
			    access(ppath, F_OK) == 0) {
+
				ret = pkg_add(db, ppath, PKG_ADD_AUTOMATIC,
+
				    keys, location);
+

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

modified libpkg/pkg_manifest.c
@@ -692,7 +692,7 @@ pkg_set_deps_from_object(struct pkg *pkg, const ucl_object_t *obj)
			if (strcasecmp(key, "version") == 0)
				version = ucl_object_tostring(cur);
		}
-
		if (origin != NULL && version != NULL)
+
		if (origin != NULL)
			pkg_adddep(pkg, okey, origin, version, false);
		else
			pkg_emit_error("Skipping malformed dependency %s", okey);
modified libpkg/pkgdb.c
@@ -1730,7 +1730,8 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete, int forced)
	 */

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
-
		if (run_prstmt(DEPS, dep->origin, dep->name, dep->version,
+
		if (run_prstmt(DEPS, dep->origin, dep->name,
+
		    dep->version ? dep->version : "",
		    package_id) != SQLITE_DONE) {
			ERROR_SQLITE(s, SQL(DEPS));
			goto cleanup;
modified src/event.c
@@ -770,9 +770,8 @@ event_callback(void *data, struct pkg_event *ev)
		    "the repositories\n", ev->e_not_found.pkg_name);
		break;
	case PKG_EVENT_MISSING_DEP:
-
		warnx("Missing dependency '%s-%s'",
-
		    pkg_dep_name(ev->e_missing_dep.dep),
-
		    pkg_dep_version(ev->e_missing_dep.dep));
+
		warnx("Missing dependency '%s'",
+
		    pkg_dep_name(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		fprintf(stderr, "Unable to open remote database \"%s\". "
modified tests/frontend/add.shin
@@ -263,6 +263,65 @@ post-install
		pkg add -M -
}

+
atf_test_case add_no_version
+
add_no_version_body() {
+
	cat << EOF > test.ucl
+
name: test
+
origin: test
+
version: 1
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /
+
abi = "*";
+
desc: <<EOD
+
Yet another test
+
EOD
+
EOF
+

+
	cat << EOF > test-lib.ucl
+
name: test-lib
+
origin: test
+
version: 1
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /
+
abi = "*";
+
desc: <<EOD
+
Yet another test
+
EOD
+
EOF
+

+
	cat << EOF > final.ucl
+
name: final
+
origin: test
+
version: 1
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /
+
abi = "*";
+
desc: <<EOD
+
Yet another test
+
EOD
+
deps {
+
	test {
+
		origin = "test";
+
	}
+
}
+
EOF
+
	for p in test test-lib final ; do
+
		atf_check -o ignore -s exit:0 \
+
			pkg create -M ${p}.ucl
+
	done
+
	atf_check -o ignore -s exit:0 \
+
		pkg add final-1.txz
+
}
+

atf_init_test_cases() {
	. $(atf_get_srcdir)/test_environment.sh

@@ -274,4 +333,5 @@ atf_init_test_cases() {
	atf_add_test_case add_quiet
	atf_add_test_case add_stdin
	atf_add_test_case add_stdin_missing
+
	atf_add_test_case add_no_version
}