Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Allow pkg add to work even if no version is specified in dependencies
Baptiste Daroussin committed 10 years ago
commit 1118360e0f9710c6e8be2276bf5dd8b3438f93ea
parent 52f577223d6175146fe3c8d01be7bee5282ee6be
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
}