65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
/**
|
|
* Provider factory — creates the appropriate IssueProvider for a repository.
|
|
*
|
|
* Auto-detects provider from git remote URL:
|
|
* - github.com → GitHubProvider (gh CLI)
|
|
* - Everything else → GitLabProvider (glab CLI)
|
|
*
|
|
* Can be overridden with explicit `provider` option.
|
|
*/
|
|
import { execFileSync } from "node:child_process";
|
|
import type { TaskManager } from "./task-manager.js";
|
|
import { GitLabProvider } from "./gitlab.js";
|
|
import { GitHubProvider } from "./github.js";
|
|
import { resolveRepoPath } from "../projects.js";
|
|
|
|
export type ProviderOptions = {
|
|
provider?: "gitlab" | "github";
|
|
repo?: string;
|
|
repoPath?: string;
|
|
};
|
|
|
|
function detectProvider(repoPath: string): "gitlab" | "github" {
|
|
try {
|
|
const url = execFileSync("git", ["remote", "get-url", "origin"], {
|
|
cwd: repoPath,
|
|
timeout: 5_000,
|
|
})
|
|
.toString()
|
|
.trim();
|
|
|
|
if (url.includes("github.com")) return "github";
|
|
return "gitlab";
|
|
} catch {
|
|
return "gitlab";
|
|
}
|
|
}
|
|
|
|
export type ProviderWithType = {
|
|
provider: TaskManager;
|
|
type: "github" | "gitlab";
|
|
};
|
|
|
|
export function createProvider(opts: ProviderOptions): ProviderWithType {
|
|
const repoPath =
|
|
opts.repoPath ?? (opts.repo ? resolveRepoPath(opts.repo) : null);
|
|
if (!repoPath) {
|
|
throw new Error(
|
|
"Either repoPath or repo must be provided to createProvider",
|
|
);
|
|
}
|
|
|
|
const type = opts.provider ?? detectProvider(repoPath);
|
|
|
|
if (type === "github") {
|
|
return {
|
|
provider: new GitHubProvider({ repoPath }),
|
|
type: "github",
|
|
};
|
|
}
|
|
return {
|
|
provider: new GitLabProvider({ repoPath }),
|
|
type: "gitlab",
|
|
};
|
|
}
|