CLAR_TEST_SUITES += u-example-decorate
CLAR_TEST_SUITES += u-hash
CLAR_TEST_SUITES += u-hashmap
+CLAR_TEST_SUITES += u-list-objects-filter-options
CLAR_TEST_SUITES += u-mem-pool
CLAR_TEST_SUITES += u-oid-array
CLAR_TEST_SUITES += u-oidmap
case LOFC_DISABLED:
/* we have no name for "no filter at all" */
break;
+ case LOFC_AUTO:
+ return "auto";
case LOFC_BLOB_NONE:
return "blob:none";
case LOFC_BLOB_LIMIT:
if (filter_options->choice)
BUG("filter_options already populated");
- if (!strcmp(arg, "blob:none")) {
+ if (!strcmp(arg, "auto")) {
+ if (!filter_options->allow_auto_filter) {
+ strbuf_addstr(
+ errbuf,
+ _("'auto' filter not supported by this command"));
+ return 1;
+ }
+ filter_options->choice = LOFC_AUTO;
+ return 0;
+
+ } else if (!strcmp(arg, "blob:none")) {
filter_options->choice = LOFC_BLOB_NONE;
return 0;
decoded = url_percent_decode(subspec->buf);
- result = has_reserved_character(subspec, errbuf) ||
- gently_parse_list_objects_filter(
+ result = has_reserved_character(subspec, errbuf);
+ if (result)
+ goto cleanup;
+
+ result = gently_parse_list_objects_filter(
&filter_options->sub[new_index], decoded, errbuf);
+ if (result)
+ goto cleanup;
+
+ result = (filter_options->sub[new_index].choice == LOFC_AUTO);
+ if (result)
+ strbuf_addstr(errbuf, _("an 'auto' filter cannot be combined"));
+cleanup:
free(decoded);
return result;
}
} else {
struct list_objects_filter_options *sub;
+ if (filter_options->choice == LOFC_AUTO)
+ die(_("an 'auto' filter is incompatible with any other filter"));
+
/*
* Make filter_options an LOFC_COMBINE spec so we can trivially
* add subspecs to it.
if (gently_parse_list_objects_filter(sub, arg, &errbuf))
die("%s", errbuf.buf);
+ if (sub->choice == LOFC_AUTO)
+ die(_("an 'auto' filter is incompatible with any other filter"));
+
strbuf_addch(&filter_options->filter_spec, '+');
filter_spec_append_urlencode(filter_options, arg);
}
struct list_objects_filter_options *filter_options)
{
size_t sub;
+ unsigned int allow_auto_filter = filter_options->allow_auto_filter;
if (!filter_options)
return;
list_objects_filter_release(&filter_options->sub[sub]);
free(filter_options->sub);
list_objects_filter_init(filter_options);
+ filter_options->allow_auto_filter = allow_auto_filter;
}
void partial_clone_register(
LOFC_SPARSE_OID,
LOFC_OBJECT_TYPE,
LOFC_COMBINE,
+ LOFC_AUTO,
LOFC__COUNT /* must be last */
};
*/
unsigned int no_filter : 1;
+ /*
+ * Is LOFC_AUTO a valid option?
+ */
+ unsigned int allow_auto_filter : 1;
+
/*
* BEGIN choice-specific parsed values from within the filter-spec. Only
* some values will be defined for any given choice.
filter->finalize_omits_fn = filter_combine__finalize_omits;
}
+static void filter_auto__init(
+ struct list_objects_filter_options *filter_options UNUSED,
+ struct filter *filter UNUSED)
+{
+ BUG("LOFC_AUTO should have been resolved before initializing the filter");
+}
+
typedef void (*filter_init_fn)(
struct list_objects_filter_options *filter_options,
struct filter *filter);
filter_sparse_oid__init,
filter_object_type__init,
filter_combine__init,
+ filter_auto__init,
};
struct filter *list_objects_filter__init(
'unit-tests/u-example-decorate.c',
'unit-tests/u-hash.c',
'unit-tests/u-hashmap.c',
+ 'unit-tests/u-list-objects-filter-options.c',
'unit-tests/u-mem-pool.c',
'unit-tests/u-oid-array.c',
'unit-tests/u-oidmap.c',
--- /dev/null
+#include "unit-test.h"
+#include "list-objects-filter-options.h"
+#include "strbuf.h"
+
+/* Helper to test gently_parse_list_objects_filter() */
+static void check_gentle_parse(const char *filter_spec,
+ int expect_success,
+ int allow_auto,
+ enum list_objects_filter_choice expected_choice)
+{
+ struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
+ struct strbuf errbuf = STRBUF_INIT;
+ int ret;
+
+ filter_options.allow_auto_filter = allow_auto;
+
+ ret = gently_parse_list_objects_filter(&filter_options, filter_spec, &errbuf);
+
+ if (expect_success) {
+ cl_assert_equal_i(ret, 0);
+ cl_assert_equal_i(expected_choice, filter_options.choice);
+ cl_assert_equal_i(errbuf.len, 0);
+ } else {
+ cl_assert(ret != 0);
+ cl_assert(errbuf.len > 0);
+ }
+
+ strbuf_release(&errbuf);
+ list_objects_filter_release(&filter_options);
+}
+
+void test_list_objects_filter_options__regular_filters(void)
+{
+ check_gentle_parse("blob:none", 1, 0, LOFC_BLOB_NONE);
+ check_gentle_parse("blob:none", 1, 1, LOFC_BLOB_NONE);
+ check_gentle_parse("blob:limit=5k", 1, 0, LOFC_BLOB_LIMIT);
+ check_gentle_parse("blob:limit=5k", 1, 1, LOFC_BLOB_LIMIT);
+ check_gentle_parse("combine:blob:none+tree:0", 1, 0, LOFC_COMBINE);
+ check_gentle_parse("combine:blob:none+tree:0", 1, 1, LOFC_COMBINE);
+}
+
+void test_list_objects_filter_options__auto_allowed(void)
+{
+ check_gentle_parse("auto", 1, 1, LOFC_AUTO);
+ check_gentle_parse("auto", 0, 0, 0);
+}
+
+void test_list_objects_filter_options__combine_auto_fails(void)
+{
+ check_gentle_parse("combine:auto+blob:none", 0, 1, 0);
+ check_gentle_parse("combine:blob:none+auto", 0, 1, 0);
+ check_gentle_parse("combine:auto+auto", 0, 1, 0);
+}