Skip to content

Commit

Permalink
scalar: add the cache-server command
Browse files Browse the repository at this point in the history
This allows setting the GVFS-enabled cache server, or listing the one(s)
associated with the remote repository.

Signed-off-by: Johannes Schindelin <[email protected]>
  • Loading branch information
dscho committed Jan 1, 2025
1 parent a3d1380 commit 5ab2cbf
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
22 changes: 22 additions & 0 deletions Documentation/scalar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ scalar run ( all | config | commit-graph | fetch | loose-objects | pack-files )
scalar reconfigure [ --all | <enlistment> ]
scalar diagnose [<enlistment>]
scalar delete <enlistment>
scalar cache-server ( --get | --set <url> | --list [<remote>] ) [<enlistment>]

DESCRIPTION
-----------
Expand Down Expand Up @@ -182,6 +183,27 @@ delete <enlistment>::
This subcommand lets you delete an existing Scalar enlistment from your
local file system, unregistering the repository.

Cache-server
~~~~~~~~~~~~

cache-server ( --get | --set <url> | --list [<remote>] ) [<enlistment>]::
This command lets you query or set the GVFS-enabled cache server used
to fetch missing objects.

--get::
This is the default command mode: query the currently-configured cache
server URL, if any.

--list::
Access the `gvfs/info` endpoint of the specified remote (default:
`origin`) to figure out which cache servers are available, if any.
+
In contrast to the `--get` command mode (which only accesses the local
repository), this command mode triggers a request via the network that
potentially requires authentication. If authentication is required, the
configured credential helper is employed (see linkgit:git-credential[1]
for details).

SEE ALSO
--------
linkgit:git-clone[1], linkgit:git-maintenance[1].
Expand Down
95 changes: 94 additions & 1 deletion scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "wrapper.h"
#include "trace2.h"
#include "json-parser.h"
#include "remote.h"
#include "path.h"

static int is_unattended(void) {
Expand Down Expand Up @@ -361,6 +362,21 @@ static int set_config(const char *fmt, ...)
return res;
}

static int list_cache_server_urls(struct json_iterator *it)
{
const char *p;
char *q;
long l;

if (it->type == JSON_STRING &&
skip_iprefix(it->key.buf, ".CacheServers[", &p) &&
(l = strtol(p, &q, 10)) >= 0 && p != q &&
!strcasecmp(q, "].Url"))
printf("#%ld: %s\n", l, it->string_value.buf);

return 0;
}

/* Find N for which .CacheServers[N].GlobalDefault == true */
static int get_cache_server_index(struct json_iterator *it)
{
Expand Down Expand Up @@ -430,6 +446,18 @@ static int supports_gvfs_protocol(const char *url, char **cache_server_url)
JSON_ITERATOR_INIT(out.buf, get_cache_server_index, &l);
struct cache_server_url_data data = { .url = NULL };

if (!cache_server_url) {
it.fn = list_cache_server_urls;
if (iterate_json(&it) < 0) {
reset_iterator(&it);
strbuf_release(&out);
return error("JSON parse error");
}
reset_iterator(&it);
strbuf_release(&out);
return 0;
}

if (iterate_json(&it) < 0) {
reset_iterator(&it);
strbuf_release(&out);
Expand All @@ -450,7 +478,9 @@ static int supports_gvfs_protocol(const char *url, char **cache_server_url)
return 1;
}
strbuf_release(&out);
return 0; /* error out quietly */
/* error out quietly, unless we wanted to list URLs */
return cache_server_url ?
0 : error(_("Could not access gvfs/config endpoint"));
}

static char *default_cache_root(const char *root)
Expand Down Expand Up @@ -1292,6 +1322,68 @@ static int cmd_version(int argc, const char **argv)
return 0;
}

static int cmd_cache_server(int argc, const char **argv)
{
int get = 0;
const char *set = NULL, *list = NULL;
struct option options[] = {
OPT_CMDMODE(0, "get", &get,
N_("get the configured cache-server URL"), 1),
OPT_STRING(0, "set", &set, N_("URL"),
N_("configure the cache-server to use")),
OPT_STRING(0, "list", &list, N_("remote"),
N_("list the possible cache-server URLs")),
OPT_END(),
};
const char * const usage[] = {
N_("scalar cache-server "
"[--get | --set <url> | --list <remote>] [<enlistment>]"),
NULL
};
int res = 0;

argc = parse_options(argc, argv, NULL, options,
usage, 0);

if (get + !!set + !!list > 1)
usage_msg_opt(_("--get/--set/--list are mutually exclusive"),
usage, options);

setup_enlistment_directory(argc, argv, usage, options, NULL);

if (list) {
const char *name = list, *url = list;

if (!strchr(list, '/')) {
struct remote *remote;

/* Look up remote */
remote = remote_get(list);
if (!remote) {
error("no such remote: '%s'", name);
return 1;
}
if (!remote->url.nr) {
return error(_("remote '%s' has no URLs"),
name);
}
url = remote->url.v[0];
}
res = supports_gvfs_protocol(url, NULL);
} else if (set) {
res = set_config("gvfs.cache-server=%s", set);
} else {
char *url = NULL;

printf("Using cache server: %s\n",
git_config_get_string("gvfs.cache-server", &url) ?
"(undefined)" : url);
free(url);
}

return !!res;
}

static struct {
const char *name;
int (*fn)(int, const char **);
Expand All @@ -1306,6 +1398,7 @@ static struct {
{ "help", cmd_help },
{ "version", cmd_version },
{ "diagnose", cmd_diagnose },
{ "cache-server", cmd_cache_server },
{ NULL, NULL},
};

Expand Down
34 changes: 34 additions & 0 deletions t/t9210-scalar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -462,4 +462,38 @@ test_expect_success '`scalar delete` with existing repo' '
test_path_is_missing existing
'

test_expect_success 'scalar cache-server basics' '
repo=with-cache-server &&
git init $repo &&
scalar cache-server --get $repo >out &&
cat >expect <<-EOF &&
Using cache server: (undefined)
EOF
test_cmp expect out &&
scalar cache-server --set http://fake-server/url $repo &&
test_cmp_config -C $repo http://fake-server/url gvfs.cache-server &&
scalar delete $repo &&
test_path_is_missing $repo
'

test_expect_success 'scalar cache-server list URL' '
repo=with-real-gvfs &&
git init $repo &&
git -C $repo remote add origin http://$HOST_PORT/ &&
scalar cache-server --list origin $repo >out &&
cat >expect <<-EOF &&
#0: http://$HOST_PORT/servertype/cache
EOF
test_cmp expect out &&
test_must_fail scalar -C $repo cache-server --list 2>err &&
grep "requires a value" err &&
scalar delete $repo &&
test_path_is_missing $repo
'

test_done

0 comments on commit 5ab2cbf

Please sign in to comment.