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