[pacman-dev] [PATCH v2 2/2] Add -F --machinereable option

Florian Pritz bluewind at xinu.at
Sun Oct 25 16:07:00 UTC 2015


Signed-off-by: Florian Pritz <bluewind at xinu.at>
---

v2:
 - Always output paths without leading slash

 doc/pacman.8.txt    |  4 ++++
 src/pacman/conf.h   |  2 ++
 src/pacman/files.c  | 69 ++++++++++++++++++++++++++++++++++++++---------------
 src/pacman/pacman.c |  6 +++++
 4 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 38b8bb7..1f11cf3 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -477,6 +477,10 @@ The '--list', '--search' and '--owns' options are exclusive and can not be combi
 *-o <file>, \--owns<file>*::
 	Search for packages that own a particular file.
 
+*--machinereadable*::
+	Use a machine readable output format for '--list', '--search' and
+	'--owns'. The format is 'repository/pkgname pkgver path'.
+
 
 Handling Config Files[[HCF]]
 ----------------------------
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 3fff900..1760b07 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -89,6 +89,7 @@ typedef struct __config_t {
 	unsigned short op_s_upgrade;
 
 	unsigned short op_f_regex;
+	unsigned short op_f_machinereadable;
 
 	unsigned short group;
 	unsigned short noask;
@@ -190,6 +191,7 @@ enum {
 	OP_RECURSIVE,
 	OP_SEARCH,
 	OP_REGEX,
+	OP_MACHINEREADABLE,
 	OP_UNREQUIRED,
 	OP_UPGRADES,
 	OP_SYSUPGRADE,
diff --git a/src/pacman/files.c b/src/pacman/files.c
index 31ce9e0..b21503a 100644
--- a/src/pacman/files.c
+++ b/src/pacman/files.c
@@ -27,6 +27,14 @@
 #include "conf.h"
 #include "package.h"
 
+static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg) {
+	alpm_filelist_t *pkgfiles = alpm_pkg_get_files(pkg);
+	for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) {
+		const alpm_file_t *file = pkgfiles->files + filenum;
+		printf("%s/%s %s %s\n", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
+				alpm_pkg_get_version(pkg), file->name);
+	}
+}
 
 static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) {
 	int ret = 0;
@@ -59,13 +67,17 @@ static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) {
 				alpm_filelist_t *files = alpm_pkg_get_files(pkg);
 
 				if(alpm_filelist_contains(files, f)) {
-
-					if(!config->quiet) {
-						printf(_("%s is owned by %s/%s %s\n"), f,
-								alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
-								alpm_pkg_get_version(pkg));
+					if(config->op_f_machinereadable) {
+						printf("%s/%s %s %s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
+								alpm_pkg_get_version(pkg), f);
 					} else {
-						printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
+						if(!config->quiet) {
+							printf(_("%s is owned by %s/%s %s\n"), f,
+									alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
+									alpm_pkg_get_version(pkg));
+						} else {
+							printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
+						}
 					}
 
 					found = 1;
@@ -137,19 +149,28 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
 				}
 
 				if(match != NULL) {
-					if(config->quiet) {
-						printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
-					} else {
+					if(config->op_f_machinereadable) {
 						alpm_list_t *ml;
-						printf("%s%s/%s%s %s%s%s\n", colstr->repo, alpm_db_get_name(repo),
-							colstr->title, alpm_pkg_get_name(pkg),
-							colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor);
-
 						for(ml = match; ml; ml = alpm_list_next(ml)) {
-							c = ml->data;
-							printf("    %s\n", c);
+							char *filename = ml->data;
+							printf("%s/%s %s %s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
+									alpm_pkg_get_version(pkg), filename);
+						}
+					} else {
+						if(config->quiet) {
+							printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
+						} else {
+							alpm_list_t *ml;
+							printf("%s%s/%s%s %s%s%s\n", colstr->repo, alpm_db_get_name(repo),
+								colstr->title, alpm_pkg_get_name(pkg),
+								colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor);
+
+							for(ml = match; ml; ml = alpm_list_next(ml)) {
+								c = ml->data;
+								printf("    %s\n", c);
+							}
+							FREELIST(match);
 						}
-						FREELIST(match);
 					}
 				}
 			}
@@ -222,8 +243,14 @@ static int files_list(alpm_list_t *syncs, alpm_list_t *targets) {
 
 				if((pkg = alpm_db_get_pkg(db, targ)) != NULL) {
 					found = 1;
-					dump_file_list(pkg);
-					break;
+					if(config->op_f_machinereadable) {
+						dump_pkg_machinereadable(db, pkg);
+						// list all repos if not asked for a specific one
+						continue;
+					} else {
+						dump_file_list(pkg);
+						break;
+					}
 				}
 			}
 			if(!found) {
@@ -240,7 +267,11 @@ static int files_list(alpm_list_t *syncs, alpm_list_t *targets) {
 
 			for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
 				alpm_pkg_t *pkg = j->data;
-				dump_file_list(pkg);
+				if(config->op_f_machinereadable) {
+					dump_pkg_machinereadable(db, pkg);
+				} else {
+					dump_file_list(pkg);
+				}
 			}
 		}
 	}
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index c680067..0bb1b39 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -181,6 +181,8 @@ static void usage(int op, const char * const myname)
 			addlist(_("  -x, --regex          enable searching using regular expressions\n"));
 			addlist(_("  -y, --refresh        download fresh package databases from the server\n"
 			          "                       (-yy to force a refresh even if up to date)\n"));
+			addlist(_("      --machinereadable\n"
+			          "                       produce machine-readable output\n"));
 		}
 		switch(op) {
 			case PM_OP_SYNC:
@@ -792,6 +794,9 @@ static int parsearg_files(int opt)
 		case 'x':
 			config->op_f_regex = 1;
 			break;
+		case OP_MACHINEREADABLE:
+			config->op_f_machinereadable = 1;
+			break;
 		case OP_QUIET:
 		case 'q':
 			config->quiet = 1;
@@ -941,6 +946,7 @@ static int parseargs(int argc, char *argv[])
 		{"recursive",  no_argument,       0, OP_RECURSIVE},
 		{"search",     no_argument,       0, OP_SEARCH},
 		{"regex",      no_argument,       0, OP_REGEX},
+		{"machinereadable",      no_argument,       0, OP_MACHINEREADABLE},
 		{"unrequired", no_argument,       0, OP_UNREQUIRED},
 		{"upgrades",   no_argument,       0, OP_UPGRADES},
 		{"sysupgrade", no_argument,       0, OP_SYSUPGRADE},
-- 
2.6.2


More information about the pacman-dev mailing list