diff --git a/packages/shared/src/cloneUrl.test.ts b/packages/shared/src/cloneUrl.test.ts index 16503923d8aa3..4794a68577599 100644 --- a/packages/shared/src/cloneUrl.test.ts +++ b/packages/shared/src/cloneUrl.test.ts @@ -3,6 +3,23 @@ import { describe, expect, it } from "vite-plus/test"; import { cloneUrlForProtocol, cloneUrlProtocol } from "./cloneUrl.ts"; describe("cloneUrlForProtocol", () => { + it.each(["C:\\repos\\project.git", "c:\\repos\\project.git", "C:/repos/project.git"])( + "does not offer network protocols for a Windows local path: %s", + (path) => { + expect(cloneUrlProtocol(path)).toBeNull(); + expect(cloneUrlForProtocol(path, "ssh")).toBeNull(); + expect(cloneUrlForProtocol(path, "https")).toBeNull(); + }, + ); + + it.each(["c:repo.git", "git@c:repo.git", "ssh://git@c/repo.git"])( + "keeps SSH URLs with a single-letter host: %s", + (url) => { + expect(cloneUrlProtocol(url)).toBe("ssh"); + expect(cloneUrlForProtocol(url, "https")).toBe("https://c/repo.git"); + }, + ); + it.each([ ["ordinary", "user:password"], ["an embedded at sign", "user:pa@rt"], diff --git a/packages/shared/src/cloneUrl.ts b/packages/shared/src/cloneUrl.ts index cface92a89a3c..6c214d32e8c7a 100644 --- a/packages/shared/src/cloneUrl.ts +++ b/packages/shared/src/cloneUrl.ts @@ -1,3 +1,5 @@ +import { isWindowsDrivePath } from "./path.ts"; + export type CloneProtocol = "ssh" | "https"; const SCP_LIKE_URL = /^(?:[^@/\s]+@)?([^:/\s]+):(?!\/)(.+)$/; @@ -9,6 +11,7 @@ function parseCloneUrl( url: string, ): { protocol: CloneProtocol; host: string; path: string; customPort: boolean } | null { const trimmed = url.trim(); + if (isWindowsDrivePath(trimmed)) return null; const ssh = SSH_URL.exec(trimmed); if (ssh) return { protocol: "ssh", host: ssh[1]!, path: ssh[3]!, customPort: !!ssh[2] }; const https = HTTPS_URL.exec(trimmed);