Skip to content

Commit 3a3722e

Browse files
lucasoshirogitster
authored andcommitted
repo-info: add the field references.format
Add the field references.format to the repo-info command. The data retrieved in this field is the same that currently is obtained by running `git rev-parse --show-ref-format`. Mentored-by: Karthik Nayak <[email protected]> Mentored-by Patrick Steinhardt <[email protected]> Signed-off-by: Lucas Seiki Oshiro <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4d04f20 commit 3a3722e

File tree

2 files changed

+162
-4
lines changed

2 files changed

+162
-4
lines changed

builtin/repo-info.c

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,56 @@
11
#include "builtin.h"
22
#include "json-writer.h"
33
#include "parse-options.h"
4+
#include "quote.h"
5+
#include "refs.h"
46

57
enum output_format {
68
FORMAT_JSON,
79
FORMAT_PLAINTEXT
810
};
911

12+
enum repo_info_category {
13+
CATEGORY_REFERENCES = 1 << 0
14+
};
15+
16+
enum repo_info_references_field {
17+
FIELD_REFERENCES_FORMAT = 1 << 0
18+
};
19+
20+
struct repo_info_field {
21+
enum repo_info_category category;
22+
union {
23+
enum repo_info_references_field references;
24+
} field;
25+
};
26+
1027
struct repo_info {
1128
struct repository *repo;
1229
enum output_format format;
30+
int n_fields;
31+
struct repo_info_field *fields;
1332
};
1433

