Add new --print operation for all operations

And a new --print-format option to configure the output.

This implements FS#14208

Example usage :
pacman -Sp --print-format "%r/%n-%v : %l [%s]" kdelibs
extra/kdelibs-4.3.2-4 : ftp://mir2.archlinuxfr.org/archlinux/extra/os/i686/kdelibs-4.3.2-4-i686.pkg.tar.gz [0,00]

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Xavier Chantry 2009-07-19 11:15:11 +02:00 committed by Dan McGee
parent 67700b926a
commit d39b1dbe62
11 changed files with 170 additions and 47 deletions

View file

@ -167,7 +167,7 @@ _pacman ()
groups) mod="${mod}g" ;; groups) mod="${mod}g" ;;
info) mod="${mod}i" ;; info) mod="${mod}i" ;;
list) mod="${mod}l" ;; list) mod="${mod}l" ;;
print-uris) mod="${mod}p" ;; print) mod="${mod}p" ;;
search) mod="${mod}s" ;; search) mod="${mod}s" ;;
sysupgrade) mod="${mod}u" ;; sysupgrade) mod="${mod}u" ;;
upgrades) mod="${mod}u" ;; upgrades) mod="${mod}u" ;;
@ -231,6 +231,8 @@ _pacman ()
-v --verbose \ -v --verbose \
-r --root \ -r --root \
-b --dbpath \ -b --dbpath \
-p --print \
--print-format \
--cachedir \ --cachedir \
' -- $cur ) ) ' -- $cur ) )
return 0 return 0
@ -252,6 +254,8 @@ _pacman ()
-v --verbose \ -v --verbose \
-r --root \ -r --root \
-b --dbpath \ -b --dbpath \
-p --print \
--print-format \
--cachedir \ --cachedir \
' -- $cur ) ) ' -- $cur ) )
return 0 return 0
@ -267,7 +271,6 @@ _pacman ()
-h --help \ -h --help \
-i --info \ -i --info \
-l --list \ -l --list \
-p --print-uris \
-s --search \ -s --search \
-u --sysupgrade \ -u --sysupgrade \
-w --downloadonly \ -w --downloadonly \
@ -283,6 +286,8 @@ _pacman ()
-v --verbose \ -v --verbose \
-r --root \ -r --root \
-b --dbpath \ -b --dbpath \
-p --print \
--print-format \
--cachedir \ --cachedir \
' -- $cur ) ) ' -- $cur ) )
return 0 return 0

View file

@ -26,6 +26,7 @@ _pacman_opts_common=(
'--noconfirm[Do not ask for confirmation]' '--noconfirm[Do not ask for confirmation]'
'--noprogressbar[Do not show a progress bar when downloading files]' '--noprogressbar[Do not show a progress bar when downloading files]'
'--noscriptlet[Do not execute the install scriptlet if one exists]' '--noscriptlet[Do not execute the install scriptlet if one exists]'
'--print[Only print the targets instead of performing the operation]'
) )
# options for passing to _arguments: options for --upgrade commands # options for passing to _arguments: options for --upgrade commands

View file

