Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Bring back pkg create -n but this time consistent
Baptiste Daroussin committed 6 years ago
commit a8bec7220491046b80ba584359491761816f65fb
parent 9a27c4f
9 files changed +81 -21
modified libpkg/libpkg.ver
@@ -30,9 +30,10 @@ global:
	pkg_create_installed;
	pkg_create_new;
	pkg_create_repo;
-
	pkg_create_set_format;
	pkg_create_set_compression_level;
+
	pkg_create_set_format;
	pkg_create_set_output_dir;
+
	pkg_create_set_overwrite;
	pkg_create_set_rootdir;
	pkg_create_set_timestamp;
	pkg_create_staged;
modified libpkg/packing.c
@@ -34,6 +34,7 @@
#include <string.h>
#include <pwd.h>
#include <grp.h>
+
#include <errno.h>

#include "pkg.h"
#include "private/event.h"
@@ -50,7 +51,7 @@ struct packing {

int
packing_init(struct packing **pack, const char *path, pkg_formats format, int clevel,
-
    time_t timestamp)
+
	time_t timestamp, bool overwrite)
{
	char archive_path[MAXPATHLEN];
	const char *ext;
@@ -86,12 +87,23 @@ packing_init(struct packing **pack, const char *path, pkg_formats format, int cl
		archive_read_free((*pack)->aread);
		archive_write_close((*pack)->awrite);
		archive_write_free((*pack)->awrite);
+
		free(*pack);
		*pack = NULL;
-
		return EPKG_FATAL; /* error set by _set_format() */
+
		return (EPKG_FATAL); /* error set by _set_format() */
	}
	snprintf(archive_path, sizeof(archive_path), "%s.%s", path,
	    ext);

+
	if (!overwrite && access(archive_path, F_OK) == 0) {
+
		archive_read_close((*pack)->aread);
+
		archive_read_free((*pack)->aread);
+
		archive_write_close((*pack)->awrite);
+
		archive_write_free((*pack)->awrite);
+
		free(*pack);
+
		*pack = NULL;
+
		errno = EEXIST;
+
		return (EPKG_EXIST);
+
	}
	pkg_debug(1, "Packing to file '%s'", archive_path);
	if (archive_write_open_filename(
	    (*pack)->awrite, archive_path) != ARCHIVE_OK) {
modified libpkg/pkg.h.in
@@ -504,7 +504,11 @@ typedef enum {
	/**
	 * Can not delete the package because it is vital, i.e. a kernel
	 */
-
	EPKG_VITAL
+
	EPKG_VITAL,
+
	/**
+
	 * the package already exist
+
	 */
+
	EPKG_EXIST
} pkg_error_t;

/**
@@ -1699,6 +1703,7 @@ struct pkg_create *pkg_create_new(void);
void pkg_create_free(struct pkg_create *);
bool pkg_create_set_format(struct pkg_create *, const char *);
void pkg_create_set_compression_level(struct pkg_create *, int);
+
void pkg_create_set_overwrite(struct pkg_create *, bool);
void pkg_create_set_rootdir(struct pkg_create *, const char *);
void pkg_create_set_output_dir(struct pkg_create *, const char *);
void pkg_create_set_timestamp(struct pkg_create *, time_t);
modified libpkg/pkg_create.c
@@ -190,8 +190,10 @@ pkg_create_archive(struct pkg *pkg, struct pkg_create *pc, unsigned required_fla
		return (NULL);
	}

-
	if (packing_init(&pkg_archive, pkg_path, pc->format, pc->compression_level, pc->timestamp) != EPKG_OK)
+
	if (packing_init(&pkg_archive, pkg_path, pc->format,
+
	    pc->compression_level, pc->timestamp, pc->overwrite) != EPKG_OK) {
		pkg_archive = NULL;
+
	}

	free(pkg_path);

@@ -231,6 +233,7 @@ pkg_create_new(void)
	pc = xcalloc(1, sizeof(*pc));
	pc->format = TXZ;
	pc->timestamp = (time_t) -1;
+
	pc->overwrite = true;

	return (pc);
}
@@ -283,6 +286,12 @@ pkg_create_set_timestamp(struct pkg_create *pc, time_t timestamp)
	pc->timestamp = timestamp;
}

+
void
+
pkg_create_set_overwrite(struct pkg_create *pc, bool overwrite)
+
{
+
	pc->overwrite = overwrite;
+
}
+

static int
hash_file(struct pkg_create *pc, struct pkg *pkg)
{
@@ -325,6 +334,8 @@ pkg_create_i(struct pkg_create *pc, struct pkg *pkg, bool hash)

	pkg_archive = pkg_create_archive(pkg, pc, required_flags);
	if (pkg_archive == NULL) {
+
		if (errno == EEXIST)
+
			return (EPKG_EXIST);
		pkg_emit_error("unable to create archive");
		return (EPKG_FATAL);
	}
@@ -361,6 +372,12 @@ pkg_create(struct pkg_create *pc, const char *metadata, const char *plist,

	pkg_archive = pkg_create_archive(pkg, pc, 0);
	if (pkg_archive == NULL) {
+
		if (errno == EEXIST) {
+
			pkg_emit_notice("%s-%s already packaged, skipping...\n",
+
			    pkg->name, pkg->version);
+
			pkg_free(pkg);
+
			return (EPKG_EXIST);
+
		}
		pkg_free(pkg);
		return (EPKG_FATAL);
	}
modified libpkg/pkg_repo_create.c
@@ -825,7 +825,7 @@ pkg_repo_pack_db(const char *name, const char *archive, char *path,
	sig = NULL;
	pub = NULL;

-
	if (packing_init(&pack, archive, meta->packing_format, 0, (time_t)-1) != EPKG_OK)
+
	if (packing_init(&pack, archive, meta->packing_format, 0, (time_t)-1, true) != EPKG_OK)
		return (EPKG_FATAL);

	if (rsa != NULL) {
modified libpkg/private/pkg.h
@@ -333,6 +333,7 @@ struct pkg {
};

struct pkg_create {
+
	bool overwrite;
	int compression_level;
	pkg_formats format;
	time_t timestamp;
@@ -737,7 +738,7 @@ int pkg_jobs_resolv(struct pkg_jobs *jobs);

struct packing;

-
int packing_init(struct packing **pack, const char *path, pkg_formats format, int clevel, time_t timestamp);
+
int packing_init(struct packing **pack, const char *path, pkg_formats format, int clevel, time_t timestamp, bool overwrite);
int packing_append_file_attr(struct packing *pack, const char *filepath,
     const char *newpath, const char *uname, const char *gname, mode_t perm,
     u_long fflags);
modified src/create.c
@@ -77,7 +77,7 @@ usage_create(void)
static int
pkg_create_matches(int argc, char **argv, match_t match, struct pkg_create *pc)
{
-
	int i, ret = EPKG_OK, retcode = EPKG_OK;
+
	int i, ret = EPKG_OK, retcode = EXIT_SUCCESS;
	struct pkg *pkg = NULL;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
@@ -123,20 +123,24 @@ pkg_create_matches(int argc, char **argv, match_t match, struct pkg_create *pc)
		if (!foundone) {
			warnx("No installed package matching \"%s\" found\n",
			    argv[i]);
-
			retcode++;
+
			retcode = EXIT_FAILURE;
		}

		pkgdb_it_free(it);
		if (ret != EPKG_END)
-
			retcode++;
+
			retcode = EXIT_FAILURE;
	}

	DL_FOREACH_SAFE(pkg_head, e, etmp) {
		DL_DELETE(pkg_head, e);
		pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg);
-
		if (pkg_create_i(pc, e->pkg, false) !=
-
		    EPKG_OK)
-
			retcode++;
+
		ret = pkg_create_i(pc, e->pkg, false);
+
		if (ret == EPKG_EXIST) {
+
			pkg_printf("%s-%v already packaged, skipping...\n",
+
			  e->pkg, e->pkg);
+
		}
+
		if (ret != EPKG_OK && ret != EPKG_EXIST)
+
			retcode = EXIT_FAILURE;
		pkg_free(e->pkg);
		free(e);
	}
@@ -175,7 +179,9 @@ exec_create(int argc, char **argv)
	char	*endptr;
	int		 ch;
	int		 level;
+
	int		 ret;
	bool		 hash = false;
+
	bool		 overwrite = true;
	time_t		 ts = (time_t)-1;

	/* Sentinel values: INT_MIN (fast), 0 (default), INT_MAX (best). */
@@ -246,6 +252,9 @@ exec_create(int argc, char **argv)
		case 'o':
			outdir = optarg;
			break;
+
		case 'n':
+
			overwrite = false;
+
			break;
		case 'p':
			plist = optarg;
			break;
@@ -301,7 +310,7 @@ exec_create(int argc, char **argv)
			warnx("unknown format %s, using the default", format);
	}
	pkg_create_set_compression_level(pc, level);
-

+
	pkg_create_set_overwrite(pc, overwrite);
	pkg_create_set_rootdir(pc, rootdir);
	pkg_create_set_output_dir(pc, outdir);
	if (ts != (time_t)-1)
@@ -309,7 +318,10 @@ exec_create(int argc, char **argv)

	if (metadatadir == NULL && manifest == NULL)
		return (pkg_create_matches(argc, argv, match, pc) == EPKG_OK ? EX_OK : EX_SOFTWARE);
-
	return (pkg_create(pc, metadatadir != NULL ? metadatadir : manifest, plist,
-
	    hash) == EPKG_OK ? EX_OK : EX_SOFTWARE);
+
	ret = pkg_create(pc, metadatadir != NULL ? metadatadir : manifest, plist,
+
	    hash);
+
	if (ret == EPKG_EXIST || ret == EPKG_OK)
+
		return (EXIT_SUCCESS);
+
	return (EXIT_FAILURE);
}

