From 63c88de1d3762fe50efbefea9752e4bd2d2faa34 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 4 Oct 2022 08:01:17 -0400 Subject: [PATCH 1/3] abspath: make strip_last_path_component() global The strip_last_component() method is helpful for finding the parent directory of a path stored in a strbuf. Extract it to a global method advertised in abspath.h. With that additional visibility, it is helpful to rename it to be more specific to paths. Signed-off-by: Derrick Stolee --- abspath.c | 6 +++--- abspath.h | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/abspath.c b/abspath.c index 0c17e98654e4b0..e899f46d02097a 100644 --- a/abspath.c +++ b/abspath.c @@ -14,7 +14,7 @@ int is_directory(const char *path) } /* removes the last path component from 'path' except if 'path' is root */ -static void strip_last_component(struct strbuf *path) +void strip_last_path_component(struct strbuf *path) { size_t offset = offset_1st_component(path->buf); size_t len = path->len; @@ -119,7 +119,7 @@ static char *strbuf_realpath_1(struct strbuf *resolved, const char *path, continue; /* '.' component */ } else if (next.len == 2 && !strcmp(next.buf, "..")) { /* '..' component; strip the last path component */ - strip_last_component(resolved); + strip_last_path_component(resolved); continue; } @@ -171,7 +171,7 @@ static char *strbuf_realpath_1(struct strbuf *resolved, const char *path, * strip off the last component since it will * be replaced with the contents of the symlink */ - strip_last_component(resolved); + strip_last_path_component(resolved); } /* diff --git a/abspath.h b/abspath.h index 4653080d5e4b7a..06241ba13cf646 100644 --- a/abspath.h +++ b/abspath.h @@ -10,6 +10,11 @@ char *real_pathdup(const char *path, int die_on_error); const char *absolute_path(const char *path); char *absolute_pathdup(const char *path); +/** + * Remove the last path component from 'path' except if 'path' is root. + */ +void strip_last_path_component(struct strbuf *path); + /* * Concatenate "prefix" (if len is non-zero) and "path", with no * connecting characters (so "prefix" should end with a "/"). From 5e7f804d5e06203f86e0d7aafee8b259889e4ff7 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 30 Sep 2022 12:41:27 -0400 Subject: [PATCH 2/3] scalar: .scalarCache should live above enlistment We should not be putting the .scalarCache inside the enlistment as a sibling to the 'src' directory. This only happens in "unattended" mode, but it also negates any benefit of a shared object cache because each enlistment absolutely does not share any objects with others. Move the shared object cache in this case to a level above the enlistment, so at least there is some hope that it can be reused. This is also critical to the upcoming --no-src option, since the shared object cache cannot be located within the Git repository. Signed-off-by: Derrick Stolee --- scalar.c | 9 +++++++-- t/t9210-scalar.sh | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scalar.c b/scalar.c index 70ea95580864e2..4cbd867e8bd748 100644 --- a/scalar.c +++ b/scalar.c @@ -477,8 +477,13 @@ static char *default_cache_root(const char *root) { const char *env; - if (is_unattended()) - return xstrfmt("%s/.scalarCache", root); + if (is_unattended()) { + struct strbuf path = STRBUF_INIT; + strbuf_addstr(&path, root); + strip_last_path_component(&path); + strbuf_addstr(&path, "/.scalarCache"); + return strbuf_detach(&path, NULL); + } #ifdef WIN32 (void)env; diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 2fd85cb47f3575..bff32aed8a2950 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -310,7 +310,7 @@ test_expect_success '`scalar clone` with GVFS-enabled server' ' cache_key="url_$(printf "%s" http://$HOST_PORT/ | tr A-Z a-z | test-tool sha1)" && - echo "$(pwd)/using-gvfs/.scalarCache/$cache_key" >expect && + echo "$(pwd)/.scalarCache/$cache_key" >expect && git -C using-gvfs/src config gvfs.sharedCache >actual && test_cmp expect actual && From 6da3cd632abe19cdb5833f87999da925d933b9ec Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Fri, 30 Sep 2022 12:44:27 -0400 Subject: [PATCH 3/3] scalar: add --no-src option Some users have strong aversions to Scalar's opinion that the repository should be in a 'src' directory, even though it creates a clean slate for placing build outputs in adjacent directories. The --no-src option allows users to opt-out of the default behavior. The parse-opt logic automatically figures out that '--src' is a possible flag that negates '--no-src'. Signed-off-by: Derrick Stolee --- Documentation/scalar.txt | 5 ++++- scalar.c | 14 ++++++++++++-- t/t9210-scalar.sh | 8 ++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Documentation/scalar.txt b/Documentation/scalar.txt index 0424d020d9b9f4..35f67801e92a98 100644 --- a/Documentation/scalar.txt +++ b/Documentation/scalar.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] scalar clone [--single-branch] [--branch ] [--full-clone] - [--local-cache-path ] [--cache-server-url ] + [--local-cache-path ] [--cache-server-url ] [--[no-]src] [] scalar list scalar register [] @@ -83,6 +83,9 @@ remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when `--single-branch` clone was made, no remote-tracking branch is created. +--no-src:: + Skip adding a `src` directory within the target enlistment. + --[no-]full-clone:: A sparse-checkout is initialized by default. This behavior can be turned off via `--full-clone`. diff --git a/scalar.c b/scalar.c index 4cbd867e8bd748..2b136d25d5ef33 100644 --- a/scalar.c +++ b/scalar.c @@ -707,6 +707,8 @@ static int cmd_clone(int argc, const char **argv) int full_clone = 0, single_branch = 0, show_progress = isatty(2); const char *cache_server_url = NULL, *local_cache_root = NULL; char *default_cache_server_url = NULL, *local_cache_root_abs = NULL; + const char *enlistment_parent; + int no_src = 0; struct option clone_options[] = { OPT_STRING('b', "branch", &branch, N_(""), N_("branch to checkout after clone")), @@ -715,6 +717,8 @@ static int cmd_clone(int argc, const char **argv) OPT_BOOL(0, "single-branch", &single_branch, N_("only download metadata for the branch that will " "be checked out")), + OPT_BOOL(0, "no-src", &no_src, + N_("skip creating a 'src' directory")), OPT_STRING(0, "cache-server-url", &cache_server_url, N_(""), N_("the url or friendly name of the cache server")), @@ -765,7 +769,13 @@ static int cmd_clone(int argc, const char **argv) ensure_absolute_path(enlistment, &enlistment); - dir = xstrfmt("%s/src", enlistment); + if (!no_src) { + dir = xstrfmt("%s/src", enlistment); + enlistment_parent = "../.."; + } else { + dir = xstrdup(enlistment); + enlistment_parent = ".."; + } if (!local_cache_root) local_cache_root = local_cache_root_abs = @@ -806,7 +816,7 @@ static int cmd_clone(int argc, const char **argv) struct strbuf path = STRBUF_INIT; strbuf_addstr(&path, enlistment); - if (chdir("../..") < 0 || + if (chdir(enlistment_parent) < 0 || remove_dir_recursively(&path, 0) < 0) die(_("'--local-cache-path' cannot be inside the src " "folder;\nCould not remove '%s'"), enlistment); diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index bff32aed8a2950..b4139b33a31855 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -395,4 +395,12 @@ test_expect_success '`scalar delete` with existing repo' ' test_path_is_missing existing ' +test_expect_success '`scalar clone --no-src`' ' + scalar clone --src "file://$(pwd)" with-src && + scalar clone --no-src "file://$(pwd)" without-src && + + test_path_is_dir with-src/src && + test_path_is_missing without-src/src +' + test_done