repo.go

113 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
//go:build cgo

package commands

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"strings"

	"congo.gg/dev/models"
)

const repoUsage = `Manage repos in the Congo Dev workspace

Usage:
  congo repo <subcommand>

Subcommands:
  list              List repos (JSON)
  create <name>     Create a new Congo project
  clone <url>       Clone a git repository
`

func Repo() {
	if len(os.Args) < 3 {
		fmt.Print(repoUsage)
		os.Exit(1)
	}

	switch os.Args[2] {
	case "list":
		repos, _ := models.Repositories.Search("ORDER BY Name")
		json.NewEncoder(os.Stdout).Encode(repos)
	case "create":
		repoCreate()
	case "clone":
		repoClone()
	default:
		fmt.Fprintf(os.Stderr, "unknown repo subcommand %q\n", os.Args[2])
		os.Exit(1)
	}
}

func repoCreate() {
	if len(os.Args) < 4 {
		fmt.Fprintln(os.Stderr, "usage: congo repo create <name>")
		os.Exit(1)
	}
	name := os.Args[3]

	// Run congo init in the repos directory
	cmd := exec.Command("congo", "init", name)
	cmd.Dir = "/home/coder/repos"
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "congo init failed: %v\n", err)
		os.Exit(1)
	}

	// Register in DB
	path := "/home/coder/repos/" + name
	exec.Command("git", "init", path).Run()
	exec.Command("git", "-C", path, "add", ".").Run()
	exec.Command("git", "-C", path, "commit", "-m", "Initial scaffold").Run()

	models.Repositories.Insert(&models.Repository{
		Name:   name,
		Path:   path,
		Branch: "main",
		Status: "created",
	})
	fmt.Println(name)
}

func repoClone() {
	if len(os.Args) < 4 {
		fmt.Fprintln(os.Stderr, "usage: congo repo clone <url>")
		os.Exit(1)
	}
	url := os.Args[3]

	// Extract name from URL
	name := url
	name = strings.TrimSuffix(name, "/")
	name = strings.TrimSuffix(name, ".git")
	if idx := strings.LastIndex(name, "/"); idx >= 0 {
		name = name[idx+1:]
	}
	if idx := strings.LastIndex(name, ":"); idx >= 0 {
		name = name[idx+1:]
	}

	path := "/home/coder/repos/" + name
	cmd := exec.Command("git", "clone", url, path)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "git clone failed: %v\n", err)
		os.Exit(1)
	}

	models.Repositories.Insert(&models.Repository{
		Name:   name,
		URL:    url,
		Path:   path,
		Branch: "main",
		Status: "cloned",
	})
	fmt.Println(name)
}