Allow sequence REFSPECs for version/list.

API probably needs to move to ostree library. Allows us to get a "list"
of REFSPECs, Eg.

"<newest>..<oldest>"

...as a REFSPEC will turn into a list of all the commits, inclusive.
This commit is contained in:
James Antill 2014-07-16 00:48:20 -04:00
parent c88545d272
commit 634541f722

View File

@ -158,7 +158,7 @@ struct RpmHeaders
/* find a common prefix length that doesn't need fnmatch */ /* find a common prefix length that doesn't need fnmatch */
static size_t static size_t
pat_fnmatch_prefix (GPtrArray *patterns) pat_fnmatch_prefix (const GPtrArray *patterns)
{ {
gsize ret = G_MAXSIZE; gsize ret = G_MAXSIZE;
int num = 0; int num = 0;
@ -198,7 +198,7 @@ pat_fnmatch_prefix (GPtrArray *patterns)
static gboolean static gboolean
pat_fnmatch_match (Header pkg, const char *name, pat_fnmatch_match (Header pkg, const char *name,
gsize patprefixlen, GPtrArray *patterns) gsize patprefixlen, const GPtrArray *patterns)
{ {
int num = 0; int num = 0;
gs_free char *pkg_na = NULL; gs_free char *pkg_na = NULL;
@ -234,7 +234,7 @@ pat_fnmatch_match (Header pkg, const char *name,
} }
static struct RpmHeaders * static struct RpmHeaders *
rpmhdrs_new (const char *root, GPtrArray *patterns) rpmhdrs_new (const char *root, const GPtrArray *patterns)
{ {
rpmts ts = rpmtsCreate(); rpmts ts = rpmtsCreate();
int status = -1; int status = -1;
@ -242,7 +242,7 @@ rpmhdrs_new (const char *root, GPtrArray *patterns)
Header h1; Header h1;
GPtrArray *hs = NULL; GPtrArray *hs = NULL;
struct RpmHeaders *ret = NULL; struct RpmHeaders *ret = NULL;
gsize patprefixlen = pat_fnmatch_prefix (patterns);; gsize patprefixlen = pat_fnmatch_prefix (patterns);
rpmtsSetVSFlags (ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); rpmtsSetVSFlags (ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES);
@ -561,7 +561,7 @@ _RPMOSTREE_DEFINE_TRIVIAL_CLEANUP_FUNC(struct RpmRevisionData *, rpmrev_free);
static struct RpmRevisionData * static struct RpmRevisionData *
rpmrev_new (OstreeRepo *repo, GFile *rpmdbdir, const char *rev, rpmrev_new (OstreeRepo *repo, GFile *rpmdbdir, const char *rev,
GPtrArray *patterns, const GPtrArray *patterns,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
@ -622,6 +622,242 @@ rpmrev_new (OstreeRepo *repo, GFile *rpmdbdir, const char *rev,
return rpmrev; return rpmrev;
} }
static char *
ost_get_prev_commit(OstreeRepo *repo, char *checksum)
{
char *ret = NULL;
gs_unref_variant GVariant *commit = NULL;
gs_unref_variant GVariant *parent_csum_v = NULL;
GError *tmp_error = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum,
&commit, &tmp_error))
goto out;
g_variant_get_child (commit, 1, "@ay", &parent_csum_v);
if (g_variant_n_children (parent_csum_v) == 0)
goto out;
ret = ostree_checksum_from_bytes_v (parent_csum_v);
out:
g_clear_error (&tmp_error);
return ret;
}
#if 0
/* glib? */
static void
_gptr_array_reverse (GPtrArray *data)
{
gpointer *ptr = NULL;
guint num = 0;
g_assert (data);
ptr = data->pdata;
num = data->len;
while (num >= 2)
{
void *swap = ptr[0];
ptr[0] = ptr[num-1];
ptr[num-1] = swap;
num -= 2;
ptr++;
}
}
#endif
static GPtrArray *
ost_get_commit_hashes(OstreeRepo *repo, const char *beg, const char *end,
GError **error)
{
char *parent = NULL;
GPtrArray *ret = NULL;
char *checksum = NULL;
char *end_checksum = NULL;
if (!ostree_repo_read_commit (repo, beg, NULL, &checksum, NULL, error))
goto out;
ret = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (ret, g_strdup (beg));
if (end &&
!ostree_repo_read_commit (repo, end, NULL, &end_checksum, NULL, error))
goto out;
if (end && g_str_equal (end_checksum, checksum))
goto success_out;
while ((parent = ost_get_prev_commit (repo, checksum)))
{
if (end && g_str_equal (end_checksum, parent))
break;
g_ptr_array_add (ret, parent);
checksum = parent;
}
if (end && !parent)
goto out;
if (end)
g_ptr_array_add (ret, g_strdup (end));
success_out:
g_free (end_checksum);
end_checksum = NULL;
// _gptr_array_reverse (ret);
out:
if (end_checksum)
{
g_free (end_checksum);
g_ptr_array_free (ret, TRUE);
ret = NULL;
}
return ret;
}
static GPtrArray *
cmdline2ptrarray(int argc, char *argv[])
{
GPtrArray *ret = NULL;
while (argc--)
{
if (!ret)
ret = g_ptr_array_new ();
g_ptr_array_add (ret, *argv++);
}
return ret;
}
static void
_prnt_commit_line(const char *rev, struct RpmRevisionData *rpmrev)
{
if (!g_str_equal (rev, rpmrev->commit))
printf ("ostree commit: %s (%s)\n", rev, rpmrev->commit);
else
printf ("ostree commit: %s\n", rev);
}
static gboolean
_builtin_rpm_version(OstreeRepo *repo, GFile *rpmdbdir, GPtrArray *revs,
GCancellable *cancellable,
GError **error)
{
int num = 0;
gboolean ret = FALSE;
for (num = 0; num < revs->len; num++)
{
char *rev = revs->pdata[num];
_cleanup_rpmrev_ struct RpmRevisionData *rpmrev = NULL;
gs_free char *rpmdbv = NULL;
char *mrev = strstr (rev, "..");
if (mrev)
{
gs_unref_ptrarray GPtrArray *range_revs = NULL;
gs_free char *revdup = g_strdup (rev);
mrev = revdup + (mrev - rev);
*mrev = 0;
mrev += 2;
if (!*mrev)
mrev = NULL;
if (!(range_revs = ost_get_commit_hashes (repo, revdup, mrev, error)))
/* treat none valid ranges as weird tags?? */
goto none_range_rev;
if (!_builtin_rpm_version (repo, rpmdbdir, range_revs,
cancellable, error))
goto out;
continue;
}
none_range_rev:
rpmrev = rpmrev_new (repo, rpmdbdir, rev, NULL, cancellable, error);
if (!rpmrev)
goto out;
rpmdbv = rpmhdrs_rpmdbv (rpmrev->root, rpmrev->rpmdb,
cancellable, error);
// FIXME: g_console?
_prnt_commit_line (rev, rpmrev);
printf (" rpmdbv is: %24s%s\n", "", rpmdbv);
}
ret = TRUE;
out:
return ret;
}
static gboolean
_builtin_rpm_list(OstreeRepo *repo, GFile *rpmdbdir,
GPtrArray *revs, const GPtrArray *patterns,
GCancellable *cancellable,
GError **error)
{
int num = 0;
gboolean ret = FALSE;
for (num = 0; num < revs->len; num++)
{
char *rev = revs->pdata[num];
_cleanup_rpmrev_ struct RpmRevisionData *rpmrev = NULL;
char *mrev = strstr (rev, "..");
if (mrev)
{
gs_unref_ptrarray GPtrArray *range_revs = NULL;
gs_free char *revdup = g_strdup (rev);
mrev = revdup + (mrev - rev);
*mrev = 0;
mrev += 2;
if (!*mrev)
mrev = NULL;
if (!(range_revs = ost_get_commit_hashes (repo, revdup, mrev, error)))
/* treat none valid ranges as weird tags?? */
goto none_range_rev;
if (!_builtin_rpm_list (repo, rpmdbdir, range_revs, patterns,
cancellable, error))
goto out;
continue;
}
none_range_rev:
rpmrev = rpmrev_new (repo, rpmdbdir, rev, patterns,
cancellable, error);
if (!rpmrev)
goto out;
_prnt_commit_line (rev, rpmrev);
rpmhdrs_list (rpmrev->root, rpmrev->rpmdb, cancellable, error);
}
ret = TRUE;
out:
return ret;
}
gboolean gboolean
rpmostree_builtin_rpm (int argc, rpmostree_builtin_rpm (int argc,
char **argv, char **argv,
@ -635,22 +871,17 @@ rpmostree_builtin_rpm (int argc,
gs_unref_object GFile *rpmdbdir = NULL; gs_unref_object GFile *rpmdbdir = NULL;
gboolean rpmdbdir_is_tmp = FALSE; gboolean rpmdbdir_is_tmp = FALSE;
const char *cmd = NULL; const char *cmd = NULL;
int argnum = 2;
g_option_context_add_main_entries (context, option_entries, NULL); g_option_context_add_main_entries (context, option_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, error)) if (!g_option_context_parse (context, &argc, &argv, error))
goto out; goto out;
if (argc < 2)
if (argc < 3) goto help_output;
{
g_printerr ("usage: rpm-ostree rpm diff|list|version COMMIT...\n");
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Argument processing failed");
goto out;
}
cmd = argv[1]; cmd = argv[1];
if (argc < 3)
goto help_output;
if ((g_str_equal (cmd, "diff")) && (argc != 4)) if ((g_str_equal (cmd, "diff")) && (argc != 4))
{ {
@ -689,33 +920,20 @@ rpmostree_builtin_rpm (int argc,
rpmdbdir = g_file_new_for_path (opt_rpmdbdir); rpmdbdir = g_file_new_for_path (opt_rpmdbdir);
} }
else else
{ { // tmp n tmpfs is much faster than /var/tmp ...
gs_free char *tmpd = g_mkdtemp (g_strdup ("/var/tmp/rpm-ostree.XXXXXX")); // and rpmdb on their own shouldn't be too big.
gs_free char *tmpd = g_mkdtemp (g_strdup ("/tmp/rpm-ostree.XXXXXX"));
rpmdbdir = g_file_new_for_path (tmpd); rpmdbdir = g_file_new_for_path (tmpd);
rpmdbdir_is_tmp = TRUE; rpmdbdir_is_tmp = TRUE;
} }
if (FALSE) {} if (FALSE) {}
else if (g_str_equal(cmd, "version")) else if (g_str_equal(cmd, "version"))
for (; argnum < argc; ++argnum)
{ {
const char *rev = argv[argnum]; gs_unref_ptrarray GPtrArray *revs = cmdline2ptrarray (argc - 2, argv + 2);
_cleanup_rpmrev_ struct RpmRevisionData *rpmrev = NULL;
gs_free char *rpmdbv = NULL;
rpmrev = rpmrev_new (repo, rpmdbdir, rev, NULL, cancellable, error); if (!_builtin_rpm_version (repo, rpmdbdir, revs, cancellable, error))
if (!rpmrev)
goto out; goto out;
rpmdbv = rpmhdrs_rpmdbv (rpmrev->root, rpmrev->rpmdb,
cancellable, error);
// FIXME: g_console
if (!g_str_equal (rev, rpmrev->commit))
printf ("ostree commit: %s (%s)\n", rev, rpmrev->commit);
else
printf ("ostree commit: %s\n", rev);
printf (" rpmdbv is: %24s%s\n", "", rpmdbv);
} }
else if (g_str_equal (cmd, "diff")) else if (g_str_equal (cmd, "diff"))
{ {
@ -747,6 +965,7 @@ rpmostree_builtin_rpm (int argc,
int listnum = argc - 3; int listnum = argc - 3;
char **listargv = argv + 2; char **listargv = argv + 2;
char *commit; char *commit;
gs_unref_ptrarray GPtrArray *revs = NULL;
// Find first commit arg. ... all before it are list args. // Find first commit arg. ... all before it are list args.
while ((listnum > 0) && while ((listnum > 0) &&
@ -759,37 +978,22 @@ rpmostree_builtin_rpm (int argc,
argc -= listnum; argc -= listnum;
argv += listnum; argv += listnum;
if (listnum)
{
patterns = g_ptr_array_new ();
while (listnum--)
g_ptr_array_add (patterns, *listargv++);
}
for (; argnum < argc; ++argnum) patterns = cmdline2ptrarray (listnum, listargv);
{ revs = cmdline2ptrarray (argc - 2, argv + 2);
const char *rev = argv[argnum];
_cleanup_rpmrev_ struct RpmRevisionData *rpmrev = NULL;
rpmrev = rpmrev_new (repo, rpmdbdir, rev, patterns, if (!_builtin_rpm_list (repo, rpmdbdir, revs, patterns,
cancellable, error); cancellable, error))
if (!rpmrev)
goto out; goto out;
if (!g_str_equal (rev, rpmrev->commit))
printf ("ostree commit: %s (%s)\n", rev, rpmrev->commit);
else
printf ("ostree commit: %s\n", rev);
rpmhdrs_list (rpmrev->root, rpmrev->rpmdb, cancellable, error);
}
} }
else else
{ {
help_output:
g_printerr ("rpm-ostree rpm SUB-COMMANDS:\n"); g_printerr ("rpm-ostree rpm SUB-COMMANDS:\n");
g_printerr (" diff COMMIT COMMIT\n"); g_printerr (" diff COMMIT COMMIT\n");
g_printerr (" list [prefix-pkgname...] COMMIT...\n"); g_printerr (" list [prefix-pkgname...] COMMIT...\n");
g_printerr (" version COMMIT...\n"); g_printerr (" version COMMIT...\n");
if (cmd && !g_str_equal (cmd, "help"))
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Command processing failed"); "Command processing failed");
goto out; goto out;