@ -170,6 +170,17 @@ Options
*\--arch* <'arch'>:: *\--arch* <'arch'>::
Specify an alternate architecture. Specify an alternate architecture.
*-p, \--print*::
Only print the targets instead of performing the actual operation (sync,
remove or upgrade). Use '\--print-format' to specify how targets are
displayed. The default format string is "%l", which displays url with '-S',
filename with '-U' and pkgname-pkgver with '-R'.
*\--print-format* <'format'>::
Specify a printf-like format to control the output of the '\--print'
operation. The possible are attributes are : %n for pkgname, %v for pkgver, %l
for location, %r for repo and %s for size.
Query Options[[QO]] Query Options[[QO]]
------------------- -------------------
*-c, \--changelog*:: *-c, \--changelog*::
@ -306,11 +317,6 @@ linkman:pacman.conf[5].
List all packages in the specified repositories. Multiple repositories List all packages in the specified repositories. Multiple repositories
can be specified on the command line. can be specified on the command line.
*-p, \--print-uris*::
Print out URIs for each package that will be installed, including any
dependencies yet to be installed. These can be piped to a file and
downloaded at a later time, using a program like wget.
*-q, \--quiet*:: *-q, \--quiet*::
Show less information for certain sync operations. (This is useful when Show less information for certain sync operations. (This is useful when
pacman's output is processed in a script.) Search will only show package pacman's output is processed in a script.) Search will only show package

View file

@ -62,6 +62,7 @@ int config_free(config_t *oldconfig)
free(oldconfig->dbpath); free(oldconfig->dbpath);
free(oldconfig->logfile); free(oldconfig->logfile);
free(oldconfig->xfercommand); free(oldconfig->xfercommand);
free(oldconfig->print_format);
free(oldconfig); free(oldconfig);
oldconfig = NULL; oldconfig = NULL;

View file

@ -31,6 +31,8 @@ typedef struct __config_t {
unsigned short noconfirm; unsigned short noconfirm;
unsigned short noprogressbar; unsigned short noprogressbar;
unsigned short logmask; unsigned short logmask;
unsigned short print;
char *print_format;
/* unfortunately, we have to keep track of paths both here and in the library /* unfortunately, we have to keep track of paths both here and in the library
* because they can come from both the command line or config file, and we * because they can come from both the command line or config file, and we
* need to ensure we get the order of preference right. */ * need to ensure we get the order of preference right. */
@ -59,7 +61,6 @@ typedef struct __config_t {
unsigned short op_s_sync; unsigned short op_s_sync;
unsigned short op_s_search; unsigned short op_s_search;
unsigned short op_s_upgrade; unsigned short op_s_upgrade;
unsigned short op_s_printuris;
unsigned short group; unsigned short group;
pmtransflag_t flags; pmtransflag_t flags;
@ -103,7 +104,8 @@ enum {
OP_IGNOREGROUP, OP_IGNOREGROUP,
OP_NEEDED, OP_NEEDED,
OP_ASEXPLICIT, OP_ASEXPLICIT,
OP_ARCH OP_ARCH,
OP_PRINTFORMAT
}; };
/* clean method */ /* clean method */

View file

@ -129,7 +129,6 @@ static void usage(int op, const char * const myname)
printf(_(" -g, --groups view all members of a package group\n")); printf(_(" -g, --groups view all members of a package group\n"));
printf(_(" -i, --info view package information\n")); printf(_(" -i, --info view package information\n"));
printf(_(" -l, --list <repo> view a list of packages in a repo\n")); printf(_(" -l, --list <repo> view a list of packages in a repo\n"));
printf(_(" -p, --print-uris print out URIs for given packages and their dependencies\n"));
printf(_(" -s, --search <regex> search remote repositories for matching strings\n")); printf(_(" -s, --search <regex> search remote repositories for matching strings\n"));
printf(_(" -u, --sysupgrade upgrade installed packages (-uu allows downgrade)\n")); printf(_(" -u, --sysupgrade upgrade installed packages (-uu allows downgrade)\n"));
printf(_(" -w, --downloadonly download packages but do not install/upgrade anything\n")); printf(_(" -w, --downloadonly download packages but do not install/upgrade anything\n"));
@ -140,6 +139,9 @@ static void usage(int op, const char * const myname)
" ignore a group upgrade (can be used more than once)\n")); " ignore a group upgrade (can be used more than once)\n"));
printf(_(" -q, --quiet show less information for query and search\n")); printf(_(" -q, --quiet show less information for query and search\n"));
} }
printf(_(" --print only print the targets instead of performing the operation\n"));
printf(_(" --print-format <string>\n"
" specify how the targets should be printed\n"));
printf(_(" --config <path> set an alternate configuration file\n")); printf(_(" --config <path> set an alternate configuration file\n"));
printf(_(" --logfile <path> set an alternate log file\n")); printf(_(" --logfile <path> set an alternate log file\n"));
printf(_(" --noconfirm do not ask for any confirmation\n")); printf(_(" --noconfirm do not ask for any confirmation\n"));
@ -371,7 +373,7 @@ static int parseargs(int argc, char *argv[])
{"nosave", no_argument, 0, 'n'}, {"nosave", no_argument, 0, 'n'},
{"owns", no_argument, 0, 'o'}, {"owns", no_argument, 0, 'o'},
{"file", no_argument, 0, 'p'}, {"file", no_argument, 0, 'p'},
{"print-uris", no_argument, 0, 'p'}, {"print", no_argument, 0, 'p'},
{"quiet", no_argument, 0, 'q'}, {"quiet", no_argument, 0, 'q'},
{"root", required_argument, 0, 'r'}, {"root", required_argument, 0, 'r'},
{"recursive", no_argument, 0, 's'}, {"recursive", no_argument, 0, 's'},
@ -397,6 +399,7 @@ static int parseargs(int argc, char *argv[])
{"needed", no_argument, 0, OP_NEEDED}, {"needed", no_argument, 0, OP_NEEDED},
{"asexplicit", no_argument, 0, OP_ASEXPLICIT}, {"asexplicit", no_argument, 0, OP_ASEXPLICIT},
{"arch", required_argument, 0, OP_ARCH}, {"arch", required_argument, 0, OP_ARCH},
{"print-format", required_argument, 0, OP_PRINTFORMAT},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -485,6 +488,9 @@ static int parseargs(int argc, char *argv[])
check_optarg(); check_optarg();
setarch(optarg); setarch(optarg);
break; break;
case OP_PRINTFORMAT:
config->print_format = strdup(optarg);
break;
case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break; case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break; case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break; case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
@ -521,9 +527,7 @@ static int parseargs(int argc, char *argv[])
case 'o': config->op_q_owns = 1; break; case 'o': config->op_q_owns = 1; break;
case 'p': case 'p':
config->op_q_isfile = 1; config->op_q_isfile = 1;
config->op_s_printuris = 1; config->print = 1;
config->flags |= PM_TRANS_FLAG_NOCONFLICTS;
config->flags |= PM_TRANS_FLAG_NOLOCK;
break; break;
case 'q': case 'q':
config->quiet = 1; config->quiet = 1;
@ -1126,6 +1130,15 @@ int main(int argc, char *argv[])
config->noconfirm = 1; config->noconfirm = 1;
} }
/* set up the print operations */
if(config->print) {
config->noconfirm = 1;
config->flags |= PM_TRANS_FLAG_NOCONFLICTS;
config->flags |= PM_TRANS_FLAG_NOLOCK;
/* Display only errors */
config->logmask &= ~PM_LOG_WARNING;
}
#if defined(HAVE_GETEUID) && !defined(CYGWIN) #if defined(HAVE_GETEUID) && !defined(CYGWIN)
/* check if we have sufficient permission for the requested operation */ /* check if we have sufficient permission for the requested operation */
if(myuid > 0 && needs_root()) { if(myuid > 0 && needs_root()) {

View file

@ -121,6 +121,12 @@ int pacman_remove(alpm_list_t *targets)
printf(_(" there is nothing to do\n")); printf(_(" there is nothing to do\n"));
goto cleanup; /* we are done */ goto cleanup; /* we are done */
} }
if(config->print) {
print_packages(pkglist);
goto cleanup;
}
/* print targets and ask user confirmation */ /* print targets and ask user confirmation */
display_targets(pkglist, 0); display_targets(pkglist, 0);
printf("\n"); printf("\n");

