SPB Git

spb/spbgit Public MIT

SPB Git — the platform hosting itself

JavaScript 73.9% CSS 11.7% Nunjucks 11.6% Shell 2.7%
3.3 KB · 77 lines javascript
Raw Blame History
1/**2 * ─────────────────────────────────────────────3 *  SPB Git — Personal Git Platform4 * ─────────────────────────────────────────────5 *  Author  : Simon-Pierre Boucher6 *  Contact : contact@spboucher.ai7 *  File    : cli/commands/create.mjs8 *  Purpose : `spbgit create` — create on server, optionally push cwd9 *  License : MIT © Simon-Pierre Boucher10 * ─────────────────────────────────────────────11 */1213import { existsSync } from 'node:fs';14import { join } from 'node:path';15import pc from 'picocolors';16import { requireCliConfig } from '../lib/config.mjs';17import { api, EXIT } from '../lib/api.mjs';18import { git } from '../lib/git.mjs';1920export function registerCreate(program) {21  program22    .command('create <name>')23    .description('create a repository on the server')24    .option('-d, --description <desc>', 'repository description', '')25    .option('--topics <topics>', 'comma-separated topics (max 10)')26    .option('--pinned', 'pin on the home page', false)27    .option('--push', 'also init the current directory, add remote, commit and push', false)28    .action(async (name, opts) => {29      const config = requireCliConfig();30      const topics = (opts.topics ?? '')31        .split(',')32        .map((t) => t.trim().toLowerCase())33        .filter(Boolean)34        .slice(0, 10);35      const repo = await api(config, 'POST', '/api/v1/repos', {36        name,37        description: opts.description,38        topics,39        pinned: Boolean(opts.pinned),40      });41      console.log(`${pc.green('✓')} Created ${pc.bold(repo.name)} → ${repo.url}`);4243      if (!opts.push) return;44      const cwd = process.cwd();45      if (!existsSync(join(cwd, '.git'))) {46        const init = await git(cwd, ['init', '-b', 'main']);47        if (!init.ok) {48          console.error(pc.red(`✗ git init failed: ${init.stderr}`));49          process.exit(EXIT.USER);50        }51        console.log(`${pc.green('✓')} Initialized git repository in ${cwd}`);52      }53      const hasRemote = await git(cwd, ['remote', 'get-url', 'origin']);54      if (!hasRemote.ok) {55        await git(cwd, ['remote', 'add', 'origin', repo.cloneUrl]);56        console.log(`${pc.green('✓')} Remote origin → ${repo.cloneUrl}`);57      }58      const hasCommit = await git(cwd, ['rev-parse', '--verify', 'HEAD']);59      if (!hasCommit.ok) {60        await git(cwd, ['add', '-A']);61        const commit = await git(cwd, ['commit', '-m', 'feat: initial commit']);62        if (!commit.ok) {63          console.error(pc.red(`✗ Nothing to commit — add files first, then: git push -u origin main`));64          process.exit(EXIT.USER);65        }66        console.log(`${pc.green('✓')} Initial commit created`);67      }68      const branch = (await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim() || 'main';69      const push = await git(cwd, ['push', '-u', 'origin', branch], { token: config.token });70      if (!push.ok) {71        console.error(pc.red(`✗ Push failed: ${push.stderr.trim()}`));72        process.exit(EXIT.NETWORK);73      }74      console.log(`${pc.green('✓')} Pushed ${branch} — live at ${repo.url}`);75    });76}77