LocalClone.go 2.7 K raw
1
package main
2
3
import (
4
	"flag"
5
	"fmt"
6
	"os"
7
	"os/exec"
8
	"path/filepath"
9
10
	"github.com/AlecAivazis/survey/v2"
11
	"github.com/fatih/color"
12
)
13
14
type Repo struct {
15
	Path string
16
	Name string
17
}
18
19
var isPrivate bool
20
21
func LocalClone() error {
22
	flag.BoolVar(&isPrivate, "private", false, "Initialize repositories as private")
23
	flag.Parse()
24
25
	repos := findGitRepos(".")
26
	selectedRepos := selectLocalRepos(repos)
27
	confirmAndInitRepos(selectedRepos)
28
	return nil
29
}
30
31
func findGitRepos(root string) []Repo {
32
	var repos []Repo
33
	var scannedDirs int
34
35
	entries, err := os.ReadDir(root)
36
	if err != nil {
37
		fmt.Printf("Error reading directory %v: %v\n", root, err)
38
		return repos
39
	}
40
41
	for _, entry := range entries {
42
		if !entry.IsDir() {
43
			continue
44
		}
45
46
		scannedDirs++
47
		fmt.Printf("\rScanned %d directories...", scannedDirs)
48
49
		dirPath := filepath.Join(root, entry.Name())
50
		gitDir := filepath.Join(dirPath, ".git")
51
52
		if _, err := os.Stat(gitDir); err == nil {
53
			repos = append(repos, Repo{
54
				Path: dirPath,
55
				Name: entry.Name(),
56
			})
57
		}
58
	}
59
60
	fmt.Printf("\rScanned %d directories. Found %d Git repositories.\n", scannedDirs, len(repos))
61
62
	return repos
63
}
64
65
func selectLocalRepos(repos []Repo) []Repo {
66
	var options []string
67
	for _, repo := range repos {
68
		options = append(options, repo.Name)
69
	}
70
71
	var selected []string
72
	prompt := &survey.MultiSelect{
73
		Message: "Select repositories to initialize:",
74
		Options: options,
75
	}
76
	survey.AskOne(prompt, &selected)
77
78
	var selectedRepos []Repo
79
	for _, name := range selected {
80
		for _, repo := range repos {
81
			if repo.Name == name {
82
				selectedRepos = append(selectedRepos, repo)
83
				break
84
			}
85
		}
86
	}
87
88
	return selectedRepos
89
}
90
91
func confirmAndInitRepos(repos []Repo) {
92
	visibilityStr := "public"
93
	if isPrivate {
94
		visibilityStr = "private"
95
	}
96
97
	confirm := false
98
	prompt := &survey.Confirm{
99
		Message: fmt.Sprintf("Initialize %d repositories as %s?", len(repos), visibilityStr),
100
	}
101
	survey.AskOne(prompt, &confirm)
102
103
	if !confirm {
104
		fmt.Println("Radicalization cancelled.")
105
		return
106
	}
107
108
	fmt.Printf("Initializing %d repositories as %s...\n", len(repos), visibilityStr)
109
110
	for i, repo := range repos {
111
		fmt.Printf("Initializing %s (%d/%d)...\n", repo.Name, i+1, len(repos))
112
		err := runRadInit(repo.Path, repo.Name)
113
		if err != nil {
114
			color.Red("Error initializing %s: %v\n", repo.Name, err)
115
		} else {
116
			color.Green("Initialized %s as %s\n", repo.Name, visibilityStr)
117
		}
118
	}
119
120
	fmt.Println("Radicalization Complete")
121
}
122
123
func runRadInit(path, name string) error {
124
	visibilityFlag := "--public"
125
	if isPrivate {
126
		visibilityFlag = "--private"
127
	}
128
129
	cmd := exec.Command("rad", "init", "--name", name, "--description", "", visibilityFlag, "--no-confirm")
130
	cmd.Dir = path
131
	return cmd.Run()
132
}