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