feat: implement runCommand wrapper and refactor command executions across modules

This commit is contained in:
Lauren ten Hoor
2026-02-13 10:50:35 +08:00
parent e55b7fa555
commit 83f1f1adf0
24 changed files with 209 additions and 178 deletions

View File

@@ -1,11 +1,11 @@
/**
* Provider factory — auto-detects GitHub vs GitLab from git remote.
*/
import { execFileSync } from "node:child_process";
import type { IssueProvider } from "./provider.js";
import { GitLabProvider } from "./gitlab.js";
import { GitHubProvider } from "./github.js";
import { resolveRepoPath } from "../projects.js";
import { runCommand } from "../run-command.js";
export type ProviderOptions = {
provider?: "gitlab" | "github";
@@ -18,19 +18,19 @@ export type ProviderWithType = {
type: "github" | "gitlab";
};
function detectProvider(repoPath: string): "gitlab" | "github" {
async function detectProvider(repoPath: string): Promise<"gitlab" | "github"> {
try {
const url = execFileSync("git", ["remote", "get-url", "origin"], { cwd: repoPath, timeout: 5_000 }).toString().trim();
return url.includes("github.com") ? "github" : "gitlab";
const result = await runCommand(["git", "remote", "get-url", "origin"], { timeoutMs: 5_000, cwd: repoPath });
return result.stdout.trim().includes("github.com") ? "github" : "gitlab";
} catch {
return "gitlab";
}
}
export function createProvider(opts: ProviderOptions): ProviderWithType {
export async function createProvider(opts: ProviderOptions): Promise<ProviderWithType> {
const repoPath = opts.repoPath ?? (opts.repo ? resolveRepoPath(opts.repo) : null);
if (!repoPath) throw new Error("Either repoPath or repo must be provided");
const type = opts.provider ?? detectProvider(repoPath);
const type = opts.provider ?? await detectProvider(repoPath);
const provider = type === "github" ? new GitHubProvider({ repoPath }) : new GitLabProvider({ repoPath });
return { provider, type };
}