gboolean
flatpak_builtin_ls_remote (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter iter;
  gpointer key;
  gpointer value;
  g_autoptr(GHashTable) names = NULL;
  guint n_keys;
  g_autofree const char **keys = NULL;
  int i;
  const char *repository;
  const char **arches = flatpak_get_arches ();
  const char *opt_arches[] = {NULL, NULL};

  context = g_option_context_new (_(" REMOTE - Show available runtimes and applications"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error))
    return FALSE;

  if (!opt_app && !opt_runtime)
    opt_app = opt_runtime = TRUE;

  if (argc < 2)
    return usage_error (context, _("REMOTE must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  repository = argv[1];


  if (!flatpak_dir_list_remote_refs (dir,
                                     repository,
                                     &refs,
                                     cancellable, error))
    return FALSE;

  names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  if (opt_arch != NULL)
    {
      if (strcmp (opt_arch, "*") == 0)
        arches = NULL;
      else
        {
          opt_arches[0] = opt_arch;
          arches = opt_arches;
        }
    }

  g_hash_table_iter_init (&iter, refs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *ref = key;
      const char *checksum = value;
      const char *name = NULL;
      g_auto(GStrv) parts = NULL;

      parts = flatpak_decompose_ref (ref, NULL);
      if (parts == NULL)
        {
          g_debug ("Invalid remote ref %s\n", ref);
          continue;
        }

      if (opt_only_updates)
        {
          g_autofree char *deployed = NULL;

          deployed = flatpak_dir_read_active (dir, ref, cancellable);
          if (deployed == NULL)
            continue;

          if (g_strcmp0 (deployed, checksum) == 0)
            continue;
        }

      if (arches != NULL && !g_strv_contains (arches, parts[2]))
        continue;

      if (strcmp (parts[0], "runtime") == 0 && !opt_runtime)
        continue;

      if (strcmp (parts[0], "app") == 0 && !opt_app)
        continue;

      if (!opt_show_details)
        name = parts[1];
      else
        name = ref;

      if (g_hash_table_lookup (names, name) == NULL)
        g_hash_table_insert (names, g_strdup (name), g_strdup (checksum));
    }

  keys = (const char **) g_hash_table_get_keys_as_array (names, &n_keys);
  g_qsort_with_data (keys, n_keys, sizeof (char *), (GCompareDataFunc) flatpak_strcmp0_ptr, NULL);

  FlatpakTablePrinter *printer = flatpak_table_printer_new ();

  for (i = 0; i < n_keys; i++)
    {
      flatpak_table_printer_add_column (printer, keys[i]);
      if (opt_show_details)
        {
          g_autofree char *value = NULL;

          value = g_strdup ((char *) g_hash_table_lookup (names, keys[i]));
          value[MIN (strlen (value), 12)] = 0;
          flatpak_table_printer_add_column (printer, value);
        }
      flatpak_table_printer_finish_row (printer);
    }

  flatpak_table_printer_print (printer);
  flatpak_table_printer_free (printer);

  return TRUE;
}
Exemple #2
0
gboolean
flatpak_option_context_parse (GOptionContext     *context,
                              const GOptionEntry *main_entries,
                              int                *argc,
                              char             ***argv,
                              FlatpakBuiltinFlags flags,
                              FlatpakDir        **out_dir,
                              GCancellable       *cancellable,
                              GError            **error)
{
  g_autoptr(FlatpakDir) dir = NULL;

  if (!(flags & FLATPAK_BUILTIN_FLAG_NO_DIR))
    g_option_context_add_main_entries (context, user_entries, NULL);

  if (main_entries != NULL)
    g_option_context_add_main_entries (context, main_entries, NULL);

  g_option_context_add_main_entries (context, global_entries, NULL);

  if (!g_option_context_parse (context, argc, argv, error))
    return FALSE;

  if (opt_version)
    {
      g_print ("%s\n", PACKAGE_STRING);
      exit (EXIT_SUCCESS);
    }

  if (opt_default_arch)
    {
      g_print ("%s\n", flatpak_get_arch ());
      exit (EXIT_SUCCESS);
    }

  if (opt_supported_arches)
    {
      const char **arches = flatpak_get_arches ();
      int i;
      for (i = 0; arches[i] != NULL; i++)
        g_print ("%s\n", arches[i]);
      exit (EXIT_SUCCESS);
    }

  if (!(flags & FLATPAK_BUILTIN_FLAG_NO_DIR))
    {
      dir = flatpak_dir_get (opt_user);

      if (!flatpak_dir_ensure_path (dir, cancellable, error))
        return FALSE;

      if (!(flags & FLATPAK_BUILTIN_FLAG_NO_REPO) &&
          !flatpak_dir_ensure_repo (dir, cancellable, error))
        return FALSE;
    }

  if (opt_verbose)
    g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);

  if (out_dir)
    *out_dir = g_steal_pointer (&dir);

  return TRUE;
}