bin/show: Add options to list metadata keys
authorDan Nicholson <dbn@endlessos.org>
Sun, 29 Jan 2023 21:13:05 +0000 (14:13 -0700)
committerDan Nicholson <dbn@endlessos.org>
Wed, 8 Feb 2023 05:59:30 +0000 (22:59 -0700)
While `--print-metadata-key` is very useful, it's not that helpful if
you don't know what the keys are.

bash/ostree
man/ostree-show.xml
src/ostree/ot-builtin-show.c
tests/basic-test.sh

index 2b7c552f06d2d05272cb4497b1fbba674059dcc6..76a62c594a677a69f770189ef923188e55e06b69 100644 (file)
@@ -1486,6 +1486,8 @@ _ostree_rev_parse() {
 _ostree_show() {
     local boolean_options="
         $main_boolean_options
+        --list-detached-metadata-keys
+        --list-metadata-keys
         --print-related
         --print-sizes
         --raw
index 4495b1e69eb36a4b6d16a87c4ff4049a7ff7ff1d..8d134cc43efd6f130771e018233d3e56eddd0638 100644 (file)
@@ -81,6 +81,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
                 </para></listitem>
             </varlistentry>
 
+            <varlistentry>
+                <term><option>--list-metadata-keys</option></term>
+
+                <listitem><para>
+                    List the available metadata keys.
+                </para></listitem>
+            </varlistentry>
+
             <varlistentry>
                 <term><option>--print-metadata-key</option>="KEY"</term>
 
@@ -89,6 +97,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
                 </para></listitem>
             </varlistentry>
 
+            <varlistentry>
+                <term><option>--list-detached-metadata-keys</option></term>
+
+                <listitem><para>
+                    List the available detached metadata keys.
+                </para></listitem>
+            </varlistentry>
+
             <varlistentry>
                 <term><option>--print-detached-metadata-key</option>="KEY"</term>
 
index 55f2b47e2174bb2a7283b3669371b39731d2ad2b..9346a7b35e7c5db2582d50525ef82afff4c8c210 100644 (file)
@@ -31,6 +31,8 @@ static gboolean opt_print_related;
 static char* opt_print_variant_type;
 static char* opt_print_metadata_key;
 static char* opt_print_detached_metadata_key;
+static gboolean opt_list_metadata_keys;
+static gboolean opt_list_detached_metadata_keys;
 static gboolean opt_print_sizes;
 static gboolean opt_raw;
 static gboolean opt_no_byteswap;
@@ -45,7 +47,9 @@ static char *opt_gpg_verify_remote;
 static GOptionEntry options[] = {
   { "print-related", 0, 0, G_OPTION_ARG_NONE, &opt_print_related, "Show the \"related\" commits", NULL },
   { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" },
+  { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, "List the available metadata keys", NULL },
   { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" },
+  { "list-detached-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_detached_metadata_keys, "List the available detached metadata keys", NULL },
   { "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" },
   { "print-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_print_sizes, "Show the commit size metadata", NULL },
   { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" },
@@ -98,12 +102,14 @@ do_print_related (OstreeRepo  *repo,
 }
 
 static gboolean
-do_print_metadata_key (OstreeRepo     *repo,
-                       const char     *resolved_rev,
-                       gboolean        detached,
-                       const char     *key,
-                       GError        **error)
+get_metadata (OstreeRepo  *repo,
+              const char  *resolved_rev,
+              gboolean     detached,
+              GVariant   **out_metadata,
+              GError     **error)
 {
+  g_assert (out_metadata != NULL);
+
   g_autoptr(GVariant) commit = NULL;
   g_autoptr(GVariant) metadata = NULL;
 
@@ -128,6 +134,59 @@ do_print_metadata_key (OstreeRepo     *repo,
         }
     }
 
+  *out_metadata = g_steal_pointer (&metadata);
+
+  return TRUE;
+}
+
+static gint
+strptr_cmp (gconstpointer a,
+            gconstpointer b)
+{
+  const char *a_str = *((const char **) a);
+  const char *b_str = *((const char **) b);
+
+  return g_strcmp0 (a_str, b_str);
+}
+
+static gboolean
+do_list_metadata_keys (OstreeRepo  *repo,
+                       const char  *resolved_rev,
+                       gboolean     detached,
+                       GError     **error)
+{
+  g_autoptr(GVariant) metadata = NULL;
+  if (!get_metadata (repo, resolved_rev, detached, &metadata, error))
+    return FALSE;
+
+  GVariantIter iter;
+  const char *key = NULL;
+  g_autoptr(GPtrArray) keys = g_ptr_array_new ();
+  g_variant_iter_init (&iter, metadata);
+  while (g_variant_iter_loop (&iter, "{&s@v}", &key, NULL))
+    g_ptr_array_add (keys, (gpointer) key);
+
+  g_ptr_array_sort (keys, strptr_cmp);
+  for (guint i = 0; i < keys-> len; i++)
+    {
+      key = keys->pdata[i];
+      g_print ("%s\n", key);
+    }
+
+  return TRUE;
+}
+
+static gboolean
+do_print_metadata_key (OstreeRepo     *repo,
+                       const char     *resolved_rev,
+                       gboolean        detached,
+                       const char     *key,
+                       GError        **error)
+{
+  g_autoptr(GVariant) metadata = NULL;
+  if (!get_metadata (repo, resolved_rev, detached, &metadata, error))
+    return FALSE;
+
   g_autoptr(GVariant) value = g_variant_lookup_value (metadata, key, NULL);
   if (!value)
     {
@@ -321,10 +380,16 @@ ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation,
       const char *key = detached ? opt_print_detached_metadata_key : opt_print_metadata_key;
       if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
         return FALSE;
-
       if (!do_print_metadata_key (repo, resolved_rev, detached, key, error))
         return FALSE;
     }
+  else if (opt_list_metadata_keys || opt_list_detached_metadata_keys)
+    {
+      if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
+        return FALSE;
+      if (!do_list_metadata_keys (repo, resolved_rev, opt_list_detached_metadata_keys, error))
+        return FALSE;
+    }
   else if (opt_print_related)
     {
       if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
index f97f6fc376d9820b3afebcae552b5f50f29e014a..e2a7d70c1422f1c3a256a33ea3f3cbe1e7594caa 100644 (file)
@@ -1006,6 +1006,13 @@ $OSTREE show -B --print-metadata-key=SOMENUM test2 > test2-meta
 assert_file_has_content test2-meta "uint64 42"
 $OSTREE show --print-detached-metadata-key=SIGNATURE test2 > test2-meta
 assert_file_has_content test2-meta "HANCOCK"
+
+$OSTREE show --list-metadata-keys test2 > test2-meta
+assert_file_has_content test2-meta "FOO"
+assert_file_has_content test2-meta "KITTENS"
+assert_file_has_content test2-meta "SOMENUM"
+$OSTREE show --list-detached-metadata-keys test2 > test2-meta
+assert_file_has_content test2-meta "SIGNATURE"
 echo "ok metadata commit with strings"
 
 $OSTREE commit ${COMMIT_ARGS} -b test2 --tree=ref=test2 \