UNPKG

doctordoc

Version:
70 lines (59 loc) 2.01 kB
import { execSync } from 'child_process'; import path from 'path'; import fs from 'fs'; import { printErrorMessage } from '../util/printUtil.js'; export function getGitRepositoryUrl(targetPath) { try { const exec = (cmd) => execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim(); // Ensure inside a Git repo let repoRoot; try { repoRoot = exec('git rev-parse --show-toplevel'); } catch { printErrorMessage('Error: Must be inside a Git repository to open the link in the browser.'); process.exit(0); } const remoteUrl = exec('git config --get remote.origin.url'); const branch = exec('git rev-parse --abbrev-ref HEAD') === 'HEAD' ? exec('git rev-parse HEAD') : exec('git rev-parse --abbrev-ref HEAD'); // Normalize remote let baseUrl = remoteUrl .replace(/^git@([^:]+):/, 'https://$1/') .replace(/^https?:\/\/([^@]+@)?/, 'https://') .replace(/\.git$/, ''); // Resolve path const fullPath = path.resolve(targetPath); if (!fullPath.startsWith(repoRoot)) { printErrorMessage('Error: Target path is outside the Git repository.'); process.exit(0); } const relativePath = path.relative(repoRoot, fullPath).replace(/\\/g, '/'); // Determine file or folder let isDir; try { isDir = fs.statSync(fullPath).isDirectory(); } catch { console.error('Error: Path does not exist:', relativePath); return null; } const type = isDir ? 'tree' : 'blob'; // Generate URL based on host if (baseUrl.includes('github.com')) { return `${baseUrl}/${type}/${branch}/${relativePath}`; } if (baseUrl.includes('gitlab.com')) { return `${baseUrl}/-/${type}/${branch}/${relativePath}`; } if (baseUrl.includes('bitbucket.org')) { return `${baseUrl}/src/${branch}/${relativePath}`; } printErrorMessage('Error: Unsupported remote platform: ' + baseUrl); process.exit(0); } catch (error) { console.error('Unexpected error:', error.message); process.exit(1); } }