/** * ───────────────────────────────────────────── * SPB Git — Personal Git Platform * ───────────────────────────────────────────── * Author : Simon-Pierre Boucher * Contact : contact@spboucher.ai * File : cli/commands/info.mjs * Purpose : `spbgit info ` — server-side repository details * License : MIT © Simon-Pierre Boucher * ───────────────────────────────────────────── */ import pc from 'picocolors'; import { requireCliConfig } from '../lib/config.mjs'; import { api } from '../lib/api.mjs'; import { printTable } from '../lib/ui.mjs'; import { ago } from './list.mjs'; function humanBytes(bytes) { const units = ['B', 'KB', 'MB', 'GB']; let value = Number(bytes) || 0; let i = 0; while (value >= 1024 && i < units.length - 1) { value /= 1024; i += 1; } return `${i === 0 ? value : value.toFixed(1)} ${units[i]}`; } export function registerInfo(program) { program .command('info ') .description('show server-side details of a repository') .option('--json', 'machine-readable output') .action(async (name, opts) => { const config = requireCliConfig(); const repo = await api(config, 'GET', `/api/v1/repos/${encodeURIComponent(name)}`, undefined, { auth: false }); if (opts.json) { console.log(JSON.stringify(repo, null, 2)); return; } console.log(`\n${pc.bold(repo.name)} ${repo.pinned ? pc.yellow('★') : ''}`); if (repo.description) console.log(pc.dim(repo.description)); console.log(''); printTable([ [pc.bold('URL'), repo.url], [pc.bold('Clone'), repo.cloneUrl], [pc.bold('Default branch'), repo.defaultBranch], [pc.bold('Commits'), String(repo.commitCount)], [pc.bold('Branches'), String(repo.branchCount)], [pc.bold('Tags'), String(repo.tagCount)], [pc.bold('Size'), humanBytes(repo.sizeBytes)], [pc.bold('Language'), repo.topLanguage ?? '—'], [pc.bold('License'), repo.license ?? '—'], [pc.bold('Topics'), repo.topics.join(', ') || '—'], [pc.bold('Last push'), ago(repo.lastPush)], [pc.bold('Clones'), String(repo.cloneCount ?? 0)], ]); }); }