Repository navigation
Add --project-naming-mode=sparse-postfixed to name a project per sparse checkout - #188
Ibrahimrahhal wants to merge 1 commit into
Conversation
…se checkout Co-authored-by: ibrahim <ibrahim@corgea.com>
| return None; | ||
| } | ||
| let path = line.strip_prefix('/').unwrap_or(line); | ||
| let folder = path.split('/').next().unwrap_or_default(); |
There was a problem hiding this comment.
high: Root files are incorrectly treated as top-level folders
top_level_folders assumes every literal first path segment is a directory. In non-cone mode, git sparse-checkout list can return exact root files such as package.json alongside service paths. This produces monorepo-package.json.services instead of monorepo-services, causing scan, upload, list, and wait to target a different project. Determine whether literal entries are directories from the repository tree, or explicitly reject/ignore file entries.
Proof or reproduction:
#[test]
fn root_files_do_not_become_project_suffixes() {
assert_eq!(
top_level_folders("package.json\n/services/**\n"),
vec!["services"]
);
}
// Current result: ["package.json", "services"]
// Current derived name: monorepo-package.json.services
There was a problem hiding this comment.
Automated review risk: 3/5.
The naming mode can route scans and queries to the wrong project for valid non-cone sparse checkouts containing explicit root files.
Critical or high-priority changes must be addressed.
Automatic approval was not submitted: automated review found critical or high-priority findings.
| let path = line.strip_prefix('/').unwrap_or(line); | ||
| let folder = path.split('/').next().unwrap_or_default(); | ||
| (!folder.is_empty() && !folder.starts_with('*')).then(|| folder.to_string()) |
There was a problem hiding this comment.
path.split('/') runs on the raw git sparse-checkout list line. On git 2.43 with the default core.quotePath=true, a cone checkout is printed as one C-quoted string, and the slash sits inside the quotes:
services/cafélists as"services/caf\303\251". The first segment is"services, so the suffix is_servicesrather thanservices.café/childlists as"caf\303\251/child". The first segment drops the closing quote and becomes_caf_303_251.caféitself stays"caf\303\251"→_caf_303_251_.
Those are three project names for one top-level folder. list and wait query that string directly, and scan uploads to it, with no warning. postfixed_name_applies_the_template_character_rule_to_folders only passes an already-extracted quoted token, so it never sees a slash inside the quotes.
core.quotePath=false (often set in ~/.gitconfig) makes list print raw UTF-8, so the same café checkout becomes caf__. This process does not pass -c core.quotePath=..., and the info/sparse-checkout fallback is raw UTF-8 too (/café/). The name then depends on git config and on which read path succeeds.
suggestion: list with git -c core.quotePath=false sparse-checkout list, take the first / segment of that raw path (and of the file fallback), then C-quote only that segment the way quotePath=true does (café → "caf\303\251", tab → \t, \\ and \" escaped, other bytes ≥ 0x80 or < 0x20 as \ooo) and run postfixed_name on that. Cover services/café and café/child with a real sparse checkout that expects services and "caf\303\251".


What
Adds
--project-naming-mode <MODE>toscan,upload,listandwait. The only value issparse-postfixed. It gives a monorepo service cloned with a sparse checkout its own Corgea project, without the pipeline having to compute a project name itself.Behaviour
<default project name>-<folders joined with '.'>. The default name is the usual one: the repo name fromorigin, else the current folder name.\nis stripped. Characters outsideA-Za-z0-9._-become_, byte by byte, and the name is cut at 100 characters. This matches the naming CI pipelines already use for sparse checkouts, so their existing projects are kept.gitbinary (git config --bool --default false core.sparseCheckout, thengit sparse-checkout list, falling back to theinfo/sparse-checkoutfile).git sparse-checkoutstores the setting inconfig.worktree, which is why git is asked rather than.git/configbeing read.main.rsand passed down exactly like--project-name.list/waittherefore query that project directly instead of resolving by repo URL. That resolution would fail once several projects share a repo.--project-name(or with--repoonlist/wait).Behaviour without the flag is unchanged.
Known limitations (kept to match existing project names)
services/aandservices/bboth give<repo>-services.aandbgives the same name as a folder calleda.b.cafégives_caf_303_251_).Tests
src/project_naming.rscover pattern reduction, the character rule and length cap, and real sparse, full, root-only and subdirectory checkouts.tests/project_naming_mode.rscovers, end to end:listquerying the derived name in a sparse clone, falling back with a warning in a full clone, the conflict with--project-nameon all four commands, and the unknown-value error../harness checkpasses: strict clippy, formatting, 968 tests.