-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simple utility for calculating the directory for go repos to go
- Loading branch information
Showing
3 changed files
with
203 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,6 @@ | |
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Tag file | ||
tags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"go/build" | ||
"net/url" | ||
"os" | ||
"path" | ||
"strings" | ||
) | ||
|
||
// parseStandardURL parses a standard URI formatted git URL | ||
func parseStandardURL(repo string) (pathParts []string, err error) { | ||
parsedURL, err := url.Parse(repo) | ||
if err != nil { | ||
return | ||
} | ||
|
||
if parsedURL.Host == "" { | ||
err = errors.New("Missing host part") | ||
return | ||
} | ||
|
||
pathParts = append(pathParts, parsedURL.Host) | ||
|
||
for _, pathPart := range strings.Split(parsedURL.Path, "/") { | ||
if pathPart == "" { | ||
continue | ||
} | ||
pathParts = append(pathParts, pathPart) | ||
} | ||
|
||
return | ||
} | ||
|
||
// parseWeirdGitURL tries to make sense of a user@host:path format git URL | ||
func parseWeirdGitURL(repo string) (pathParts []string, err error) { | ||
|
||
hostIndex := strings.Index(repo, "@") + 1 | ||
pathIndex := strings.Index(repo, ":") + 1 | ||
repoPath := strings.Split(string(repo[pathIndex:]), "/") | ||
|
||
// If there is no : then this is wrong | ||
if pathIndex == 0 || len(repoPath) == 0 { | ||
err = errors.New("Missing path part") | ||
return | ||
} | ||
|
||
// if index of @ is -1 then host is the first thing | ||
// if @ is after : then it's part of the path | ||
if hostIndex > pathIndex { | ||
hostIndex = 0 | ||
} | ||
|
||
host := string(repo[hostIndex : pathIndex-1]) | ||
pathParts = append(pathParts, host) | ||
|
||
for _, pathPart := range repoPath { | ||
if pathPart == "" { | ||
err = fmt.Errorf("Blank path segment") | ||
return | ||
} | ||
pathParts = append(pathParts, pathPart) | ||
} | ||
|
||
return | ||
} | ||
|
||
// calculateSourcePath works out the local filesystem path to directory above a given repo | ||
func calculateSourcePath(goPath string, repo string) (repoPath string, err error) { | ||
pathParts, err := parseStandardURL(repo) | ||
if err != nil { | ||
pathParts, err = parseWeirdGitURL(repo) | ||
if err != nil { | ||
return | ||
} | ||
} | ||
|
||
if len(pathParts) < 2 { | ||
err = errors.New("Host and path required") | ||
return | ||
} | ||
|
||
pathParts = append([]string{goPath, "src"}, pathParts[:len(pathParts)-1]...) | ||
repoPath = path.Join(pathParts...) | ||
return | ||
} | ||
|
||
func getGoPath() string { | ||
goPath := os.Getenv("GOPATH") | ||
if goPath != "" { | ||
return goPath | ||
} | ||
return build.Default.GOPATH | ||
} | ||
|
||
func main() { | ||
args := os.Args[1:] | ||
|
||
// Require at least one repo | ||
if len(args) == 0 { | ||
os.Exit(1) | ||
} | ||
|
||
// Work out where GOPATH really is | ||
goPath := getGoPath() | ||
|
||
// Calculate path for all repos | ||
for _, repo := range args { | ||
repoPath, err := calculateSourcePath(goPath, repo) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Cannot parse repo URL %s: %s\n", repo, err) | ||
os.Exit(1) | ||
} | ||
fmt.Println(repoPath) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package main | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
type ParseTest struct { | ||
Name string | ||
Repo string | ||
} | ||
|
||
func TestParsesStandardURL(t *testing.T) { | ||
for _, test := range []ParseTest{ | ||
{"HTTPS", "https://[email protected]/path/to/repo"}, | ||
{"SSH", "ssh://[email protected]/path/to/repo"}, | ||
{"Empty path elements", "https://[email protected]//path//to//repo"}, | ||
} { | ||
repoPath, err := parseStandardURL(test.Repo) | ||
if err != nil { | ||
t.Errorf("%s: Unexpected error %q", test.Name, err) | ||
} | ||
|
||
expectedPath := []string{"host.com", "path", "to", "repo"} | ||
if !reflect.DeepEqual(repoPath, expectedPath) { | ||
t.Errorf("%s: Expected %q, got %q", test.Name, expectedPath, repoPath) | ||
} | ||
} | ||
} | ||
|
||
func TestParsesWeirdGitURL(t *testing.T) { | ||
for _, test := range []ParseTest{ | ||
{"with user", "[email protected]:path/to/repo"}, | ||
{"without user", "host.com:path/to/repo"}, | ||
} { | ||
repoPath, err := parseWeirdGitURL(test.Repo) | ||
if err != nil { | ||
t.Errorf("%s: Unexpected error %q", test.Name, err) | ||
} | ||
|
||
expectedPath := []string{"host.com", "path", "to", "repo"} | ||
if !reflect.DeepEqual(repoPath, expectedPath) { | ||
t.Errorf("%s: Expected %q, got %q", test.Name, expectedPath, repoPath) | ||
} | ||
} | ||
} | ||
|
||
func TestIsIntolerantToEmptyPathElementsInWeirdURL(t *testing.T) { | ||
_, err := parseWeirdGitURL("[email protected]:path/to//repo") | ||
if err == nil { | ||
t.Errorf("Expected error, got %q", err) | ||
} | ||
} | ||
|
||
func TestSourcePath(t *testing.T) { | ||
for _, test := range []ParseTest{ | ||
{"Standard URL", "https://[email protected]/path/to/repo"}, | ||
{"Weird URL", "[email protected]:path/to/repo"}, | ||
} { | ||
repoPath, err := calculateSourcePath("/home/user", test.Repo) | ||
if err != nil { | ||
t.Errorf("%s: Unexpected error %q", test.Name, err) | ||
} | ||
|
||
expectedPath := "/home/user/src/host.com/path/to" | ||
if repoPath != expectedPath { | ||
t.Errorf("%sExpected %q, got %q", test.Name, expectedPath, repoPath) | ||
} | ||
} | ||
} | ||
|
||
func TestSourcePathErrorsIfMissingHostOrPath(t *testing.T) { | ||
for _, test := range []ParseTest{ | ||
{"Standard URL", "https://[email protected]/"}, | ||
{"Weird URL", "[email protected]:"}, | ||
} { | ||
_, err := calculateSourcePath("/home/user", "[email protected]:") | ||
if err == nil { | ||
t.Errorf("%s: Expected error, got %q", test.Name, err) | ||
} | ||
} | ||
} |