[pacman-dev] [PATCH 0/2] Add color support in -Ql and option to output in tree format
Hello. This is my first contribution. I Wanted to enhance -Ql output so i prepared 2 patches. The first one is quite trivial, so i don't think there will be a problem. The second one i'm not quite sure you'll want it in pacman instead of an external tool like pkgfile or pactree. I'm submitting it anyways so you can take a look. Right now you need to pass 2 (or more) -l flags in -Q(uery) to activate it. This is obviously very naive and it will break some flag combinations. This is just a proof of concept. If you like it, then a seperate flag like --tree can be added. Thanks for any feedback! Bill Kolokithas (2): Make folders appear in bold when listing files owned by a package. Add Query flag to list all files contained in a package in a tree format. src/pacman/package.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/package.h | 1 + src/pacman/pacman.c | 2 +- src/pacman/query.c | 4 ++- 4 files changed, 89 insertions(+), 2 deletions(-) -- 1.8.4.2
It's a trivial patch to make folders stand out more when -l is passed on Query without the -q(uiet) flag. Right now is using the same color as the pkgname (config->colstr.title), which is bold. Signed-off-by: Bill Kolokithas <kolokithas.b@gmail.com> --- src/pacman/package.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pacman/package.c b/src/pacman/package.c index 78bfb50..1485889 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -322,6 +322,11 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) */ if(!quiet) { printf("%s%s%s ", config->colstr.title, pkgname, config->colstr.nocolor); + /* Make folders appear in bold */ + if (file->name[strlen(file->name) - 1] == '/') { + printf("%s%s%s%s\n", config->colstr.title, root, file->name, config->colstr.nocolor); + continue; + } } printf("%s%s\n", root, file->name); } -- 1.8.4.2
On 07/11/13 11:07, Bill Kolokithas wrote:
It's a trivial patch to make folders stand out more when -l is passed on Query without the -q(uiet) flag. Right now is using the same color as the pkgname (config->colstr.title), which is bold.
Signed-off-by: Bill Kolokithas <kolokithas.b@gmail.com>
Why would you want the directories highlighted? This seems one of the least important pieces of information about what is in a package.
--- src/pacman/package.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/pacman/package.c b/src/pacman/package.c index 78bfb50..1485889 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -322,6 +322,11 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) */ if(!quiet) { printf("%s%s%s ", config->colstr.title, pkgname, config->colstr.nocolor); + /* Make folders appear in bold */ + if (file->name[strlen(file->name) - 1] == '/') { + printf("%s%s%s%s\n", config->colstr.title, root, file->name, config->colstr.nocolor); + continue; + } } printf("%s%s\n", root, file->name); }
My goal was to replicate the tree output format from gentoo's equery tool. No support for differentiating output based on file types (symlink, FIFO etc). Signed-off-by: Bill Kolokithas <kolokithas.b@gmail.com> --- src/pacman/package.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/package.h | 1 + src/pacman/pacman.c | 2 +- src/pacman/query.c | 4 ++- 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/pacman/package.c b/src/pacman/package.c index 1485889..949755a 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -334,6 +334,85 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) fflush(stdout); } +/* Count character occurrences in a string + */ +static int count_char(char *s, char c) +{ + int count = 0; + + for (; *s; s++) + if (*s == c) + count++; + + return count; +} + +/* List all files contained in a package in a tree format + */ +void dump_pkg_file_tree(alpm_pkg_t *pkg) +{ + const char *pkgname, *root, *prefix; + const alpm_file_t *file; + alpm_filelist_t *pkgfiles; + char *basename, filename[512], pool[128]; + int len, isDir, num_spaces, dirdepth; + size_t i; + + /* Fill our pool with spaces */ + memset(pool, ' ', sizeof(pool)); + pkgname = alpm_pkg_get_name(pkg); + pkgfiles = alpm_pkg_get_files(pkg); + root = alpm_option_get_root(config->handle); + + printf("%s%s:%s\n", config->colstr.title, pkgname, config->colstr.nocolor); + + for(i = 0; i < pkgfiles->count; i++) { + /* Duplicate the file name because we will alter it */ + file = pkgfiles->files + i; + strncpy(filename, file->name, sizeof(filename)); + /* Ensure string is always terminated */ + filename[512 - 1] = '\0'; + + prefix = "/"; + len = strlen(filename); + isDir = filename[len - 1] == '/'; + dirdepth = count_char(filename, '/'); + + /* Indent accordingly */ + num_spaces = 1; + if(dirdepth == 2) { + num_spaces = 3; + } else if(dirdepth > 2) { + num_spaces = 3 * (dirdepth - 1); + } + + /* Cut the trailing '/' so we can find the one before it */ + if(isDir) { + filename[len - 1] = '\0'; + } else { + /* Extra padding for files */ + num_spaces += 3; + } + + /* If no '/' is found, then it means we are on the top level so, we prepend the root */ + basename = strrchr(filename, '/'); + if(!basename) { + basename = filename; + prefix = root; + } else { + /* Skip the starting '/' char */ + basename++; + } + + if(isDir) { + printf("%.*s%s> %s%s%s\n", num_spaces, pool, config->colstr.title, prefix, basename, config->colstr.nocolor); + } else { + printf("%.*s%s+%s %s\n", num_spaces, pool, config->colstr.title, config->colstr.nocolor, basename); + } + } + fflush(stdout); +} + /* Display the changelog of a package */ void dump_pkg_changelog(alpm_pkg_t *pkg) diff --git a/src/pacman/package.h b/src/pacman/package.h index 65eea87..58d58b5 100644 --- a/src/pacman/package.h +++ b/src/pacman/package.h @@ -26,6 +26,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra); void dump_pkg_backups(alpm_pkg_t *pkg); void dump_pkg_files(alpm_pkg_t *pkg, int quiet); +void dump_pkg_file_tree(alpm_pkg_t *pkg); void dump_pkg_changelog(alpm_pkg_t *pkg); void print_installed(alpm_db_t *db_local, alpm_pkg_t *pkg); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index e5d16fc..60e0f0d 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -525,7 +525,7 @@ static int parsearg_query(int opt) break; case OP_LIST: case 'l': - config->op_q_list = 1; + (config->op_q_list)++; break; case OP_FOREIGN: case 'm': diff --git a/src/pacman/query.c b/src/pacman/query.c index 8814307..d1a11d5 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -301,8 +301,10 @@ static int display(alpm_pkg_t *pkg) dump_pkg_full(pkg, config->op_q_info > 1); } } - if(config->op_q_list) { + if(config->op_q_list == 1) { dump_pkg_files(pkg, config->quiet); + } else if(config->op_q_list > 1) { + dump_pkg_file_tree(pkg); } if(config->op_q_changelog) { dump_pkg_changelog(pkg); -- 1.8.4.2
On 07/11/13 11:07, Bill Kolokithas wrote:
My goal was to replicate the tree output format from gentoo's equery tool. No support for differentiating output based on file types (symlink, FIFO etc).
Signed-off-by: Bill Kolokithas <kolokithas.b@gmail.com>
For those that have no idea of what that output looks like, take a look at [1]. I'm not sure what the gain is here. Testing it out with glibc, I was required to scroll up five screens before seeing the parent directory name and all the way to the top to see it was in /usr. [1] https://wiki.gentoo.org/wiki/Gentoolkit#Listing_Files_Installed_by_a_Package... A
--- src/pacman/package.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/package.h | 1 + src/pacman/pacman.c | 2 +- src/pacman/query.c | 4 ++- 4 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/src/pacman/package.c b/src/pacman/package.c index 1485889..949755a 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -334,6 +334,85 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) fflush(stdout); }
+/* Count character occurrences in a string + */ +static int count_char(char *s, char c) +{ + int count = 0; + + for (; *s; s++) + if (*s == c) + count++; + + return count; +} + +/* List all files contained in a package in a tree format + */ +void dump_pkg_file_tree(alpm_pkg_t *pkg) +{ + const char *pkgname, *root, *prefix; + const alpm_file_t *file; + alpm_filelist_t *pkgfiles; + char *basename, filename[512], pool[128]; + int len, isDir, num_spaces, dirdepth; + size_t i; + + /* Fill our pool with spaces */ + memset(pool, ' ', sizeof(pool)); + pkgname = alpm_pkg_get_name(pkg); + pkgfiles = alpm_pkg_get_files(pkg); + root = alpm_option_get_root(config->handle); + + printf("%s%s:%s\n", config->colstr.title, pkgname, config->colstr.nocolor); + + for(i = 0; i < pkgfiles->count; i++) { + /* Duplicate the file name because we will alter it */ + file = pkgfiles->files + i; + strncpy(filename, file->name, sizeof(filename)); + /* Ensure string is always terminated */ + filename[512 - 1] = '\0'; + + prefix = "/"; + len = strlen(filename); + isDir = filename[len - 1] == '/'; + dirdepth = count_char(filename, '/'); + + /* Indent accordingly */ + num_spaces = 1; + if(dirdepth == 2) { + num_spaces = 3; + } else if(dirdepth > 2) { + num_spaces = 3 * (dirdepth - 1); + } + + /* Cut the trailing '/' so we can find the one before it */ + if(isDir) { + filename[len - 1] = '\0'; + } else { + /* Extra padding for files */ + num_spaces += 3; + } + + /* If no '/' is found, then it means we are on the top level so, we prepend the root */ + basename = strrchr(filename, '/'); + if(!basename) { + basename = filename; + prefix = root; + } else { + /* Skip the starting '/' char */ + basename++; + } + + if(isDir) { + printf("%.*s%s> %s%s%s\n", num_spaces, pool, config->colstr.title, prefix, basename, config->colstr.nocolor); + } else { + printf("%.*s%s+%s %s\n", num_spaces, pool, config->colstr.title, config->colstr.nocolor, basename); + } + } + fflush(stdout); +} + /* Display the changelog of a package */ void dump_pkg_changelog(alpm_pkg_t *pkg) diff --git a/src/pacman/package.h b/src/pacman/package.h index 65eea87..58d58b5 100644 --- a/src/pacman/package.h +++ b/src/pacman/package.h @@ -26,6 +26,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra);
void dump_pkg_backups(alpm_pkg_t *pkg); void dump_pkg_files(alpm_pkg_t *pkg, int quiet); +void dump_pkg_file_tree(alpm_pkg_t *pkg); void dump_pkg_changelog(alpm_pkg_t *pkg);
void print_installed(alpm_db_t *db_local, alpm_pkg_t *pkg); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index e5d16fc..60e0f0d 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -525,7 +525,7 @@ static int parsearg_query(int opt) break; case OP_LIST: case 'l': - config->op_q_list = 1; + (config->op_q_list)++; break; case OP_FOREIGN: case 'm': diff --git a/src/pacman/query.c b/src/pacman/query.c index 8814307..d1a11d5 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -301,8 +301,10 @@ static int display(alpm_pkg_t *pkg) dump_pkg_full(pkg, config->op_q_info > 1); } } - if(config->op_q_list) { + if(config->op_q_list == 1) { dump_pkg_files(pkg, config->quiet); + } else if(config->op_q_list > 1) { + dump_pkg_file_tree(pkg); } if(config->op_q_changelog) { dump_pkg_changelog(pkg); -- 1.8.4.2
For long filelists it's not so practical, i agree. Well, your call if you want to keep any patch. :) On Thu, Nov 7, 2013 at 6:51 AM, Allan McRae <allan@archlinux.org> wrote:
On 07/11/13 11:07, Bill Kolokithas wrote:
My goal was to replicate the tree output format from gentoo's equery tool. No support for differentiating output based on file types (symlink, FIFO etc).
Signed-off-by: Bill Kolokithas <kolokithas.b@gmail.com>
For those that have no idea of what that output looks like, take a look at [1].
I'm not sure what the gain is here. Testing it out with glibc, I was required to scroll up five screens before seeing the parent directory name and all the way to the top to see it was in /usr.
[1] https://wiki.gentoo.org/wiki/Gentoolkit#Listing_Files_Installed_by_a_Package...
A
--- src/pacman/package.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/package.h | 1 + src/pacman/pacman.c | 2 +- src/pacman/query.c | 4 ++- 4 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/src/pacman/package.c b/src/pacman/package.c index 1485889..949755a 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -334,6 +334,85 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) fflush(stdout); }
+/* Count character occurrences in a string + */ +static int count_char(char *s, char c) +{ + int count = 0; + + for (; *s; s++) + if (*s == c) + count++; + + return count; +} + +/* List all files contained in a package in a tree format + */ +void dump_pkg_file_tree(alpm_pkg_t *pkg) +{ + const char *pkgname, *root, *prefix; + const alpm_file_t *file; + alpm_filelist_t *pkgfiles; + char *basename, filename[512], pool[128]; + int len, isDir, num_spaces, dirdepth; + size_t i; + + /* Fill our pool with spaces */ + memset(pool, ' ', sizeof(pool)); + pkgname = alpm_pkg_get_name(pkg); + pkgfiles = alpm_pkg_get_files(pkg); + root = alpm_option_get_root(config->handle); + + printf("%s%s:%s\n", config->colstr.title, pkgname, config->colstr.nocolor); + + for(i = 0; i < pkgfiles->count; i++) { + /* Duplicate the file name because we will alter it */ + file = pkgfiles->files + i; + strncpy(filename, file->name, sizeof(filename)); + /* Ensure string is always terminated */ + filename[512 - 1] = '\0'; + + prefix = "/"; + len = strlen(filename); + isDir = filename[len - 1] == '/'; + dirdepth = count_char(filename, '/'); + + /* Indent accordingly */ + num_spaces = 1; + if(dirdepth == 2) { + num_spaces = 3; + } else if(dirdepth > 2) { + num_spaces = 3 * (dirdepth - 1); + } + + /* Cut the trailing '/' so we can find the one before it */ + if(isDir) { + filename[len - 1] = '\0'; + } else { + /* Extra padding for files */ + num_spaces += 3; + } + + /* If no '/' is found, then it means we are on the top level so, we prepend the root */ + basename = strrchr(filename, '/'); + if(!basename) { + basename = filename; + prefix = root; + } else { + /* Skip the starting '/' char */ + basename++; + } + + if(isDir) { + printf("%.*s%s> %s%s%s\n", num_spaces, pool, config->colstr.title, prefix, basename, config->colstr.nocolor); + } else { + printf("%.*s%s+%s %s\n", num_spaces, pool, config->colstr.title, config->colstr.nocolor, basename); + } + } + fflush(stdout); +} + /* Display the changelog of a package */ void dump_pkg_changelog(alpm_pkg_t *pkg) diff --git a/src/pacman/package.h b/src/pacman/package.h index 65eea87..58d58b5 100644 --- a/src/pacman/package.h +++ b/src/pacman/package.h @@ -26,6 +26,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra);
void dump_pkg_backups(alpm_pkg_t *pkg); void dump_pkg_files(alpm_pkg_t *pkg, int quiet); +void dump_pkg_file_tree(alpm_pkg_t *pkg); void dump_pkg_changelog(alpm_pkg_t *pkg);
void print_installed(alpm_db_t *db_local, alpm_pkg_t *pkg); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index e5d16fc..60e0f0d 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -525,7 +525,7 @@ static int parsearg_query(int opt) break; case OP_LIST: case 'l': - config->op_q_list = 1; + (config->op_q_list)++; break; case OP_FOREIGN: case 'm': diff --git a/src/pacman/query.c b/src/pacman/query.c index 8814307..d1a11d5 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -301,8 +301,10 @@ static int display(alpm_pkg_t *pkg) dump_pkg_full(pkg, config->op_q_info > 1); } } - if(config->op_q_list) { + if(config->op_q_list == 1) { dump_pkg_files(pkg, config->quiet); + } else if(config->op_q_list > 1) { + dump_pkg_file_tree(pkg); } if(config->op_q_changelog) { dump_pkg_changelog(pkg); -- 1.8.4.2
participants (3)
-
Allan McRae
-
Bill Kolokithas
-
Bill kolokithas