modified tests/frontend/create.sh
@@ -18,6 +18,7 @@ tests_init \
	create_from_plist_hash \
	create_from_plist_with_keyword_and_message \
	create_with_hardlink \
+
	create_no_clobber
	time

genmanifest() {
@@ -238,7 +239,7 @@ create_from_plist_bad_fflags_body() {
	atf_check \
		-o empty \
		-e inline:"${PROGNAME}: Malformed keyword '', wrong fflags\n" \
-
		-s exit:70 \
+
		-s exit:1 \
		pkg create -o ${TMPDIR} -m . -p test.plist -r .
}

@@ -248,7 +249,7 @@ create_from_plist_with_keyword_arguments_body() {
	atf_check \
		-o empty \
		-e inline:"${PROGNAME}: cannot load keyword from ./testkeyword.ucl: No such file or directory\n${PROGNAME}: unknown keyword testkeyword: @testkeyword\n" \
-
		-s exit:70 \
+
		-s exit:1 \
		pkg -o PLIST_KEYWORDS_DIR=. create -o ${TMPDIR} -m . -p test.plist -r .

cat << EOF >> testkeyword.ucl
@@ -261,7 +262,7 @@ EOF
	atf_check \
		-o empty \
		-e inline:"${PROGNAME}: Requesting argument %2 while only 1 arguments are available\n" \
-
		-s exit:70 \
+
		-s exit:1 \
		pkg -o PLIST_KEYWORDS_DIR=. create -o ${TMPDIR} -m . -p test.plist -r .

cat << EOF > testkeyword.ucl
@@ -276,7 +277,7 @@ EOF
	atf_check \
		-o empty \
		-e inline:"${PROGNAME}: Invalid argument: expecting a number got (%1)\n" \
-
		-s exit:70 \
+
		-s exit:1 \
		pkg -o PLIST_KEYWORDS_DIR=. create -o ${TMPDIR} -m . -p test.plist -r .

cat << EOF > testkeyword.ucl
@@ -494,3 +495,14 @@ EOF
		-o match:"${pattern}" \
		ls -l ${TMPDIR}/target/${TMPDIR}/a
}
+

+
create_no_clobber_body()
+
{
+
	atf_check sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+

+
	touch test-1.txz
+
	before=$(ls -l test-1.txz)
+
	atf_check pkg create -nM test.ucl
+
	after=$(ls -l test-1.txz)
+
	[ "$before" = "$after" ] || atf_fail "Package was recreated"
+
}
modified tests/frontend/pkg.sh
@@ -70,7 +70,7 @@ EOF
	atf_check \
	    -o empty \
	    -e inline:"${PROGNAME}: Bad format in manifest for key: files\n" \
-
	    -s exit:70 \
+
	    -s exit:1 \
	    pkg create -q -m testpkg/.metadir -r testpkg
}