commit:     1038786d92a885dece9cc82588e88d8367a0fda2
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Fri Dec 27 19:14:44 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Fri Dec 27 19:14:44 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=1038786d

qkeyword: apply profile masks to -S/-T results

Technically, this should be enough to implement the Puppet provider for
Gentoo.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 man/include/qkeyword-01-latest-testing.include | 23 ++++++++
 man/include/qkeyword.desc                      | 10 +++-
 man/qkeyword.1                                 | 34 ++++++++++--
 qkeyword.c                                     | 73 +++++++++++++++++++++-----
 4 files changed, 121 insertions(+), 19 deletions(-)

diff --git a/man/include/qkeyword-01-latest-testing.include 
b/man/include/qkeyword-01-latest-testing.include
new file mode 100644
index 0000000..1c2fde5
--- /dev/null
+++ b/man/include/qkeyword-01-latest-testing.include
@@ -0,0 +1,23 @@
+.SH "RETRIEVING LATEST TESTING VERSION AVAILABLE"
+.PP
+To retrieve the latest available version in the ebuild tree marked as
+testing for the given ARCH, can be done with a combination of flags,
+mostly to restrict the search.  For instance, to find the latest version
+of \fIsys-devel/gcc\fR available, one could use:
+.nf
+$ qkeyword -p sys-devel/gcc -T
+sys-devel/gcc-8.3.0
+.fi
+It may be that there is a newer version available, but masked for the
+configured profile (via package.mask).  Using \fB-v\fR will inform about
+this scenario happening:
+.nf
+$ qkeyword -p dev-vcs/cvs -Tv
+masked by =dev-vcs/cvs-1.12.12*: dev-vcs/cvs-1.12.12-r12
+.fi
+Unrelated, but to locate the mask given, use verbose mode on \fIq\fR's
+mask listing:
+.nf
+$ q -mv dev-vcs/cvs
+=dev-vcs/cvs-1.12.12* [/repo/gentoo/profiles/prefix/sunos/solaris/package.mask]
+.fi

diff --git a/man/include/qkeyword.desc b/man/include/qkeyword.desc
index b7a863c..adc55ea 100644
--- a/man/include/qkeyword.desc
+++ b/man/include/qkeyword.desc
@@ -1,5 +1,5 @@
-\fIqkeyword\fR allows various searches based on KEYWORDS aimed at Gentoo
-developers.  Various modes allow to query which packages would be
+\fIqkeyword\fR allows various searches based on KEYWORDS.  Some uses are
+aimed at Gentoo developers, to allow querying which packages would be
 available, or are candidate for keywording.
 .P
 By default, the entire tree is traversed.  Since this process can be
@@ -12,3 +12,9 @@ as package in one go.  The \fB-m\fR maintainer match, while 
reducing the
 resulting set, is likely to slow down the query processing since the
 metadata.xml file has to be read for each package examined.  It is best
 used in combination with \fB-p\fR or \fB-c\fR.
+.P
+\fIqkeyword\fR uses the keyword found in the configured profile (ARCH)
+for its queries.  This keyword can be overridden by giving the desired
+keyword as argument.  Note that this does not change the profile in use,
+which most notably can result in incorrect masks being applied for the
+\fB-T\fR and \fB-S\fR options.

diff --git a/man/qkeyword.1 b/man/qkeyword.1
index 34beb18..5a26218 100644
--- a/man/qkeyword.1
+++ b/man/qkeyword.1
@@ -6,8 +6,8 @@ qkeyword \- list packages based on keywords
 .B qkeyword
 \fI[opts] <action> <args>\fR
 .SH DESCRIPTION
-\fIqkeyword\fR allows various searches based on KEYWORDS aimed at Gentoo
-developers.  Various modes allow to query which packages would be
+\fIqkeyword\fR allows various searches based on KEYWORDS.  Some uses are
+aimed at Gentoo developers, to allow querying which packages would be
 available, or are candidate for keywording.
 .P
 By default, the entire tree is traversed.  Since this process can be
@@ -20,6 +20,12 @@ as package in one go.  The \fB-m\fR maintainer match, while 
reducing the
 resulting set, is likely to slow down the query processing since the
 metadata.xml file has to be read for each package examined.  It is best
 used in combination with \fB-p\fR or \fB-c\fR.
+.P
+\fIqkeyword\fR uses the keyword found in the configured profile (ARCH)
+for its queries.  This keyword can be overridden by giving the desired
+keyword as argument.  Note that this does not change the profile in use,
+which most notably can result in incorrect masks being applied for the
+\fB-T\fR and \fB-S\fR options.
 .SH OPTIONS
 .TP
 \fB\-p\fR \fI<arg>\fR, \fB\-\-matchpkg\fR \fI<arg>\fR
@@ -75,7 +81,29 @@ Print this help and exit.
 .TP
 \fB\-V\fR, \fB\-\-version\fR
 Print version and exit.
