Skip to content

Commit b201d2d

Browse files
committed
Allow more ways to specify the repository
gh-get now accepts more repository definitions that are allowed by GitHub CLI, see https://cli.github.com/manual/gh_repo_clone. Fixes #3
1 parent 638ef83 commit b201d2d

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Example:
1616

1717
`gh get britter/gh-get` will clone this respository into `~/github/britter/gh-get`
1818

19+
> [!TIP]
20+
> gh-get also accepts full github URLs like https://github.com/britter/gh-get.git as well as SSH protocol URLs like [email protected]:britter/gh-get.git.
21+
1922
## Configuration
2023

2124
There are two environment variables that control the location gh-get clones repositories to:

main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@ import (
55
"log"
66
"os"
77

8+
"github.com/britter/gh-get/pkg/github"
89
"github.com/cli/go-gh"
910
)
1011

1112
func main() {
1213
ghFolder := getGhFolder()
13-
repository, err := getRepository()
14+
repositoryDefinition, err := getRepository()
1415
if err != nil {
1516
log.Fatal(err)
1617
return
1718
}
1819

19-
repoClone := []string{"repo", "clone", repository, ghFolder + "/" + repository}
20+
repository, err := github.Parse(repositoryDefinition)
21+
if err != nil {
22+
log.Fatal(err)
23+
return
24+
}
25+
26+
repoClone := []string{"repo", "clone", repositoryDefinition, ghFolder + "/" + repository.Owner + "/" + repository.Name}
2027
stdOut, stdErr, err := gh.Exec(repoClone...)
2128
if err != nil {
2229
log.Fatal(err)

pkg/github/repository.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type Repository struct {
9+
Owner string
10+
Name string
11+
}
12+
13+
func Parse(definition string) (Repository, error) {
14+
definition = strings.TrimPrefix(definition, "https://github.com/")
15+
definition = strings.TrimPrefix(definition, "[email protected]:")
16+
definition = strings.TrimSuffix(definition, ".git")
17+
18+
parts := strings.Split(definition, "/")
19+
if len(parts) != 2 {
20+
return Repository{}, fmt.Errorf("Invalid repository definition: %s", definition)
21+
}
22+
23+
owner, name := parts[0], parts[1]
24+
if owner == "" || name == "" {
25+
return Repository{}, fmt.Errorf("Invalid repository definition: %s", definition)
26+
}
27+
28+
return Repository{parts[0], parts[1]}, nil
29+
}

pkg/github/repository_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package github
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestParse(t *testing.T) {
8+
tests := []struct {
9+
input string
10+
expectedOwner string
11+
expectedName string
12+
expectError bool
13+
}{
14+
// Valid cases
15+
{"owner/name", "owner", "name", false},
16+
{"https://github.com/owner/name", "owner", "name", false},
17+
{"https://github.com/owner/name.git", "owner", "name", false},
18+
{"[email protected]:owner/name.git", "owner", "name", false},
19+
20+
// Invalid cases
21+
{"https://github.com/invalidinput", "", "", true}, // Missing /
22+
{"invalidinput", "", "", true}, // Missing /
23+
{"https://github.com/", "", "", true}, // Empty path
24+
{"owner/", "", "", true}, // Missing name
25+
{"/name", "", "", true}, // Missing owner
26+
}
27+
28+
for _, test := range tests {
29+
repository, err := Parse(test.input)
30+
31+
if test.expectError {
32+
if err == nil {
33+
t.Errorf("Expected error for input %q, but got none", test.input)
34+
}
35+
} else {
36+
if err != nil {
37+
t.Errorf("Did not expect error fro input %q, but got: %v", test.input, err)
38+
}
39+
if repository.Owner != test.expectedOwner {
40+
t.Errorf("For input %q, expected owner %q, but got %q", test.input, test.expectedOwner, repository.Owner)
41+
}
42+
if repository.Name != test.expectedName {
43+
t.Errorf("For input %q, expected name %q, but got %q", test.input, test.expectedName, repository.Name)
44+
}
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)