Skip to content

Commit ca70e26

Browse files
committed
cleanig
1 parent f93f8b0 commit ca70e26

8 files changed

Lines changed: 125 additions & 112 deletions

File tree

git-genius

1.09 MB
Binary file not shown.

internal/github/token.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,6 @@ func HasStoredToken() bool {
7373
return storedToken() != ""
7474
}
7575

76-
func HasStoredUsername() bool {
77-
return storedUsername() != ""
78-
}
79-
8076
func storedToken() string {
8177
path, err := getTokenPath()
8278
if err != nil {

internal/menu/menu.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func mainMenu() bool {
160160

161161
func limitedMenu() bool {
162162
fmt.Println("1) Setup / Reconfigure")
163-
fmt.Println("2) Change Project Directory")
163+
fmt.Println("2) Switch Project")
164164
fmt.Println("3) Doctor (health check)")
165165
fmt.Println("4) Help / About")
166166
fmt.Println("5) Exit")
@@ -171,7 +171,7 @@ func limitedMenu() bool {
171171
case "1":
172172
track("tools", "setup_reconfigure", setup.Run)
173173
case "2":
174-
track("tools", "change_project_dir", setup.ChangeProjectDir)
174+
track("tools", "switch_project", setup.SwitchProject)
175175
case "3":
176176
track("tools", "doctor", doctor.Run)
177177
case "4", "h", "help", "?":
@@ -308,14 +308,14 @@ func toolsMenu(gitAvailable bool) {
308308
ui.Header("Tools")
309309

310310
fmt.Println("1) Setup / Reconfigure")
311+
fmt.Println("2) Switch Project")
312+
311313
if gitAvailable {
312-
fmt.Println("2) Create / Link GitHub Repository")
313-
fmt.Println("3) Git Auth / Credential Helper")
314-
fmt.Println("4) Switch Project / Repo")
314+
fmt.Println("3) Create / Link GitHub Repository")
315+
fmt.Println("4) Git Auth / Credential Helper")
315316
fmt.Println("5) Doctor (health check)")
316317
fmt.Println("6) Back")
317318
} else {
318-
fmt.Println("2) Change Project Directory")
319319
fmt.Println("3) Doctor (health check)")
320320
fmt.Println("4) Back")
321321
}
@@ -326,28 +326,24 @@ func toolsMenu(gitAvailable bool) {
326326
case "1":
327327
track("tools", "setup_reconfigure", setup.Run)
328328
case "2":
329-
if gitAvailable {
330-
track("tools", "create_or_link_repo", setup.CreateOrLinkRepo)
331-
} else {
332-
track("tools", "change_project_dir", setup.ChangeProjectDir)
333-
}
329+
track("tools", "switch_project", setup.SwitchProject)
334330
case "3":
335331
if gitAvailable {
336-
track("tools", "configure_git_auth", setup.ConfigureGitAuth)
332+
track("tools", "create_or_link_repo", setup.CreateOrLinkRepo)
337333
} else {
338334
track("tools", "doctor", doctor.Run)
339335
}
340336
case "4":
341337
if gitAvailable {
342-
track("tools", "switch_project_repo", setup.SwitchProjectRepo)
338+
track("tools", "configure_git_auth", setup.ConfigureGitAuth)
343339
} else {
344340
return
345341
}
346342
case "5":
347343
if gitAvailable {
348344
track("tools", "doctor", doctor.Run)
349345
} else {
350-
return
346+
ui.Error("Invalid option")
351347
}
352348
case "6":
353349
if gitAvailable {

internal/setup/change_dir.go

Lines changed: 102 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,13 @@ import (
1212
"git-genius/internal/ui"
1313
)
1414

15-
func ChangeProjectDir() bool {
16-
return switchProject(false)
17-
}
18-
19-
func SwitchProjectRepo() bool {
20-
return switchProject(true)
21-
}
22-
23-
func switchProject(withRepoOptions bool) bool {
24-
title := "Change Project Directory"
25-
if withRepoOptions {
26-
title = "Switch Project / Repo"
27-
}
28-
15+
/*
16+
SwitchProject is the unified entry point for changing the active project directory.
17+
It detects if the target is a Git repo and shows context before switching.
18+
*/
19+
func SwitchProject() bool {
2920
ui.Clear()
30-
ui.Header(title)
21+
ui.Header("Switch Project")
3122

3223
current := config.Load().GetWorkDir()
3324
ui.Info("Current project directory:")
@@ -52,33 +43,65 @@ func switchProject(withRepoOptions bool) bool {
5243
return false
5344
}
5445

55-
cfg, isRepo, err := activateProjectDir(resolveRecentDir(dir, recent))
46+
targetDir := resolveRecentDir(dir, recent)
47+
abs, err := filepath.Abs(targetDir)
5648
if err != nil {
57-
ui.Error(err.Error())
49+
ui.Error("Failed to resolve directory path")
50+
if !ui.ConfirmDefault("Try another directory?", true) {
51+
return false
52+
}
53+
continue
54+
}
55+
56+
info, err := os.Stat(abs)
57+
if err != nil || !info.IsDir() {
58+
ui.Error("Invalid directory path")
5859
if !ui.ConfirmDefault("Try another directory?", true) {
5960
return false
6061
}
6162
continue
6263
}
6364

65+
// Load config for the target directory to show context
66+
targetCfg := config.LoadForWorkDir(abs)
67+
isRepo := system.IsGitRepoAt(abs)
68+
69+
ui.Divider()
70+
ui.Info("Target Directory: " + abs)
71+
if isRepo {
72+
ui.Success("Git repository detected")
73+
showRepoContext(abs, targetCfg)
74+
} else {
75+
ui.Warn("Not a git repository")
76+
}
77+
ui.Divider()
78+
79+
if !ui.ConfirmDefault("Switch to this project?", true) {
80+
if ui.Confirm("Try another directory?") {
81+
continue
82+
}
83+
return false
84+
}
85+
86+
// Perform the switch
87+
config.SetActiveWorkDir(abs)
6488
ui.Success("Project directory updated")
65-
ui.Info("New project directory:")
66-
ui.Info(cfg.WorkDir)
6789

6890
if !isRepo {
69-
return handleNonRepoSelection(cfg)
91+
return handleNonRepoSelection(targetCfg)
7092
}
7193

72-
ui.Success("Git repository detected in new directory")
73-
bootstrapProjectConfig(&cfg)
94+
// Sync branch/remote defaults if it's a new repo for Git Genius
95+
bootstrapProjectConfig(&targetCfg)
7496

75-
if !system.EnsureBranchSync() {
76-
return false
97+
// Offer post-switch options if Git is available
98+
if system.CommandExists("git") {
99+
if !system.EnsureBranchSync() {
100+
return false
101+
}
102+
return offerRepoSwitchOptions(targetCfg)
77103
}
78104

79-
if withRepoOptions {
80-
return offerRepoSwitchOptions(cfg)
81-
}
82105
return true
83106
}
84107
}
@@ -93,29 +116,32 @@ func resolveRecentDir(input string, recent []string) string {
93116
return input
94117
}
95118

96-
func activateProjectDir(dir string) (config.Config, bool, error) {
97-
abs, err := filepath.Abs(strings.TrimSpace(dir))
98-
if err != nil {
99-
return config.Config{}, false, fmt.Errorf("failed to resolve directory path")
119+
func showRepoContext(dir string, cfg config.Config) {
120+
// We need to temporarily set the work dir to inspect it, or use GitOutputAt
121+
branch, _ := system.GitOutputAt(dir, "branch", "--show-current")
122+
if branch == "" {
123+
branch = cfg.Branch
100124
}
101-
102-
info, err := os.Stat(abs)
103-
if err != nil || !info.IsDir() {
104-
return config.Config{}, false, fmt.Errorf("invalid directory path")
125+
if branch == "" {
126+
branch = "-"
105127
}
106128

107-
config.SetActiveWorkDir(abs)
108-
109-
if system.IsGitRepo() {
110-
system.EnsureSafeDirectory(abs)
111-
cfg := config.Load()
112-
cfg.WorkDir = abs
113-
return cfg, true, nil
129+
remote := cfg.Remote
130+
if remote == "" {
131+
// Try to auto-detect a remote if not in config
132+
if remotes, err := system.RemoteNames(); err == nil && len(remotes) > 0 {
133+
remote = remotes[0]
134+
}
135+
}
136+
if remote == "" {
137+
remote = "-"
114138
}
115139

116-
cfg := config.LoadForWorkDir(abs)
117-
cfg.WorkDir = abs
118-
return cfg, false, nil
140+
ui.Info("Branch : " + branch)
141+
ui.Info("Remote : " + remote)
142+
if cfg.Owner != "" && cfg.Repo != "" {
143+
ui.Info("Repo : https://github.com/" + cfg.Owner + "/" + cfg.Repo)
144+
}
119145
}
120146

121147
func bootstrapProjectConfig(cfg *config.Config) {
@@ -126,14 +152,17 @@ func bootstrapProjectConfig(cfg *config.Config) {
126152
changed := false
127153

128154
if !config.HasProjectConfig(cfg.WorkDir) {
129-
if branch := system.CurrentGitBranch(); branch != "" {
155+
if branch, _ := system.GitOutputAt(cfg.WorkDir, "branch", "--show-current"); branch != "" {
130156
cfg.Branch = branch
131157
changed = true
132158
}
133159

134-
if remotes, err := system.RemoteNames(); err == nil && len(remotes) == 1 {
135-
cfg.Remote = remotes[0]
136-
changed = true
160+
if remotes, err := system.GitOutputAt(cfg.WorkDir, "remote"); err == nil && remotes != "" {
161+
lines := strings.Split(remotes, "\n")
162+
if len(lines) > 0 && lines[0] != "" {
163+
cfg.Remote = strings.TrimSpace(lines[0])
164+
changed = true
165+
}
137166
}
138167
}
139168

@@ -142,17 +171,21 @@ func bootstrapProjectConfig(cfg *config.Config) {
142171
}
143172

144173
config.Save(*cfg)
145-
ui.Info("Loaded repo defaults for this project so setup does not need to be repeated")
174+
ui.Info("Loaded repo defaults for this project")
146175
}
147176

148177
func handleNonRepoSelection(cfg config.Config) bool {
149-
ui.Warn("Selected directory is not a git repository")
178+
if !system.CommandExists("git") {
179+
ui.Warn("Git is not installed. Operations will be limited.")
180+
return true
181+
}
182+
150183
if !ui.Confirm("Initialize a git repository here?") {
151184
ui.Warn("Git operations will be limited until repo is initialized")
152185
return true
153186
}
154187

155-
if err := system.RunGit("init"); err != nil {
188+
if err := system.RunGitAt(cfg.WorkDir, "init"); err != nil {
156189
ui.Error("Failed to initialize git repository")
157190
return false
158191
}
@@ -161,37 +194,39 @@ func handleNonRepoSelection(cfg config.Config) bool {
161194
bootstrapProjectConfig(&cfg)
162195

163196
if cfg.Branch != "" {
164-
if err := system.PrepareBranch(cfg.Branch); err != nil {
165-
ui.Warn("Could not prepare configured branch")
166-
ui.Info(err.Error())
167-
} else {
168-
ui.Success("Branch ready: " + cfg.Branch)
169-
}
197+
// We can't use PrepareBranch easily here because it uses config.Load()
198+
// but we just initialized a repo. Let's just try to create/checkout.
199+
_ = system.RunGitAt(cfg.WorkDir, "checkout", "-b", cfg.Branch)
170200
}
171201

172202
return true
173203
}
174204

175205
func offerRepoSwitchOptions(cfg config.Config) bool {
176-
ui.Info("Saved branch : " + cfg.Branch)
177-
ui.Info("Saved remote : " + cfg.Remote)
206+
ui.Info("Current branch : " + cfg.Branch)
207+
ui.Info("Current remote : " + cfg.Remote)
178208

179-
if ui.Confirm("Switch branch in this repo now?") {
209+
if ui.Confirm("Switch branch now?") {
180210
if !gitops.SwitchBranch() {
181211
return false
182212
}
183213
}
184214

185-
if ui.Confirm("Configure or switch the active remote now?") {
215+
if ui.Confirm("Configure or switch remote now?") {
186216
if !gitops.SwitchRemote() {
187217
return false
188218
}
189219
}
190220

191-
if !config.HasProjectConfig(cfg.WorkDir) {
192-
ui.Info("This repo is using auto-detected defaults right now")
193-
ui.Info("Run Tools -> Setup / Reconfigure later if you want to save owner/repo details too")
194-
}
195-
196221
return true
197222
}
223+
224+
// Deprecated: used for backward compatibility during refactor
225+
func ChangeProjectDir() bool {
226+
return SwitchProject()
227+
}
228+
229+
// Deprecated: used for backward compatibility during refactor
230+
func SwitchProjectRepo() bool {
231+
return SwitchProject()
232+
}

internal/system/git.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -668,14 +668,6 @@ func envSlice(env map[string]string) []string {
668668
return out
669669
}
670670

671-
func CurrentGitBranchAt(dir string) string {
672-
branch, err := GitOutputAt(dir, "branch", "--show-current")
673-
if err != nil {
674-
return ""
675-
}
676-
return branch
677-
}
678-
679671
func EnsureBranchSync() bool {
680672
if !IsGitRepo() {
681673
return true

internal/ui/help.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ var HelpTools = []string{
109109
"- Initialize git",
110110
"- Configure branch, remote, GitHub",
111111
"",
112+
"Switch Project",
113+
"- Switch to another project folder",
114+
"- Detects if the folder is a Git repo and shows context before switching",
115+
"- Loads that repo's saved branch and remote config when available",
116+
"- Can immediately switch branch or remote after changing directory",
117+
"",
112118
"Create / Link GitHub Repository",
113119
"- Create repo on GitHub if missing",
114120
"- Link local project to GitHub",
@@ -119,11 +125,6 @@ var HelpTools = []string{
119125
"- Can preload your current GitHub token into Git",
120126
"- Best fix when push keeps asking for username and token",
121127
"",
122-
"Switch Project / Repo",
123-
"- Switch to another project folder without re-running full setup",
124-
"- Loads that repo's saved branch and remote config when available",
125-
"- Can immediately switch branch or remote after changing directory",
126-
"",
127128
"Doctor",
128129
"- Checks git, branch, remote, token, repo",
129130
"- Suggests fixes if something is wrong",
@@ -168,7 +169,7 @@ var HelpWorkflow = []string{
168169
"- Push with a clear commit message",
169170
"",
170171
"Multi-Project Workflow",
171-
"- Use Tools -> Switch Project / Repo",
172+
"- Use Tools -> Switch Project",
172173
"- Re-run Setup when switching to a brand-new repo",
173174
}
174175

@@ -190,6 +191,6 @@ var HelpTroubleshooting = []string{
190191
"- Re-run Tools -> Setup / Reconfigure if needed",
191192
"",
192193
"Switching between repos should not require setup every time",
193-
"- Use Tools -> Switch Project / Repo",
194+
"- Use Tools -> Switch Project",
194195
"- Each repo keeps its own local .git/.genius/config.json",
195196
}

0 commit comments

Comments
 (0)