UNPKG

@capawesome/cli

Version:

The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.

93 lines (92 loc) 3.79 kB
import { execSync } from 'child_process'; import { UserError } from '../utils/error.js'; const HOSTNAME_TO_PROVIDER = { 'github.com': 'github', 'gitlab.com': 'gitlab', 'bitbucket.org': 'bitbucket', 'dev.azure.com': 'azure', 'ssh.dev.azure.com': 'azure', }; export const getGitRemoteInfo = () => { const remoteUrl = getGitRemoteUrl(); return parseGitRemoteUrl(remoteUrl); }; const getGitRemoteUrl = () => { try { return execSync('git remote get-url origin', { encoding: 'utf-8' }).trim(); } catch { throw new UserError('Could not read the git remote URL. Make sure you are inside a git repository with an origin remote.'); } }; export const parseGitRemoteUrl = (remoteUrl) => { // Azure DevOps HTTPS: https://dev.azure.com/{org}/{project}/_git/{repo} const azureHttpsMatch = remoteUrl.match(/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/]+?)(?:\.git)?$/); if (azureHttpsMatch && azureHttpsMatch[1] && azureHttpsMatch[2] && azureHttpsMatch[3]) { return { ownerSlug: azureHttpsMatch[1], provider: 'azure', repositorySlug: azureHttpsMatch[3], projectSlug: azureHttpsMatch[2], }; } // Azure DevOps SSH: git@ssh.dev.azure.com:v3/{org}/{project}/{repo} const azureSshMatch = remoteUrl.match(/ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\/([^/]+?)(?:\.git)?$/); if (azureSshMatch && azureSshMatch[1] && azureSshMatch[2] && azureSshMatch[3]) { return { ownerSlug: azureSshMatch[1], provider: 'azure', repositorySlug: azureSshMatch[3], projectSlug: azureSshMatch[2], }; } // Visual Studio HTTPS: https://{org}.visualstudio.com/{project}/_git/{repo} const vsHttpsMatch = remoteUrl.match(/([^/]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/]+?)(?:\.git)?$/); if (vsHttpsMatch && vsHttpsMatch[1] && vsHttpsMatch[2] && vsHttpsMatch[3]) { return { ownerSlug: vsHttpsMatch[1], provider: 'azure', repositorySlug: vsHttpsMatch[3], projectSlug: vsHttpsMatch[2], }; } // SSH: git@{host}:{owner}[/{subgroup}]/{repo}.git const sshMatch = remoteUrl.match(/git@([^:]+):([^/]+)(?:\/([^/]+))?\/([^/]+?)(?:\.git)?$/); if (sshMatch && sshMatch[1] && sshMatch[2] && sshMatch[4]) { const hostname = sshMatch[1]; const provider = HOSTNAME_TO_PROVIDER[hostname]; if (!provider) { throw new UserError(`Unsupported git provider for hostname "${hostname}".`); } return { ownerSlug: sshMatch[2], provider, repositorySlug: sshMatch[4], projectSlug: sshMatch[3], }; } // HTTPS: https://[user@]{host}/{owner}[/{subgroup}]/{repo}.git try { const url = new URL(remoteUrl); if (url.protocol === 'http:' || url.protocol === 'https:') { const hostname = url.hostname; const provider = HOSTNAME_TO_PROVIDER[hostname]; if (!provider) { throw new UserError(`Unsupported git provider for hostname "${hostname}".`); } const pathSegments = url.pathname.split('/').filter(Boolean); const repositorySlug = pathSegments.pop()?.replace(/\.git$/, ''); const ownerSlug = pathSegments.shift(); const projectSlug = pathSegments.length > 0 ? pathSegments.join('/') : undefined; if (ownerSlug && repositorySlug) { return { ownerSlug, provider, repositorySlug, projectSlug }; } } } catch (error) { if (error instanceof UserError) { throw error; } } throw new UserError('Could not parse git remote URL.'); };