View file

@ -688,23 +688,8 @@ static int sync_trans(alpm_list_t *targets)
} }
/* Step 3: actually perform the operation */ /* Step 3: actually perform the operation */
if(config->op_s_printuris) { if(config->print) {
/* print uris */ print_packages(packages);
alpm_list_t *i;
for(i = packages; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = alpm_list_getdata(i);
pmdb_t *db = alpm_pkg_get_db(pkg);
const char *dburl = alpm_db_get_url(db);
if(dburl) {
printf("%s/%s\n", dburl, alpm_pkg_get_filename(pkg));
} else {
/* can't use WARNING here, we don't show warnings in -Sp... */
pm_fprintf(stderr, PM_LOG_ERROR, _("no URL for package: %s\n"),
alpm_pkg_get_name(pkg));
}
}
/* we are done */
goto cleanup; goto cleanup;
} }
@ -777,11 +762,6 @@ int pacman_sync(alpm_list_t *targets)
{ {
alpm_list_t *sync_dbs = NULL; alpm_list_t *sync_dbs = NULL;
/* Display only errors with -Sp and -Sw operations */
if((config->flags & PM_TRANS_FLAG_DOWNLOADONLY) || config->op_s_printuris) {
config->logmask &= ~PM_LOG_WARNING;
}
/* clean the cache */ /* clean the cache */
if(config->op_s_clean) { if(config->op_s_clean) {
int ret = 0; int ret = 0;
@ -851,7 +831,7 @@ int pacman_sync(alpm_list_t *targets)
} }
alpm_list_t *targs = alpm_list_strdup(targets); alpm_list_t *targs = alpm_list_strdup(targets);
if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY) && !config->op_s_printuris) { if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY) && !config->print) {
/* check for newer versions of packages to be upgraded first */ /* check for newer versions of packages to be upgraded first */
alpm_list_t *packages = syncfirst(); alpm_list_t *packages = syncfirst();
if(packages) { if(packages) {

View file

@ -69,7 +69,6 @@ int pacman_upgrade(alpm_list_t *targets)
} }
/* add targets to the created transaction */ /* add targets to the created transaction */
printf(_("loading package data...\n"));
for(i = targets; i; i = alpm_list_next(i)) { for(i = targets; i; i = alpm_list_next(i)) {
char *targ = alpm_list_getdata(i); char *targ = alpm_list_getdata(i);
if(alpm_add_target(targ) == -1) { if(alpm_add_target(targ) == -1) {
@ -129,6 +128,13 @@ int pacman_upgrade(alpm_list_t *targets)
} }
/* Step 3: perform the installation */ /* Step 3: perform the installation */
if(config->print) {
print_packages(alpm_trans_get_add());
trans_release();
return(0);
}
/* print targets and ask user confirmation */ /* print targets and ask user confirmation */
alpm_list_t *packages = alpm_trans_get_add(); alpm_list_t *packages = alpm_trans_get_add();
if(packages == NULL) { /* we are done */ if(packages == NULL) { /* we are done */

View file

@ -47,8 +47,15 @@
int trans_init(pmtransflag_t flags) int trans_init(pmtransflag_t flags)
{ {
if(alpm_trans_init(flags, cb_trans_evt, int ret;
cb_trans_conv, cb_trans_progress) == -1) { if(config->print) {
ret = alpm_trans_init(flags, NULL, NULL, NULL);
} else {
ret = alpm_trans_init(flags, cb_trans_evt, cb_trans_conv,
cb_trans_progress);
}
if(ret == -1) {
pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"), pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"),
alpm_strerrorlast()); alpm_strerrorlast());
if(pm_errno == PM_ERR_HANDLE_LOCK) { if(pm_errno == PM_ERR_HANDLE_LOCK) {
@ -72,13 +79,16 @@ int trans_release(void)
int needs_root(void) int needs_root(void)
{ {
if(config->op == PM_OP_UPGRADE || config->op == PM_OP_REMOVE || /* -U, -R */ switch(config->op) {
(config->op == PM_OP_SYNC && (config->op_s_clean || config->op_s_sync || /* -Sc, -Sy */ case PM_OP_UPGRADE:
(!config->group && !config->op_s_info && !config->op_q_list /* all other -S combinations, where */ case PM_OP_REMOVE:
&& !config->op_s_search && !config->op_s_printuris)))) { /* -g, -i, -l, -s, -p is not set */ return(!config->print);
return(1); case PM_OP_SYNC:
} else { return(config->op_s_clean || config->op_s_sync ||
return(0); (!config->group && !config->op_s_info && !config->op_q_list &&
!config->op_s_search && !config->print));
default:
return(0);
} }
} }
@ -553,6 +563,98 @@ void display_targets(const alpm_list_t *pkgs, int install)
FREELIST(targets); FREELIST(targets);
} }
off_t pkg_get_size(pmpkg_t *pkg)
{
switch(config->op) {
case PM_OP_SYNC:
return(alpm_pkg_download_size(pkg));
case PM_OP_UPGRADE:
return(alpm_pkg_get_size(pkg));
default:
return(alpm_pkg_get_isize(pkg));
}
}
char *pkg_get_location(pmpkg_t *pkg)
{
pmdb_t *db;
const char *dburl;
char *string;
switch(config->op) {
case PM_OP_SYNC:
db = alpm_pkg_get_db(pkg);
dburl = alpm_db_get_url(db);
if(dburl) {
char *pkgurl = NULL;
asprintf(&pkgurl, "%s/%s", dburl, alpm_pkg_get_filename(pkg));
return(pkgurl);
}
case PM_OP_UPGRADE:
return(strdup(alpm_pkg_get_filename(pkg)));
default:
string = NULL;
asprintf(&string, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
return(string);
}
}
void print_packages(const alpm_list_t *packages)
{
const alpm_list_t *i;
if(!config->print_format) {
config->print_format = strdup("%l");
}
for(i = packages; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = alpm_list_getdata(i);
char *string = strdup(config->print_format);
char *temp = string;
/* %n : pkgname */
if(strstr(temp,"%n")) {
string = strreplace(temp, "%n", alpm_pkg_get_name(pkg));
free(temp);
temp = string;
}
/* %v : pkgver */
if(strstr(temp,"%v")) {
string = strreplace(temp, "%v", alpm_pkg_get_version(pkg));
free(temp);
temp = string;
}
/* %l : location */
if(strstr(temp,"%l")) {
char *pkgloc = pkg_get_location(pkg);
string = strreplace(temp, "%l", pkgloc);
free(pkgloc);
free(temp);
temp = string;
}
/* %r : repo */
if(strstr(temp,"%r")) {
const char *repo = "local";
pmdb_t *db = alpm_pkg_get_db(pkg);
if(db) {
repo = alpm_db_get_name(db);
}
string = strreplace(temp, "%r", repo);
free(temp);
temp = string;
}
/* %s : size */
if(strstr(temp,"%s")) {
char *size;
double mbsize = 0.0;
mbsize = pkg_get_size(pkg) / (1024.0 * 1024.0);
asprintf(&size, "%.2f", mbsize);
string = strreplace(temp, "%s", size);
free(size);
free(temp);
temp = string;
}
printf("%s\n",string);
free(string);
}
}
/* Helper function for comparing strings using the /* Helper function for comparing strings using the
* alpm "compare func" signature */ * alpm "compare func" signature */
int str_cmp(const void *s1, const void *s2) int str_cmp(const void *s1, const void *s2)

View file

@ -55,6 +55,7 @@ void list_display_linebreak(const char *title, const alpm_list_t *list);
void display_targets(const alpm_list_t *pkgs, int install); void display_targets(const alpm_list_t *pkgs, int install);
void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg); void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg);
void display_optdepends(pmpkg_t *pkg); void display_optdepends(pmpkg_t *pkg);
void print_packages(const alpm_list_t *packages);
int yesno(char *fmt, ...); int yesno(char *fmt, ...);
int noyes(char *fmt, ...); int noyes(char *fmt, ...);
int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3))); int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));