Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
Blame · Line-by-line history

repo.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

repo.tsBlame90 lines · 1 contributor
63fe719Claude1/**
2 * Workspace-aware helpers that combine VS Code APIs with the pure parser
3 * in `git.ts`. Returns `null` whenever the active workspace can't be
4 * resolved to a Gluecron-hosted repo.
5 */
6
7import * as vscode from "vscode";
8import { execFile } from "node:child_process";
9import { promisify } from "node:util";
10import { parseGitRemote, isGluecronRemote, type RepoInfo } from "./git";
11
12const execFileP = promisify(execFile);
13
14export function getHost(): string {
15 const v = vscode.workspace
16 .getConfiguration("gluecron")
17 .get<string>("host");
18 return (v && v.trim()) || "https://gluecron.com";
19}
20
21export function getDefaultBranch(): string {
22 const v = vscode.workspace
23 .getConfiguration("gluecron")
24 .get<string>("defaultBranch");
25 return (v && v.trim()) || "main";
26}
27
28/**
29 * Pick a workspace folder — prefers the active editor's folder, falls back
30 * to the first workspace folder. Returns `null` if there is no workspace.
31 */
32export function pickWorkspaceFolder(): vscode.WorkspaceFolder | null {
33 const editor = vscode.window.activeTextEditor;
34 if (editor) {
35 const folder = vscode.workspace.getWorkspaceFolder(editor.document.uri);
36 if (folder) return folder;
37 }
38 const folders = vscode.workspace.workspaceFolders;
39 if (folders && folders.length > 0) return folders[0];
40 return null;
41}
42
43/**
44 * Resolve the current workspace's Gluecron repo. Returns `null` if there
45 * is no workspace, no git remote, or the remote isn't hosted on the
46 * configured Gluecron instance.
47 */
48export async function getRepoInfo(): Promise<RepoInfo | null> {
49 const folder = pickWorkspaceFolder();
50 if (!folder) return null;
51 let url: string;
52 try {
53 const { stdout } = await execFileP(
54 "git",
55 ["remote", "get-url", "origin"],
56 { cwd: folder.uri.fsPath }
57 );
58 url = stdout.trim();
59 } catch {
60 return null;
61 }
62 const info = parseGitRemote(url);
63 if (!info) return null;
64 if (!isGluecronRemote(info.host, getHost())) {
65 // We still return the parse — callers may want the bare info for
66 // building cross-host URLs — but most callers should use
67 // `getGluecronRepoInfo` which filters this out.
68 return info;
69 }
70 return info;
71}
72
73/**
74 * Like `getRepoInfo` but returns `null` for non-Gluecron remotes.
75 */
76export async function getGluecronRepoInfo(): Promise<RepoInfo | null> {
77 const info = await getRepoInfo();
78 if (!info) return null;
79 if (!isGluecronRemote(info.host, getHost())) return null;
80 return info;
81}
82
83/**
84 * Build a URL inside the configured Gluecron host.
85 */
86export function hostUrl(path: string): string {
87 const host = getHost().replace(/\/+$/, "");
88 const p = path.startsWith("/") ? path : `/${path}`;
89 return host + p;
90}