-
+.SH "RETRIEVING LATEST TESTING VERSION AVAILABLE"
+.PP
+To retrieve the latest available version in the ebuild tree marked as
+testing for the given ARCH, can be done with a combination of flags,
+mostly to restrict the search.  For instance, to find the latest version
+of \fIsys-devel/gcc\fR available, one could use:
+.nf
+$ qkeyword -p sys-devel/gcc -T
+sys-devel/gcc-8.3.0
+.fi
+It may be that there is a newer version available, but masked for the
+configured profile (via package.mask).  Using \fB-v\fR will inform about
+this scenario happening:
+.nf
+$ qkeyword -p dev-vcs/cvs -Tv
+masked by =dev-vcs/cvs-1.12.12*: dev-vcs/cvs-1.12.12-r12
+.fi
+Unrelated, but to locate the mask given, use verbose mode on \fIq\fR's
+mask listing:
+.nf
+$ q -mv dev-vcs/cvs
+=dev-vcs/cvs-1.12.12* [/repo/gentoo/profiles/prefix/sunos/solaris/package.mask]
+.fi
 .SH "REPORTING BUGS"
 Please report bugs via http://bugs.gentoo.org/
 .br

diff --git a/qkeyword.c b/qkeyword.c
index 4a55b6a..4e84ebd 100644
--- a/qkeyword.c
+++ b/qkeyword.c
@@ -76,8 +76,9 @@ static set *archs = NULL;
 static char **archlist = NULL;
 static size_t archlist_count;
 static size_t arch_longest_len;
-const char status[3] = {'-', '~', '+'};
-int qkeyword_test_arch = 0;
+static const char status[3] = {'-', '~', '+'};
+static int qkeyword_test_arch = 0;
+static set *pmasks = NULL;
 
 enum { none = 0, testing, stable, minus };
 
@@ -226,13 +227,33 @@ qkeyword_imlate(tree_pkg_ctx *pkg_ctx, void *priv)
 }
 
 static int
-qkeyword_lstable(tree_pkg_ctx *pkg_ctx, void *priv)
+qkeyword_kw(tree_pkg_ctx *pkg_ctx, void *priv, int what)
 {
        qkeyword_data *data = (qkeyword_data *)priv;
+       depend_atom *atom;
+       array_t *masks;
 
-       if (data->keywordsbuf[qkeyword_test_arch] == stable)
+       if (data->keywordsbuf[qkeyword_test_arch] == what)
        {
-               printf("%s", atom_format(data->fmt, tree_get_atom(pkg_ctx, 
true)));
+               size_t n;
+               depend_atom *mask;
+
+               atom = tree_get_atom(pkg_ctx, false);
+               masks = get_set(atom_format("%[CAT]%[PN]", atom), pmasks);
+               if (masks != NULL) {
+                       array_for_each(masks, n, mask) {
+                               if (atom_compare(atom, mask) == EQUAL) {
+                                       if (verbose) {
+                                               printf("masked by %s: ", 
atom_to_string(mask));
+                                               printf("%s\n", 
atom_format(data->fmt,
+                                                                       
tree_get_atom(pkg_ctx, true)));
+                                       }
+                                       return EXIT_FAILURE;
+                               }
+                       }
+               }
+
+               printf("%s\n", atom_format(data->fmt, tree_get_atom(pkg_ctx, 
true)));
                return EXIT_SUCCESS;
        }
 
@@ -240,17 +261,15 @@ qkeyword_lstable(tree_pkg_ctx *pkg_ctx, void *priv)
 }
 
 static int
-qkeyword_ltesting(tree_pkg_ctx *pkg_ctx, void *priv)
+qkeyword_lstable(tree_pkg_ctx *pkg_ctx, void *priv)
 {
-       qkeyword_data *data = (qkeyword_data *)priv;
-
-       if (data->keywordsbuf[qkeyword_test_arch] == testing)
-       {
-               printf("%s\n", atom_format(data->fmt, tree_get_atom(pkg_ctx, 
true)));
-               return EXIT_SUCCESS;
-       }
+       return qkeyword_kw(pkg_ctx, priv, stable);
+}
 
-       return EXIT_FAILURE;
+static int
+qkeyword_ltesting(tree_pkg_ctx *pkg_ctx, void *priv)
+{
+       return qkeyword_kw(pkg_ctx, priv, testing);
 }
 
 static int
@@ -868,6 +887,32 @@ int qkeyword_main(int argc, char **argv)
        data.keywordsbuflen = 0;
        data.qmaint = maint;
 
+       /* prepare masks for easy(er) matching by key-ing on CAT/PN */
+       {
+               DECLARE_ARRAY(masks);
+               array_t *bucket;
+               array_t *ebuck;
+               size_t n;
+               char *mask;
+               depend_atom *atom;
+
+               pmasks = create_set();
+
+               array_set(package_masks, masks);
+               array_for_each(masks, n, mask) {
+                       if ((atom = atom_explode(mask)) == NULL)
+                               continue;
+                       bucket = xzalloc(sizeof(array_t));
+                       xarraypush_ptr(bucket, atom);
+                       ebuck = add_set_value(atom_format("%[CAT]%[PN]", atom),
+                                       bucket, pmasks);
+                       if (ebuck != NULL) {
+                               xarraypush_ptr(ebuck, atom);
+                               xarrayfree_int(bucket);
+                       }
+               }
+       }
+
        switch (action) {
                case 'i': i = qkeyword_traverse(qkeyword_imlate, &data);        
break;
                case 'd': i = qkeyword_traverse(qkeyword_dropped, &data);

Reply via email to