@@ -722,6 +722,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
TEST_BUILTINS_OBJS += test-advise.o
TEST_BUILTINS_OBJS += test-bitmap.o
TEST_BUILTINS_OBJS += test-bloom.o
+TEST_BUILTINS_OBJS += test-bundle-uri.o
TEST_BUILTINS_OBJS += test-chmtime.o
TEST_BUILTINS_OBJS += test-config.o
TEST_BUILTINS_OBJS += test-crontab.o
@@ -66,6 +66,39 @@ int for_all_bundles_in_list(struct bundle_list *list,
return 0;
}
+static int summarize_bundle(struct remote_bundle_info *info, void *data)
+{
+ FILE *fp = data;
+ fprintf(fp, "[bundle \"%s\"]\n", info->id);
+ fprintf(fp, "\turi = %s\n", info->uri);
+ return 0;
+}
+
+void print_bundle_list(FILE *fp, struct bundle_list *list)
+{
+ const char *mode;
+
+ switch (list->mode) {
+ case BUNDLE_MODE_ALL:
+ mode = "all";
+ break;
+
+ case BUNDLE_MODE_ANY:
+ mode = "any";
+ break;
+
+ case BUNDLE_MODE_NONE:
+ default:
+ mode = "<unknown>";
+ }
+
+ fprintf(fp, "[bundle]\n");
+ fprintf(fp, "\tversion = %d\n", list->version);
+ fprintf(fp, "\tmode = %s\n", mode);
+
+ for_all_bundles_in_list(list, summarize_bundle, fp);
+}
+
/**
* Given a key-value pair, update the state of the given bundle list.
* Returns 0 if the key-value pair is understood. Returns -1 if the key
@@ -59,6 +59,9 @@ int for_all_bundles_in_list(struct bundle_list *list,
bundle_iterator iter,
void *data);
+struct FILE;
+void print_bundle_list(FILE *fp, struct bundle_list *list);
+
/**
* Fetch data from the given 'uri' and unbundle the bundle data found
* based on that information.
new file mode 100644
@@ -0,0 +1,70 @@
+#include "test-tool.h"
+#include "parse-options.h"
+#include "bundle-uri.h"
+#include "strbuf.h"
+#include "string-list.h"
+
+static int cmd__bundle_uri_parse(int argc, const char **argv)
+{
+ const char *key_value_usage[] = {
+ "test-tool bundle-uri parse-key-values <input>",
+ NULL
+ };
+ const char **usage = key_value_usage;
+ struct option options[] = {
+ OPT_END(),
+ };
+ struct strbuf sb = STRBUF_INIT;
+ struct bundle_list list;
+ int err = 0;
+ FILE *fp;
+
+ argc = parse_options(argc, argv, NULL, options, usage, 0);
+ if (argc != 1)
+ goto usage;
+
+ init_bundle_list(&list);
+ fp = fopen(argv[0], "r");
+ if (!fp)
+ die("failed to open '%s'", argv[0]);
+
+ while (strbuf_getline(&sb, fp) != EOF) {
+ if (bundle_uri_parse_line(&list, sb.buf))
+ err = error("bad line: '%s'", sb.buf);
+ }
+ strbuf_release(&sb);
+ fclose(fp);
+
+ print_bundle_list(stdout, &list);
+
+ clear_bundle_list(&list);
+
+ return !!err;
+
+usage:
+ usage_with_options(usage, options);
+}
+
+int cmd__bundle_uri(int argc, const char **argv)
+{
+ const char *usage[] = {
+ "test-tool bundle-uri <subcommand> [<options>]",
+ NULL
+ };
+ struct option options[] = {
+ OPT_END(),
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage,
+ PARSE_OPT_STOP_AT_NON_OPTION |
+ PARSE_OPT_KEEP_ARGV0);
+ if (argc == 1)
+ goto usage;
+
+ if (!strcmp(argv[1], "parse-key-values"))
+ return cmd__bundle_uri_parse(argc - 1, argv + 1);
+ error("there is no test-tool bundle-uri tool '%s'", argv[1]);
+
+usage:
+ usage_with_options(usage, options);
+}
@@ -17,6 +17,7 @@ static struct test_cmd cmds[] = {
{ "advise", cmd__advise_if_enabled },
{ "bitmap", cmd__bitmap },
{ "bloom", cmd__bloom },
+ { "bundle-uri", cmd__bundle_uri },
{ "chmtime", cmd__chmtime },
{ "config", cmd__config },
{ "crontab", cmd__crontab },
@@ -7,6 +7,7 @@
int cmd__advise_if_enabled(int argc, const char **argv);
int cmd__bitmap(int argc, const char **argv);
int cmd__bloom(int argc, const char **argv);
+int cmd__bundle_uri(int argc, const char **argv);
int cmd__chmtime(int argc, const char **argv);
int cmd__config(int argc, const char **argv);
int cmd__crontab(int argc, const char **argv);
new file mode 100755
@@ -0,0 +1,121 @@
+#!/bin/sh
+
+test_description="Test bundle-uri bundle_uri_parse_line()"
+
+TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'bundle_uri_parse_line() just URIs' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+ bundle.two.uri=https://example.com/bundle.bdl
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: empty key or value' '
+ cat >in <<-\EOF &&
+ =bogus-value
+ bogus-key=
+ EOF
+
+ cat >err.expect <<-EOF &&
+ error: bundle-uri: line has empty key or value
+ error: bad line: '\''=bogus-value'\''
+ error: bundle-uri: line has empty key or value
+ error: bad line: '\''bogus-key='\''
+ EOF
+
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: empty lines' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+
+ bundle.two.uri=https://example.com/bundle.bdl
+
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >err.expect <<-\EOF &&
+ error: bundle-uri: got an empty line
+ error: bad line: '\'''\''
+ error: bundle-uri: got an empty line
+ error: bad line: '\'''\''
+ EOF
+
+ # We fail, but try to continue parsing regardless
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_expect_success 'bundle_uri_parse_line() parsing edge cases: duplicate lines' '
+ cat >in <<-\EOF &&
+ bundle.one.uri=http://example.com/bundle.bdl
+ bundle.two.uri=https://example.com/bundle.bdl
+ bundle.one.uri=https://example.com/bundle-2.bdl
+ bundle.three.uri=file:///usr/share/git/bundle.bdl
+ EOF
+
+ cat >err.expect <<-\EOF &&
+ error: bad line: '\''bundle.one.uri=https://example.com/bundle-2.bdl'\''
+ EOF
+
+ # We fail, but try to continue parsing regardless
+ cat >expect <<-\EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ [bundle "one"]
+ uri = http://example.com/bundle.bdl
+ [bundle "two"]
+ uri = https://example.com/bundle.bdl
+ [bundle "three"]
+ uri = file:///usr/share/git/bundle.bdl
+ EOF
+
+ test_must_fail test-tool bundle-uri parse-key-values in >actual 2>err &&
+ test_cmp err.expect err &&
+ test_cmp_config_output expect actual
+'
+
+test_done
@@ -1956,3 +1956,14 @@ test_is_magic_mtime () {
rm -f .git/test-mtime-actual
return $ret
}
+
+# Given two filenames, parse both using 'git config --list --file'
+# and compare the sorted output of those commands. Useful when
+# wanting to ignore whitespace differences and sorting concerns.
+test_cmp_config_output () {
+ git config --list --file="$1" >config-expect &&
+ git config --list --file="$2" >config-actual &&
+ sort config-expect >sorted-expect &&
+ sort config-actual >sorted-actual &&
+ test_cmp sorted-expect sorted-actual
+}