From f8fcdba0a542507917fe49a7b81b8932c6ce115e Mon Sep 17 00:00:00 2001 From: Yu Qi Zhang Date: Tue, 14 Jun 2016 14:13:06 +0000 Subject: [PATCH] refs: add "ostree refs --create" and unit tests Added the ability to create a ref (much like a git tag) for an existing commit through "ostree refs EXISTING --create=NEWREF". Previously the only way to create a new ref was by creating a new commit, but refs --create allows multiple refs to point to the same commit. The command will fail if: - None/more than one existing ref is specified - The specified EXISTING tag does not exist, or was not specified - The specified NEWREF already exists, or is the name of a folder Add unit tests in tests-ref.sh to verify above functionality Closes: #340 Approved by: jlebon --- src/ostree/ot-builtin-refs.c | 46 +++++++++++++++++++++++++++++++++++- tests/test-refs.sh | 31 ++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index af90c841..10647ec6 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -28,10 +28,12 @@ static gboolean opt_delete; static gboolean opt_list; +static char *opt_create; static GOptionEntry options[] = { { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", NULL }, { "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, "Do not remove the prefix from the refs", NULL }, + { "create", 0, 0, G_OPTION_ARG_STRING, &opt_create, "Create a new ref for an existing commit", "NEWREF" }, { NULL } }; @@ -48,10 +50,16 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab cancellable, error)) goto out; } + else if (opt_create) + { + if (!ostree_repo_list_refs_ext (repo, NULL, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, + cancellable, error)) + goto out; + } else if (!ostree_repo_list_refs (repo, refspec_prefix, &refs, cancellable, error)) goto out; - if (!opt_delete) + if (!opt_delete && !opt_create) { g_hash_table_iter_init (&hashiter, refs); while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) @@ -60,7 +68,30 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab g_print ("%s\n", ref); } } + else if (opt_create) + { + g_autofree char *checksum = NULL; + g_autofree char *checksum_existing = NULL; + + if (!ostree_repo_resolve_rev (repo, opt_create, TRUE, &checksum_existing, error)) + goto out; + + if (checksum_existing != NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "--create specified but ref %s already exists", opt_create); + goto out; + } + + if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error)) + goto out; + + if (!ostree_repo_set_ref_immediate (repo, NULL, opt_create, checksum, + cancellable, error)) + goto out; + } else + /* delete */ { g_hash_table_iter_init (&hashiter, refs); while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) @@ -97,6 +128,12 @@ ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError ** if (argc >= 2) { + if (opt_create && argc > 2) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "You must specify only 1 existing ref when creating a new ref"); + goto out; + } for (i = 1; i < argc; i++) if (!do_ref (repo, argv[i], cancellable, error)) goto out; @@ -110,6 +147,13 @@ ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError ** "At least one PREFIX is required when deleting refs"); goto out; } + else if (opt_create) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "You must specify an existing ref when creating a new ref"); + goto out; + } + ret = do_ref (repo, NULL, cancellable, error); } diff --git a/tests/test-refs.sh b/tests/test-refs.sh index bcebae9e..3d229031 100755 --- a/tests/test-refs.sh +++ b/tests/test-refs.sh @@ -65,4 +65,35 @@ ${CMD_PREFIX} ostree refs --repo=repo | wc -l > refscount.delete3 assert_file_has_content refscount.delete3 "^3$" assert_not_file_has_content reflist '^test-1$' +#Add a few more commits, to test --create +${CMD_PREFIX} ostree --repo=repo commit --branch=ctest -m ctest -s ctest tree +${CMD_PREFIX} ostree --repo=repo commit --branch=foo/ctest -m ctest -s ctest tree + +${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount +assert_file_has_content refscount "^5$" + +if ${CMD_PREFIX} ostree --repo=repo refs --create=ctest-new; then + assert_not_reached "refs --create unexpectedly succeeded without specifying an existing ref!" +fi +if ${CMD_PREFIX} ostree --repo=repo refs ctest --create; then + assert_not_reached "refs --create unexpectedly succeeded without specifying the ref to create!" +fi +if ${CMD_PREFIX} ostree --repo=repo refs does-not-exist --create=ctest-new; then + assert_not_reached "refs --create unexpectedly succeeded for a prefix that doesn't exist!" +fi +if ${CMD_PREFIX} ostree --repo=repo refs ctest --create=foo; then + assert_not_reached "refs --create unexpectedly succeeded for a prefix that is already in use by a folder!" +fi +if ${CMD_PREFIX} ostree --repo=repo refs foo/ctest --create=ctest; then + assert_not_reached "refs --create unexpectedly succeeded in overwriting an existing prefix!" +fi + +#Check to see if any uncleaned tmp files were created after failed --create +${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create1 +assert_file_has_content refscount.create1 "^5$" + +${CMD_PREFIX} ostree --repo=repo refs ctest --create ctest-new +${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create2 +assert_file_has_content refscount.create2 "^6$" + echo "ok refs"