34+
static struct repo_info_field default_fields[] = {
35+
{
36+
.category = CATEGORY_REFERENCES,
37+
.field.references = FIELD_REFERENCES_FORMAT
38+
}
39+
};
40+
41+
static void print_key_value(const char *key, const char *value) {
42+
printf("%s=", key);
43+
quote_c_style(value, NULL, stdout, 0);
44+
putchar('\n');
45+
}
46+
1547
static void repo_info_init(struct repo_info *repo_info,
1648
struct repository *repo,
17-
char *format)
49+
char *format,
50+
int allow_empty,
51+
int argc, const char **argv)
1852
{
53+
int i;
1954
repo_info->repo = repo;
2055

2156
if (format == NULL || !strcmp(format, "json"))
@@ -24,19 +59,83 @@ static void repo_info_init(struct repo_info *repo_info,
2459
repo_info->format = FORMAT_PLAINTEXT;
2560
else
2661
die("invalid format %s", format);
62+
63+
if (argc == 0 && !allow_empty) {
64+
repo_info->n_fields = ARRAY_SIZE(default_fields);
65+
repo_info->fields = default_fields;
66+
} else {
67+
repo_info->n_fields = argc;
68+
ALLOC_ARRAY(repo_info->fields, argc);
69+
70+
for (i = 0; i < argc; i++) {
71+
const char *arg = argv[i];
72+
struct repo_info_field *field = repo_info->fields + i;
73+
74+
if (!strcmp(arg, "references.format")) {
75+
field->category = CATEGORY_REFERENCES;
76+
field->field.references = FIELD_REFERENCES_FORMAT;
77+
} else {
78+
die("invalid field '%s'", arg);
79+
}
80+
}
81+
}
2782
}
2883

29-
static void repo_info_print_plaintext(struct repo_info *repo_info UNUSED)
84+
static void repo_info_release(struct repo_info *repo_info)
3085
{
86+
if (repo_info->fields != default_fields) free(repo_info->fields);
3187
}
3288

33-
static void repo_info_print_json(struct repo_info *repo_info UNUSED)
89+
static void repo_info_print_plaintext(struct repo_info *repo_info) {
90+
struct repository *repo = repo_info->repo;
91+
int i;
92+
for (i = 0; i < repo_info->n_fields; i++) {
93+
struct repo_info_field *field = &repo_info->fields[i];
94+
switch (field->category) {
95+
case CATEGORY_REFERENCES:
96+
switch (field->field.references) {
97+
case FIELD_REFERENCES_FORMAT:
98+
print_key_value("references.format",
99+
ref_storage_format_to_name(
100+
repo->ref_storage_format));
101+
break;
102+
}
103+
break;
104+
}
105+
}
106+
}
107+
108+
static void repo_info_print_json(struct repo_info *repo_info)
34109
{
35110
struct json_writer jw;
111+
int i;
112+
unsigned int categories = 0;
113+
unsigned int references_fields = 0;
114+
struct repository *repo = repo_info->repo;
115+
116+
for (i = 0; i < repo_info->n_fields; i++) {
117+
struct repo_info_field *field = repo_info->fields + i;
118+
categories |= field->category;
119+
switch (field->category) {
120+
case CATEGORY_REFERENCES:
121+
references_fields |= field->field.references;
122+
break;
123+
}
124+
}
36125

37126
jw_init(&jw);
38127

39128
jw_object_begin(&jw, 1);
129+
130+
if (categories & CATEGORY_REFERENCES) {
131+
jw_object_inline_begin_object(&jw, "references");
132+
if (references_fields & FIELD_REFERENCES_FORMAT) {
133+
const char *format_name = ref_storage_format_to_name(
134+
repo->ref_storage_format);
135+
jw_object_string(&jw, "format", format_name);
136+
}
137+
jw_end(&jw);
138+
}
40139
jw_end(&jw);
41140

42141
puts(jw.json.buf);
@@ -79,8 +178,9 @@ int cmd_repo_info(int argc,
79178

80179
argc = parse_options(argc, argv, prefix, options, repo_info_usage,
81180
PARSE_OPT_KEEP_UNKNOWN_OPT);
82-
repo_info_init(&repo_info, repo, format);
181+
repo_info_init(&repo_info, repo, format, allow_empty, argc, argv);
83182
repo_info_print(&repo_info);
183+
repo_info_release(&repo_info);
84184

85185
return 0;
86186
}

t/t1900-repo-info.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
66

77
. ./test-lib.sh
88

9+
DEFAULT_NUMBER_OF_FIELDS=1
10+
911
parse_json () {
1012
tr '\n' ' ' | "$PERL_PATH" "$TEST_DIRECTORY/t0019/parse_json.perl"
1113
}
@@ -14,6 +16,45 @@ test_lazy_prereq PERLJSON '
1416
perl -MJSON -e "exit 0"
1517
'
1618

19+
# Test if a field is correctly returned in both plaintext and json formats.
20+
#
21+
# Usage: test_repo_info <label> <init command> <key> <expected value>
22+
#
23+
# Arguments:
24+
# label: the label of the test
25+
# init command: a command that creates a repository called 'repo', configured
26+
# accordingly to what is being tested
27+
# key: the key of the field that is being tested
28+
# expected value: the value that the field should contain
29+
test_repo_info () {
30+
label=$1
31+
init_command=$2
32+
key=$3
33+
expected_value=$4
34+
35+
test_expect_success PERLJSON "json: $label" "
36+
test_when_finished 'rm -rf repo' &&
37+
'$SHELL_PATH' -c '$init_command' &&
38+
cd repo &&
39+
echo '$expected_value' >expect &&
40+
git repo-info '$key' >output &&
41+
cat output | parse_json >parsed &&
42+
grep -F 'row[0].$key' parsed | cut -d ' ' -f 2 >value &&
43+
cat value | sed 's/^0$/false/' | sed 's/^1$/true/' >actual &&
44+
test_cmp expect actual
45+
"
46+
47+
test_expect_success "plaintext: $label" "
48+
test_when_finished 'rm -rf repo' &&
49+
'$SHELL_PATH' -c '$init_command' &&
50+
cd repo &&
51+
echo '$expected_value' >expect &&
52+
git repo-info --format=plaintext '$key' >output &&
53+
cat output | cut -d '=' -f 2 >actual &&
54+
test_cmp expect actual
55+
"
56+
}
57+
1758
test_expect_success PERLJSON 'json: returns empty output with allow-empty' '
1859
git repo-info --allow-empty --format=json >output &&
1960
test_line_count = 2 output
@@ -24,4 +65,21 @@ test_expect_success 'plaintext: returns empty output with allow-empty' '
2465
test_line_count = 0 output
2566
'
2667

68+
test_repo_info 'ref format files is retrieved correctly' '
69+
git init --ref-format=files repo' 'references.format' 'files'
70+
71+
test_repo_info 'ref format reftable is retrieved correctly' '
72+
git init --ref-format=reftable repo' 'references.format' 'reftable'
73+
74+
test_expect_success 'plaintext: output all default fields' "
75+
git repo-info --format=plaintext >actual &&
76+
test_line_count = $DEFAULT_NUMBER_OF_FIELDS actual
77+
"
78+
79+
test_expect_success PERLJSON 'json: output all default fields' "
80+
git repo-info --format=json > output &&
81+
cat output | parse_json | grep '.*\..*\..*' >actual &&
82+
test_line_count = $DEFAULT_NUMBER_OF_FIELDS actual
83+
"
84+
2785
test_done

0 commit comments

Comments
 (0)