MCPcopy Index your code
hub / github.com/coder/mux / deriveRepoFolderName

Function deriveRepoFolderName

src/node/services/projectService.ts:157–193  ·  view source on GitHub ↗
(repoUrl: string)

Source from the content-addressed store, hash-verified

155}
156
157function deriveRepoFolderName(repoUrl: string): string {
158 const trimmedRepoUrl = repoUrl.trim();
159 if (!trimmedRepoUrl) {
160 throw new Error("Repository URL cannot be empty");
161 }
162
163 let candidatePath = trimmedRepoUrl;
164
165 // SSH-style shorthand: git@github.com:owner/repo.git
166 const scpLikeMatch = /^[^@\s]+@[^:\s]+:(.+)$/.exec(trimmedRepoUrl);
167 if (scpLikeMatch) {
168 candidatePath = scpLikeMatch[1];
169 } else if (/^[^/\\\s]+\/[^/\\\s]+$/.test(trimmedRepoUrl)) {
170 // Owner/repo shorthand
171 candidatePath = trimmedRepoUrl;
172 } else {
173 try {
174 // https://..., ssh://..., file://...
175 const parsed = new URL(trimmedRepoUrl);
176 candidatePath = decodeURIComponent(parsed.pathname);
177 } catch {
178 // Not a URL with protocol. Treat as local path-like input.
179 }
180 }
181
182 const normalizedCandidatePath = candidatePath.replace(/\\/g, "/").replace(/\/+$/, "");
183 const repoName = path.posix.basename(normalizedCandidatePath).replace(/\.git$/i, "");
184 const safeFolderName = sanitizeRepoFolderName(repoName);
185
186 // Keep clone flow resilient even when the repo basename contains only symbols/emojis.
187 // A deterministic fallback avoids user-visible hard failures while staying shell-safe.
188 if (!safeFolderName) {
189 return deriveFallbackRepoFolderName(trimmedRepoUrl);
190 }
191
192 return safeFolderName;
193}
194
195const GITHUB_SHORTHAND_PATTERN = /^[a-zA-Z0-9][\w-]*\/[a-zA-Z0-9][\w.-]*$/;
196

Callers 1

Calls 5

sanitizeRepoFolderNameFunction · 0.85
testMethod · 0.80
execMethod · 0.65
basenameMethod · 0.45

Tested by

no test coverage detected