























@@ -18,43 +18,47 @@ export type GitSource = {
1818pinned: boolean;
1919};
202021+function splitPathRef(params: {
22+originalRepo: string;
23+pathWithMaybeRef: string;
24+buildRepo: (repoPath: string) => string;
25+}): { repo: string; ref?: string } {
26+const refSeparator = params.pathWithMaybeRef.indexOf("@");
27+if (refSeparator < 0) {
28+return { repo: params.originalRepo };
29+}
30+const repoPath = params.pathWithMaybeRef.slice(0, refSeparator);
31+const ref = params.pathWithMaybeRef.slice(refSeparator + 1);
32+if (!repoPath || !ref) {
33+return { repo: params.originalRepo };
34+}
35+return {
36+repo: params.buildRepo(repoPath),
37+ ref,
38+};
39+}
40+2141function splitRef(url: string): { repo: string; ref?: string } {
2242const scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);
2343if (scpLikeMatch) {
24-const pathWithMaybeRef = scpLikeMatch[2] ?? "";
25-const refSeparator = pathWithMaybeRef.indexOf("@");
26-if (refSeparator < 0) {
27-return { repo: url };
28-}
29-const repoPath = pathWithMaybeRef.slice(0, refSeparator);
30-const ref = pathWithMaybeRef.slice(refSeparator + 1);
31-if (!repoPath || !ref) {
32-return { repo: url };
33-}
34-return {
35-repo: `git@${scpLikeMatch[1] ?? ""}:${repoPath}`,
36- ref,
37-};
44+return splitPathRef({
45+originalRepo: url,
46+pathWithMaybeRef: scpLikeMatch[2] ?? "",
47+buildRepo: (repoPath) => `git@${scpLikeMatch[1] ?? ""}:${repoPath}`,
48+});
3849}
39504051if (url.includes("://")) {
4152try {
4253const parsed = new URL(url);
43-const pathWithMaybeRef = parsed.pathname.replace(/^\/+/, "");
44-const refSeparator = pathWithMaybeRef.indexOf("@");
45-if (refSeparator < 0) {
46-return { repo: url };
47-}
48-const repoPath = pathWithMaybeRef.slice(0, refSeparator);
49-const ref = pathWithMaybeRef.slice(refSeparator + 1);
50-if (!repoPath || !ref) {
51-return { repo: url };
52-}
53-parsed.pathname = `/${repoPath}`;
54-return {
55-repo: parsed.toString().replace(/\/$/, ""),
56- ref,
57-};
54+return splitPathRef({
55+originalRepo: url,
56+pathWithMaybeRef: parsed.pathname.replace(/^\/+/, ""),
57+buildRepo: (repoPath) => {
58+parsed.pathname = `/${repoPath}`;
59+return parsed.toString().replace(/\/$/, "");
60+},
61+});
5862} catch {
5963return { repo: url };
6064}
@@ -65,20 +69,11 @@ function splitRef(url: string): { repo: string; ref?: string } {
6569return { repo: url };
6670}
6771const host = url.slice(0, slashIndex);
68-const pathWithMaybeRef = url.slice(slashIndex + 1);
69-const refSeparator = pathWithMaybeRef.indexOf("@");
70-if (refSeparator < 0) {
71-return { repo: url };
72-}
73-const repoPath = pathWithMaybeRef.slice(0, refSeparator);
74-const ref = pathWithMaybeRef.slice(refSeparator + 1);
75-if (!repoPath || !ref) {
76-return { repo: url };
77-}
78-return {
79-repo: `${host}/${repoPath}`,
80- ref,
81-};
72+return splitPathRef({
73+originalRepo: url,
74+pathWithMaybeRef: url.slice(slashIndex + 1),
75+buildRepo: (repoPath) => `${host}/${repoPath}`,
76+});
8277}
83788479function parseGenericGitUrl(url: string): GitSource | null {
@@ -154,6 +149,33 @@ function normalizeGitPath(path: string): string | null {
154149return segments.join("/");
155150}
156151152+function resolveHostedGitSource(params: {
153+candidate: string;
154+split: { repo: string; ref?: string };
155+repo: string;
156+}): GitSource | null {
157+const info = hostedGitInfo.fromUrl(params.candidate);
158+if (!info) {
159+return null;
160+}
161+if (params.split.ref && info.project?.includes("@")) {
162+return null;
163+}
164+const host = info.domain || "";
165+const path = normalizeGitPath(`${info.user}/${info.project}`);
166+if (!isSafeGitHost(host) || !path) {
167+return null;
168+}
169+return {
170+type: "git",
171+repo: params.repo,
172+ host,
173+ path,
174+ref: info.committish || params.split.ref || undefined,
175+pinned: Boolean(info.committish || params.split.ref),
176+};
177+}
178+157179/**
158180 * Parse git source into a GitSource.
159181 *
@@ -176,30 +198,19 @@ export function parseGitUrl(source: string): GitSource | null {
176198(value): value is string => Boolean(value),
177199);
178200for (const candidate of hostedCandidates) {
179-const info = hostedGitInfo.fromUrl(candidate);
180-if (info) {
181-if (split.ref && info.project?.includes("@")) {
182-continue;
183-}
184-const host = info.domain || "";
185-const path = normalizeGitPath(`${info.user}/${info.project}`);
186-if (!isSafeGitHost(host) || !path) {
187-continue;
188-}
189-const useHttpsPrefix =
190-!split.repo.startsWith("http://") &&
191-!split.repo.startsWith("https://") &&
192-!split.repo.startsWith("ssh://") &&
193-!split.repo.startsWith("git://") &&
194-!split.repo.startsWith("git@");
195-return {
196-type: "git",
197-repo: useHttpsPrefix ? `https://${split.repo}` : split.repo,
198- host,
199- path,
200-ref: info.committish || split.ref || undefined,
201-pinned: Boolean(info.committish || split.ref),
202-};
201+const useHttpsPrefix =
202+!split.repo.startsWith("http://") &&
203+!split.repo.startsWith("https://") &&
204+!split.repo.startsWith("ssh://") &&
205+!split.repo.startsWith("git://") &&
206+!split.repo.startsWith("git@");
207+const parsed = resolveHostedGitSource({
208+ candidate,
209+ split,
210+repo: useHttpsPrefix ? `https://${split.repo}` : split.repo,
211+});
212+if (parsed) {
213+return parsed;
203214}
204215}
205216@@ -208,24 +219,13 @@ export function parseGitUrl(source: string): GitSource | null {
208219`https://${url}`,
209220].filter((value): value is string => Boolean(value));
210221for (const candidate of httpsCandidates) {
211-const info = hostedGitInfo.fromUrl(candidate);
212-if (info) {
213-if (split.ref && info.project?.includes("@")) {
214-continue;
215-}
216-const host = info.domain || "";
217-const path = normalizeGitPath(`${info.user}/${info.project}`);
218-if (!isSafeGitHost(host) || !path) {
219-continue;
220-}
221-return {
222-type: "git",
223-repo: `https://${split.repo}`,
224- host,
225- path,
226-ref: info.committish || split.ref || undefined,
227-pinned: Boolean(info.committish || split.ref),
228-};
222+const parsed = resolveHostedGitSource({
223+ candidate,
224+ split,
225+repo: `https://${split.repo}`,
226+});
227+if (parsed) {
228+return parsed;
229229}
230230}
231231此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。