Skip to content

Commit d5758df

Browse files
stefanhallerkarolzwolak
authored andcommitted
refactor add fork functionality
Inline addRemoteAndRefresh and selectRemoteAndCheckout into addAndCheckoutRemote. It's not worth having them as separate helper functions since they are only called from within addAndCheckoutRemote, and that function is not overly long. This fixes two issues: - selectRemoteAndCheckout had an unused parameter remoteUrl - the error return value from addRemoteAndRefresh was not checked Prefer errors.New over fmt.Errorf when there are no placeholders. Combine the three regex's into one. While it makes the regex itself more complex, it simplifies the code.
1 parent 89c3950 commit d5758df

File tree

1 file changed

+15
-35
lines changed

1 file changed

+15
-35
lines changed

pkg/gui/controllers/remotes_controller.go

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controllers
22

33
import (
4+
"errors"
45
"fmt"
56
"regexp"
67
"slices"
@@ -143,8 +144,8 @@ func (self *RemotesController) enter(remote *models.Remote) error {
143144
return nil
144145
}
145146

146-
// Adds a new remote and refreshes the list of remotes.
147-
func (self *RemotesController) addRemoteAndRefresh(remoteName string, remoteUrl string) error {
147+
// Adds a new remote, refreshes and selects it, then fetches and checks out the specified branch if provided.
148+
func (self *RemotesController) addAndCheckoutRemote(remoteName string, remoteUrl string, branchToCheckout string) error {
148149
self.c.LogAction(self.c.Tr.Actions.AddRemote)
149150
err := self.c.Git().Remote.AddRemote(remoteName, remoteUrl)
150151
if err != nil {
@@ -158,11 +159,7 @@ func (self *RemotesController) addRemoteAndRefresh(remoteName string, remoteUrl
158159
Scope: []types.RefreshableView{types.REMOTES},
159160
Mode: types.SYNC,
160161
})
161-
return nil
162-
}
163162

164-
// Selects the given remote in the UI, fetches it, and checks out the specified branch if profided.
165-
func (self *RemotesController) selectRemoteAndCheckout(remoteName string, remoteUrl string, branchToCheckout string) error {
166163
// Select the remote
167164
for idx, remote := range self.c.Model().Remotes {
168165
if remote.Name == remoteName {
@@ -175,13 +172,6 @@ func (self *RemotesController) selectRemoteAndCheckout(remoteName string, remote
175172
return self.fetchAndCheckout(self.c.Contexts().Remotes.GetSelected(), branchToCheckout)
176173
}
177174

178-
// Adds a new remote, refreshes and selects it, then fetches and checks out the specified branch if provided.
179-
func (self *RemotesController) addAndCheckoutRemote(remoteName string, remoteUrl string, branchToCheckout string) error {
180-
self.addRemoteAndRefresh(remoteName, remoteUrl)
181-
182-
return self.selectRemoteAndCheckout(remoteName, remoteUrl, branchToCheckout)
183-
}
184-
185175
// Ensures the fork remote exists (matching the given URL).
186176
// If it exists and matches, it’s selected and fetched; otherwise, it’s created and then fetched and checked out.
187177
// If it does exist but with a different URL, an error is returned.
@@ -190,7 +180,7 @@ func (self *RemotesController) ensureForkRemoteAndCheckout(remoteName string, re
190180
if remote.Name == remoteName {
191181
hasTheSameUrl := slices.Contains(remote.Urls, remoteUrl)
192182
if !hasTheSameUrl {
193-
return fmt.Errorf("%s", utils.ResolvePlaceholderString(
183+
return errors.New(utils.ResolvePlaceholderString(
194184
self.c.Tr.IncompatibleForkAlreadyExistsError,
195185
map[string]string{
196186
"remoteName": remoteName,
@@ -222,37 +212,27 @@ func (self *RemotesController) add() error {
222212
return nil
223213
}
224214

225-
var (
226-
// 1. SCP-like SSH: git@host:owner[/subgroups]/repo(.git)
227-
sshScpRegex = regexp.MustCompile(`^(git@[^:]+:)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$`)
228-
229-
// 2. SSH URL style: ssh://user@host[:port]/owner[/subgroups]/repo(.git)
230-
sshUrlRegex = regexp.MustCompile(`^(ssh://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$`)
231-
232-
// 3. HTTPS: https://host/owner[/subgroups]/repo(.git)
233-
httpRegex = regexp.MustCompile(`^(https?://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$`)
234-
)
215+
// Regex to match and capture parts of a Git remote URL. Supports the following formats:
216+
// 1. SCP-like SSH: git@host:owner[/subgroups]/repo(.git)
217+
// 2. SSH URL style: ssh://user@host[:port]/owner[/subgroups]/repo(.git)
218+
// 3. HTTPS: https://host/owner[/subgroups]/repo(.git)
219+
var urlRegex = regexp.MustCompile(`^(git@[^:]+:|ssh://[^/]+/|https?://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$`)
235220

236221
// Rewrites a Git remote URL to use the given fork username,
237222
// keeping the repo name and host intact. Supports SCP-like SSH, SSH URL style, and HTTPS.
238223
func replaceForkUsername(remoteUrl, forkUsername string) (string, error) {
239224
if forkUsername == "" {
240-
return "", fmt.Errorf("fork username cannot be empty")
225+
return "", errors.New("fork username cannot be empty")
241226
}
242227
if remoteUrl == "" {
243-
return "", fmt.Errorf("remote URL cannot be empty")
228+
return "", errors.New("remote URL cannot be empty")
244229
}
245230

246-
switch {
247-
case sshScpRegex.MatchString(remoteUrl):
248-
return sshScpRegex.ReplaceAllString(remoteUrl, "${1}"+forkUsername+"/$3$4"), nil
249-
case sshUrlRegex.MatchString(remoteUrl):
250-
return sshUrlRegex.ReplaceAllString(remoteUrl, "${1}"+forkUsername+"/$3$4"), nil
251-
case httpRegex.MatchString(remoteUrl):
252-
return httpRegex.ReplaceAllString(remoteUrl, "${1}"+forkUsername+"/$3$4"), nil
253-
default:
254-
return "", fmt.Errorf("unsupported or invalid remote URL: %s", remoteUrl)
231+
if urlRegex.MatchString(remoteUrl) {
232+
return urlRegex.ReplaceAllString(remoteUrl, "${1}"+forkUsername+"/$3$4"), nil
255233
}
234+
235+
return "", fmt.Errorf("unsupported or invalid remote URL: %s", remoteUrl)
256236
}
257237

258238
func (self *RemotesController) addFork(baseRemote *models.Remote) error {

0 commit comments

Comments
 (0)