Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
set: allow to bulk "partial replacement"
Baptiste Daroussin committed 8 months ago
commit d59cddb437fb3dd59ed05685244750515da6a7d6
parent 01f2851
3 files changed +86 -1
modified libpkg/pkg.h.in
@@ -729,6 +729,7 @@ int pkg_config_files(const struct pkg *pkg, struct pkg_config_file **cf);

int pkg_analyse_files(struct pkgdb *, struct pkg *, const char *);

+
int pkgdb_replace(struct pkgdb *db, unsigned int field, const char *pattern, const char *replace);
int pkgdb_set2(struct pkgdb *db, struct pkg *pkg, ...);
#define pkgdb_set(db, pkg, ...) pkgdb_set2(db, pkg, __VA_ARGS__, -1)

modified libpkg/pkgdb.c
@@ -2503,6 +2503,50 @@ pkgdb_set2(struct pkgdb *db, struct pkg *pkg, ...)
	return (ret);
}

+
/*
+
 * return the number of row changed or -1 in case of sql failure, -2 in case of invalid field
+
 */
+
int
+
pkgdb_replace(struct pkgdb *db, unsigned int field, const char *pattern, const char *replace)
+
{
+
	sqlite3_stmt *stmt;
+
	char *globmatch = NULL;
+

+
	const char *sql[PKG_SET_MAX] = {
+
		[PKG_SET_NAME] = "update packages set name = replace(name, ?1, ?2) where name glob ?3",
+
		[PKG_SET_ORIGIN] = "update packages set origin = replace(origin, ?1, ?2) where origin glob ?3",
+
		[PKG_SET_DEPNAME] = "update deps set name = replace(name, ?1, ?2) where name glob '?3'",
+
		[PKG_SET_DEPORIGIN] = "update deps set origin = replace(origin, ?1, ?2) where origin glob ?3",
+
	};
+

+
	if (pattern == NULL)
+
		return (-3);
+
	if (replace == NULL)
+
		return (-4);
+
	if (field != PKG_SET_NAME && field != PKG_SET_ORIGIN &&
+
	    field != PKG_SET_DEPNAME && field != PKG_SET_DEPORIGIN) {
+
		return (-2);
+
	}
+

+
	stmt = prepare_sql(db->sqlite, sql[field]);
+
	if (stmt == NULL)
+
		return (EPKG_FATAL);
+
	sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
+
	sqlite3_bind_text(stmt, 2, replace, -1, SQLITE_STATIC);
+
	xasprintf(&globmatch, "*%s*", pattern);
+
	sqlite3_bind_text(stmt, 2, globmatch, -1, SQLITE_STATIC);
+
	pkgdb_debug(4, stmt);
+
	if (sqlite3_step(stmt) != SQLITE_DONE) {
+
		free(globmatch);
+
		ERROR_STMT_SQLITE(db->sqlite, stmt);
+
		sqlite3_finalize(stmt);
+
		return (-1);
+
	}
+
	free(globmatch);
+
	sqlite3_finalize(stmt);
+
	return (sqlite3_changes(db->sqlite));
+
}
+

int
pkgdb_file_set_cksum(struct pkgdb *db, struct pkg_file *file,
     const char *sum)
modified src/set.c
@@ -108,6 +108,7 @@ exec_set(int argc, char **argv)
	unsigned int	 sets = 0;
	unsigned int	 field = 0, depfield = 0;
	int		 retcode;
+
	bool partial = false;

	struct option longopts[] = {
		{ "automatic",		required_argument,	NULL,	'A' },
@@ -116,6 +117,7 @@ exec_set(int argc, char **argv)
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "change-origin",	required_argument,	NULL,	'o' },
+
		{ "partial",		no_argument,		NULL,	'p' },
		{ "change-name",	required_argument,	NULL,	'n' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "vital",		required_argument,	NULL,	'v' },
@@ -123,7 +125,7 @@ exec_set(int argc, char **argv)
		{ NULL,			0,			NULL,	0   },
	};

-
	while ((ch = getopt_long(argc, argv, "+A:aCgio:xyn:v:", longopts, NULL)) != -1) {
+
	while ((ch = getopt_long(argc, argv, "+A:aCgio:pxyn:v:", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
			sets |= AUTOMATIC;
@@ -181,6 +183,9 @@ exec_set(int argc, char **argv)
		case 'y':
			yes = true;
			break;
+
		case 'p':
+
			partial = true;
+
			break;
		default:
			free(oldvalue);
			free(newvalue);
@@ -208,6 +213,11 @@ exec_set(int argc, char **argv)
		field = PKG_SET_ORIGIN;
		depfield = PKG_SET_DEPORIGIN;
	}
+
	if (partial && ((sets & (NAME|ORIGIN)) == 0)) {
+
		warnx("-p requires either -o or -n option)");
+
		usage_set();
+
		return (EXIT_FAILURE);
+
	}

	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
			       PKGDB_DB_LOCAL);
@@ -247,6 +257,36 @@ exec_set(int argc, char **argv)
		return (EXIT_FAILURE);
	}

+
	if (partial) {
+
		int cnt, cntdep;
+
		rc = yes;
+
		if (!yes)
+
			rc = query_yesno(false, "Do you want to batch replace '%S' in package %S with '%S'?",
+
			    oldvalue, changed, newvalue);
+
		if (!rc) {
+
			retcode = EXIT_SUCCESS;
+
			goto cleanup;
+
		}
+
		cnt = pkgdb_replace(db, field, oldvalue, newvalue);
+
		if (cnt < 0) {
+
			retcode = EXIT_FAILURE;
+
			goto cleanup;
+
		} else if (cnt == 0) {
+
			if (!quiet)
+
				warnx("No packages renamed.");
+
			retcode = EXIT_FAILURE;
+
			goto cleanup;
+
		}
+
		cntdep = pkgdb_replace(db, depfield, oldvalue, newvalue);
+
		if (cntdep < 0) {
+
			retcode = EXIT_FAILURE;
+
			goto cleanup;
+
		}
+
		if (!quiet)
+
			printf("%d packages have been renamed.\n", cnt);
+
		retcode = EXIT_SUCCESS;
+
		goto cleanup;
+
	}

	if (oldvalue != NULL) {
		match = MATCH_ALL;