[pacman-dev] [PATCH 1/2] Document pacman -F
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- doc/pacman.8.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 5c57450..a4dd1f0 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,11 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files. +*-F, \--files*:: + Query the files database. This operation allows you to look for package + owning certain files or display files owned by certain packages. See + <<FO,File Options>> below. + *-V, \--version*:: Display version and exit. @@ -451,6 +456,23 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available. +File Options[[FO]] +------------------ + +The '--list', '--search' and '--owns' options are exclusive and can not be combined. + +*-l <package>, \--list <package>*:: + List the files owned by the queried package. + +*-s <pattern>, \--search <pattern>*:: + Search package file names for matching strings. + +*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o <file>, \--owns<file>*:: + Search for packages that own a particular file. + Handling Config Files[[HCF]] ---------------------------- -- 2.6.2
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- doc/pacman.8.txt | 4 +++ src/pacman/conf.h | 2 ++ src/pacman/files.c | 70 ++++++++++++++++++++++++++++++++++++++--------------- src/pacman/pacman.c | 6 +++++ 4 files changed, 63 insertions(+), 19 deletions(-) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index a4dd1f0..8aff288 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -473,6 +473,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 feda75d..33825df 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -27,6 +27,15 @@ #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); + const char *root = alpm_option_get_root(config->handle); + for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) { + const alpm_file_t *file = pkgfiles->files + filenum; + printf("%s/%s %s %s%s\n", alpm_db_get_name(db), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg), root, file->name); + } +} static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) { int ret = 0; @@ -59,13 +68,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 +150,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); } } } @@ -200,8 +222,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_pkg_files(pkg, config->quiet); - break; + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + // list all repos if not asked for a specific one + continue; + } else { + dump_pkg_files(pkg, config->quiet); + break; + } } } if(!found) { @@ -218,7 +246,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_pkg_files(pkg, config->quiet); + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + } else { + dump_pkg_files(pkg, config->quiet); + } } } } 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
On Sun, Oct 25, 2015 at 04:30:00PM +0100, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- doc/pacman.8.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 5c57450..a4dd1f0 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,11 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files.
+*-F, \--files*:: + Query the files database. This operation allows you to look for package + owning certain files or display files owned by certain packages. See + <<FO,File Options>> below. + *-V, \--version*:: Display version and exit.
@@ -451,6 +456,23 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available.
+File Options[[FO]] +------------------ + +The '--list', '--search' and '--owns' options are exclusive and can not be combined. +
-y, --refresh
+*-l <package>, \--list <package>*:: + List the files owned by the queried package. + +*-s <pattern>, \--search <pattern>*:: + Search package file names for matching strings. + +*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o <file>, \--owns<file>*:: + Search for packages that own a particular file. +
Handling Config Files[[HCF]] ---------------------------- -- 2.6.2
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- v2: - Document --refresh doc/pacman.8.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 5c57450..38b8bb7 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,11 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files. +*-F, \--files*:: + Query the files database. This operation allows you to look for package + owning certain files or display files owned by certain packages. See + <<FO,File Options>> below. + *-V, \--version*:: Display version and exit. @@ -451,6 +456,27 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available. +File Options[[FO]] +------------------ + +The '--list', '--search' and '--owns' options are exclusive and can not be combined. + +*-y, --refresh*:: + Download fresh package databases from the server. Use twice to force a + refresh even if databases are up to date. + +*-l <package>, \--list <package>*:: + List the files owned by the queried package. + +*-s <pattern>, \--search <pattern>*:: + Search package file names for matching strings. + +*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o <file>, \--owns<file>*:: + Search for packages that own a particular file. + Handling Config Files[[HCF]] ---------------------------- -- 2.6.2
Signed-off-by: Florian Pritz <bluewind@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
On 10/25/15 at 05:07pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@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'.
Spaces are not really reliable field separators. Every single field being printed is allowed to contain spaces by alpm/pacman.
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)); + }
No need to nest this if, make it part of the outer conditional.
}
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); }
Same for this one.
- FREELIST(match);
match needs to be free'd any time it's not NULL, this needs to be moved to the outer block.
} } } @@ -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
I don't like having the machine readable format printing a different set of packages than the normal format.
+ continue;
Unnecessary 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
On Sun, 25 Oct 2015 14:14:49 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
On 10/25/15 at 05:07pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@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'.
Spaces are not really reliable field separators. Every single field being printed is allowed to contain spaces by alpm/pacman.
What is then? Best I see is that man PKGBUILD exclude hyphens for pkgname, pkgver, pkgrel, but obviously it doesn't say anything about repo names. I would not have expected a space to be allowed in those though. Is that intentional or should we maybe exclude it too?
@@ -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
I don't like having the machine readable format printing a different set of packages than the normal format.
My format includes the repo so a user can easily tell when lines appear multiple times why that happens while this is not possible with the normal format. I don't care too much about this though. Allan, Dave?
+ continue;
Unnecessary continue.
Given the else uses break it seems more readable to be me include the continue so that the intention is clear. Allan, Dave? I've fixed the other stuff you mentioned and will send a new patch once the questions above are cleared.
On 27/10/15 20:10, Florian Pritz wrote:
On Sun, 25 Oct 2015 14:14:49 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
On 10/25/15 at 05:07pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@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'.
Spaces are not really reliable field separators. Every single field being printed is allowed to contain spaces by alpm/pacman.
What is then? Best I see is that man PKGBUILD exclude hyphens for pkgname, pkgver, pkgrel, but obviously it doesn't say anything about repo names. I would not have expected a space to be allowed in those though. Is that intentional or should we maybe exclude it too?
pkgname and pkgrel can not contain spaces according to makepkg. I believe pacman will handle packages with them just fine though. pkgver works with a space.
@@ -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
I don't like having the machine readable format printing a different set of packages than the normal format.
My format includes the repo so a user can easily tell when lines appear multiple times why that happens while this is not possible with the normal format. I don't care too much about this though. Allan, Dave?
I'm failure sure I said the same as Andrew with an earlier iteratino on IRC earlier.
+ continue;
Unnecessary continue.
Given the else uses break it seems more readable to be me include the continue so that the intention is clear. Allan, Dave?
I've fixed the other stuff you mentioned and will send a new patch once the questions above are cleared.
Not needed anyway if only one package is printed. A
On 27/10/15 20:27, Allan McRae wrote:
On 27/10/15 20:10, Florian Pritz wrote:
On Sun, 25 Oct 2015 14:14:49 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
On 10/25/15 at 05:07pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@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'.
Spaces are not really reliable field separators. Every single field being printed is allowed to contain spaces by alpm/pacman.
What is then? Best I see is that man PKGBUILD exclude hyphens for pkgname, pkgver, pkgrel, but obviously it doesn't say anything about repo names. I would not have expected a space to be allowed in those though. Is that intentional or should we maybe exclude it too?
pkgname and pkgrel can not contain spaces according to makepkg. I believe pacman will handle packages with them just fine though. pkgver works with a space.
And pkgver allowing a space was a mistake in libmakepkg... Allan
On 10/27/15 at 08:27pm, Allan McRae wrote:
On 27/10/15 20:10, Florian Pritz wrote:
On Sun, 25 Oct 2015 14:14:49 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
On 10/25/15 at 05:07pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@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'.
Spaces are not really reliable field separators. Every single field being printed is allowed to contain spaces by alpm/pacman.
What is then? Best I see is that man PKGBUILD exclude hyphens for pkgname, pkgver, pkgrel, but obviously it doesn't say anything about repo names. I would not have expected a space to be allowed in those though. Is that intentional or should we maybe exclude it too?
pkgname and pkgrel can not contain spaces according to makepkg. I believe pacman will handle packages with them just fine though. pkgver works with a space.
makepkg may be the official method of building packages, but it is certainly not the only way to build one, so I don't consider its limitations particularly relevant here. If the goal is to provide an output format that programs can reliably parse it should work with the full range of values supported by alpm/pacman. alpm only restricts <repo> to characters legal in a file name; they can even contain newlines, although pacman doesn't support repos with newlines. <pkgname> and <pkgver> are similarly limited to file-name-legal characters, but they cannot contain newlines. Paths can, of course, contain any path-legal character except newlines. If you want to provide this level of detail in a reliable machine-readable format, the only characters you can rely on for field/record separators are '/', '\n', and '\0'. apg
On 26/10/15 02:06, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@xinu.at> ---
v2: - Document --refresh
doc/pacman.8.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 5c57450..38b8bb7 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,11 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files.
+*-F, \--files*:: + Query the files database. This operation allows you to look for package + owning certain files or display files owned by certain packages. See + <<FO,File Options>> below. + *-V, \--version*:: Display version and exit.
@@ -451,6 +456,27 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available.
+File Options[[FO]] +------------------ + +The '--list', '--search' and '--owns' options are exclusive and can not be combined.
I first read that as --list can not be combined with anything else (e.g. --refresh). I also note that we do not do that for any other option, so is it fine just to delete this line?
+ +*-y, --refresh*:: + Download fresh package databases from the server. Use twice to force a + refresh even if databases are up to date. + +*-l <package>, \--list <package>*:: + List the files owned by the queried package. + +*-s <pattern>, \--search <pattern>*:: + Search package file names for matching strings. + +*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o <file>, \--owns<file>*:: + Search for packages that own a particular file. +
Handling Config Files[[HCF]] ----------------------------
On Wed, 28 Oct 2015 13:17:27 +1000 Allan McRae <allan@archlinux.org> wrote:
+The '--list', '--search' and '--owns' options are exclusive and can not be combined.
I first read that as --list can not be combined with anything else (e.g. --refresh). I also note that we do not do that for any other option, so is it fine just to delete this line?
Deleted and pushed to my working branch.
On 10/25/15 at 05:06pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@xinu.at> ---
v2: - Document --refresh
doc/pacman.8.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 5c57450..38b8bb7 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,11 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files.
+*-F, \--files*:: + Query the files database. This operation allows you to look for package + owning certain files or display files owned by certain packages. See + <<FO,File Options>> below.
This should mention somewhere that this is for sync databases.
*-V, \--version*:: Display version and exit.
@@ -451,6 +456,27 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available.
+File Options[[FO]] +------------------ + +The '--list', '--search' and '--owns' options are exclusive and can not be combined. + +*-y, --refresh*:: + Download fresh package databases from the server. Use twice to force a + refresh even if databases are up to date. + +*-l <package>, \--list <package>*:: + List the files owned by the queried package.
None of our other options repeat the argument name for both the short and long forms of an option. Unfortunately, our man page is inconsistent as to when the argument name is included at all. Since '<package>' isn't actually an argument to '--list' and '--list' doesn't actually require any targets I would say to just omit it entirely.
+*-s <pattern>, \--search <pattern>*:: + Search package file names for matching strings.
Same as above. It makes a little more sense to include an argument name here since this option does at least require targets, but --search doesn't really take a pattern; it only compares the target to the file basename and requires an exact match.
+*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o <file>, \--owns<file>*:: + Search for packages that own a particular file.
Same as above, and you're missing a space after --owns.
Handling Config Files[[HCF]] ---------------------------- -- 2.6.2
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- v3: - Change output format to use \0 as field separator. - Only output one repo for -Fl - Combine else if - Fix incorrect placement of FREELIST(match) doc/pacman.8.txt | 5 +++++ src/pacman/conf.h | 2 ++ src/pacman/files.c | 46 ++++++++++++++++++++++++++++++++++++++++------ src/pacman/pacman.c | 6 ++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 57929b4..1df7980 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -477,6 +477,11 @@ 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\0pkgname\0pkgver\0path\n' with '\0' + being the NULL character and '\n' a linefeed. + Handling Config Files[[HCF]] ---------------------------- diff --git a/src/pacman/conf.h b/src/pacman/conf.h index cde6741..7a7e9cf 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -90,6 +90,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; @@ -192,6 +193,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..18fd763 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -27,6 +27,25 @@ #include "conf.h" #include "package.h" +static void print_line_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, char *filename) { + // Fields are repo, pkgname, pkgver, filename separated with \0 + fputs(alpm_db_get_name(db), stdout); + fputc(0, stdout); + fputs(alpm_pkg_get_name(pkg), stdout); + fputc(0, stdout); + fputs(alpm_pkg_get_version(pkg), stdout); + fputc(0, stdout); + fputs(filename, stdout); + fputs("\n", stdout); +} + +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; + print_line_machinereadable(db, pkg, file->name); + } +} static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) { int ret = 0; @@ -59,8 +78,9 @@ 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) { + if(config->op_f_machinereadable) { + print_line_machinereadable(repo, pkg, f); + } else 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)); @@ -137,7 +157,13 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { } if(match != NULL) { - if(config->quiet) { + if(config->op_f_machinereadable) { + alpm_list_t *ml; + for(ml = match; ml; ml = alpm_list_next(ml)) { + char *filename = ml->data; + print_line_machinereadable(repo, 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; @@ -149,8 +175,8 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { c = ml->data; printf(" %s\n", c); } - FREELIST(match); } + FREELIST(match); } } } @@ -222,7 +248,11 @@ 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); + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + } else { + dump_file_list(pkg); + } break; } } @@ -240,7 +270,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 d777663..ad90ee6 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: @@ -796,6 +798,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; @@ -945,6 +950,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
On 10/27/15 at 11:24pm, Florian Pritz wrote:
Signed-off-by: Florian Pritz <bluewind@xinu.at> ---
v3: - Change output format to use \0 as field separator. - Only output one repo for -Fl - Combine else if - Fix incorrect placement of FREELIST(match)
doc/pacman.8.txt | 5 +++++ src/pacman/conf.h | 2 ++ src/pacman/files.c | 46 ++++++++++++++++++++++++++++++++++++++++------ src/pacman/pacman.c | 6 ++++++ 4 files changed, 53 insertions(+), 6 deletions(-)
Aside from a few style nitpicks, the code looks fine. I am curious as to the motivation for this though. Most of our operations are made easier to parse by using --quiet to reduce the output to a single field. Do you have a use case in mind for this that wouldn't be taken care of by adding a --quiet option to -F or intend to add --machinereadable to other operations?
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 57929b4..1df7980 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -477,6 +477,11 @@ 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\0pkgname\0pkgver\0path\n' with '\0' + being the NULL character and '\n' a linefeed. +
Handling Config Files[[HCF]] ---------------------------- diff --git a/src/pacman/conf.h b/src/pacman/conf.h index cde6741..7a7e9cf 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -90,6 +90,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; @@ -192,6 +193,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..18fd763 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -27,6 +27,25 @@ #include "conf.h" #include "package.h"
+static void print_line_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, char *filename) {
Opening brace on its own line.
+ // Fields are repo, pkgname, pkgver, filename separated with \0
C89-style comment.
+ fputs(alpm_db_get_name(db), stdout); + fputc(0, stdout); + fputs(alpm_pkg_get_name(pkg), stdout); + fputc(0, stdout); + fputs(alpm_pkg_get_version(pkg), stdout); + fputc(0, stdout); + fputs(filename, stdout); + fputs("\n", stdout); +} + +static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg) {
Opening brace on its own line.
+ 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; + print_line_machinereadable(db, pkg, file->name); + } +}
static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) { int ret = 0; @@ -59,8 +78,9 @@ 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) { + if(config->op_f_machinereadable) { + print_line_machinereadable(repo, pkg, f); + } else 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)); @@ -137,7 +157,13 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { }
if(match != NULL) { - if(config->quiet) { + if(config->op_f_machinereadable) { + alpm_list_t *ml; + for(ml = match; ml; ml = alpm_list_next(ml)) { + char *filename = ml->data; + print_line_machinereadable(repo, 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; @@ -149,8 +175,8 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { c = ml->data; printf(" %s\n", c); } - FREELIST(match); } + FREELIST(match); } } } @@ -222,7 +248,11 @@ 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); + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + } else { + dump_file_list(pkg); + } break; } } @@ -240,7 +270,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 d777663..ad90ee6 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: @@ -796,6 +798,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; @@ -945,6 +950,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
On Fri, 30 Oct 2015 13:59:53 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
Aside from a few style nitpicks, the code looks fine. I am curious as to the motivation for this though. Most of our operations are made easier to parse by using --quiet to reduce the output to a single field. Do you have a use case in mind for this that wouldn't be taken care of by adding a --quiet option to -F or intend to add --machinereadable to other operations?
Depending on what you want at least -Fs produces some very hard to parse output as you can see here:
src/pacman/pacman -Fs makepkg core/pacman 4.2.1-4 usr/bin/makepkg usr/share/bash-completion/completions/makepkg community/libreoffice-extension-texmaths 0.41-2 usr/lib/libreoffice/share/extensions/texmaths/makepkg community/plan9port 20150629-1 usr/lib/plan9/.git/logs/refs/heads/makepkg usr/lib/plan9/.git/refs/heads/makepkg
-Fqs is easier to parse but provides only very limited information:
src/pacman/pacman -Fqs makepkg core/pacman community/libreoffice-extension-texmaths community/plan9port
Also the format is not consistent across -F operations so any code that parses one format can not be used for the others which seems unnecessary. I brought this up when Allan created the feature and he asked me to create a dedicated switch so I did. If you know of any operations that could benefit from such an option I might consider implementing it, however, expac already covers most of the normal stuff and I don't know if pacman can do a better job there. I certainly can with the -F operations. I fixed the style issues and the subject typo mentioned by Pierre in my branch.
On 10/30/15 at 07:32pm, Florian Pritz wrote:
On Fri, 30 Oct 2015 13:59:53 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
Aside from a few style nitpicks, the code looks fine. I am curious as to the motivation for this though. Most of our operations are made easier to parse by using --quiet to reduce the output to a single field. Do you have a use case in mind for this that wouldn't be taken care of by adding a --quiet option to -F or intend to add --machinereadable to other operations?
Depending on what you want at least -Fs produces some very hard to parse output as you can see here:
src/pacman/pacman -Fs makepkg core/pacman 4.2.1-4 usr/bin/makepkg usr/share/bash-completion/completions/makepkg community/libreoffice-extension-texmaths 0.41-2 usr/lib/libreoffice/share/extensions/texmaths/makepkg community/plan9port 20150629-1 usr/lib/plan9/.git/logs/refs/heads/makepkg usr/lib/plan9/.git/refs/heads/makepkg
-Fqs is easier to parse but provides only very limited information:
src/pacman/pacman -Fqs makepkg core/pacman community/libreoffice-extension-texmaths community/plan9port
Also the format is not consistent across -F operations so any code that parses one format can not be used for the others which seems unnecessary.
I brought this up when Allan created the feature and he asked me to create a dedicated switch so I did. If you know of any operations that could benefit from such an option I might consider implementing it, however, expac already covers most of the normal stuff and I don't know if pacman can do a better job there. I certainly can with the -F operations.
I fixed the style issues and the subject typo mentioned by Pierre in my branch.
It is certainly true that getting detailed information out of pacman in a way that's easy to parse is non-trivial. But, that's true across all of our operations. Really, very little of pacman's output can be reliably parsed without --quiet and I doubt anybody who isn't a pacman developer would know all of the caveats to do so (even our own scripts are unreliable). My personal preference would be for people to use --quiet (which needs to be added to -Fh BTW) and separately request any additional detail they need. But, maybe adding this will get people to stop trying to parse output that is not meant to parsed, so I'm neutral on this change. If we do go this route though, I'd like to see it implemented for other operations (the other --search operations are the most obvious candidates), but that doesn't need to be part of this patch, of course. apg
On 31/10/15 05:08, Andrew Gregory wrote:
On 10/30/15 at 07:32pm, Florian Pritz wrote:
On Fri, 30 Oct 2015 13:59:53 -0400 Andrew Gregory <andrew.gregory.8@gmail.com> wrote:
Aside from a few style nitpicks, the code looks fine. I am curious as to the motivation for this though. Most of our operations are made easier to parse by using --quiet to reduce the output to a single field. Do you have a use case in mind for this that wouldn't be taken care of by adding a --quiet option to -F or intend to add --machinereadable to other operations?
Depending on what you want at least -Fs produces some very hard to parse output as you can see here:
src/pacman/pacman -Fs makepkg core/pacman 4.2.1-4 usr/bin/makepkg usr/share/bash-completion/completions/makepkg community/libreoffice-extension-texmaths 0.41-2 usr/lib/libreoffice/share/extensions/texmaths/makepkg community/plan9port 20150629-1 usr/lib/plan9/.git/logs/refs/heads/makepkg usr/lib/plan9/.git/refs/heads/makepkg
-Fqs is easier to parse but provides only very limited information:
src/pacman/pacman -Fqs makepkg core/pacman community/libreoffice-extension-texmaths community/plan9port
Also the format is not consistent across -F operations so any code that parses one format can not be used for the others which seems unnecessary.
I brought this up when Allan created the feature and he asked me to create a dedicated switch so I did. If you know of any operations that could benefit from such an option I might consider implementing it, however, expac already covers most of the normal stuff and I don't know if pacman can do a better job there. I certainly can with the -F operations.
I fixed the style issues and the subject typo mentioned by Pierre in my branch.
It is certainly true that getting detailed information out of pacman in a way that's easy to parse is non-trivial. But, that's true across all of our operations. Really, very little of pacman's output can be reliably parsed without --quiet and I doubt anybody who isn't a pacman developer would know all of the caveats to do so (even our own scripts are unreliable).
My personal preference would be for people to use --quiet (which needs to be added to -Fh BTW) and separately request any additional detail they need. But, maybe adding this will get people to stop trying to parse output that is not meant to parsed, so I'm neutral on this change. If we do go this route though, I'd like to see it implemented for other operations (the other --search operations are the most obvious candidates), but that doesn't need to be part of this patch, of course.
I saw this as something that could be expanded in the future, so adding to -F was a first step. A
My guess you meant '--machinereadable' in the commit subject ;) -- Pierre Neidhardt All people are born alike -- except Republicans and Democrats. -- Groucho Marx
Signed-off-by: Florian Pritz <bluewind@xinu.at> --- v4: - Mention that onyl sync dbs are searched - Add --quiet doc/pacman.8.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 18303c3..838b70b 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -110,6 +110,12 @@ greater than `1:3.6-1`. Options>> below; also see <<HCF,Handling Config Files>> for an explanation on how pacman takes care of configuration files. +*-F, \--files*:: + Query the files database. This operation allows you to look for packages + owning certain files or display files owned by certain packages. Only + packages that are part of your sync databases are searched. See + <<FO,File Options>> below. + *-V, \--version*:: Display version and exit. @@ -451,6 +457,29 @@ Database Options[[QO]] a check on the sync databases to ensure all specified dependencies are available. +File Options[[FO]] +------------------ + +*-y, --refresh*:: + Download fresh package databases from the server. Use twice to force a + refresh even if databases are up to date. + +*-l, \--list*:: + List the files owned by the queried package. + +*-s, \--search*:: + Search package file names for matching strings. + +*-x, --regex*:: + Treat arguments to '--search' as regular expressions. + +*-o, \--owns*:: + Search for packages that own a particular file. + +*-q, \--quiet*:: + Show less information for certain file operations. This is useful when + pacman's output is processed in a script, however, you may want to use + '--machinereadable' instead. Handling Config Files[[HCF]] ---------------------------- -- 2.6.2
participants (5)
-
Allan McRae
-
Andrew Gregory
-
Florian Pritz
-
Mohammad_AlSaleh
-
Pierre Neidhardt