aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/path_util/path_util.go29
-rw-r--r--internal/revision/parser.go4
-rw-r--r--internal/revision/parser_test.go7
-rw-r--r--internal/url/url.go6
-rwxr-xr-xinternal/url/url_test.go107
5 files changed, 120 insertions, 33 deletions
diff --git a/internal/path_util/path_util.go b/internal/path_util/path_util.go
new file mode 100644
index 0000000..48e4a3d
--- /dev/null
+++ b/internal/path_util/path_util.go
@@ -0,0 +1,29 @@
+package path_util
+
+import (
+ "os"
+ "os/user"
+ "strings"
+)
+
+func ReplaceTildeWithHome(path string) (string, error) {
+ if strings.HasPrefix(path, "~") {
+ firstSlash := strings.Index(path, "/")
+ if firstSlash == 1 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return path, err
+ }
+ return strings.Replace(path, "~", home, 1), nil
+ } else if firstSlash > 1 {
+ username := path[1:firstSlash]
+ userAccount, err := user.Lookup(username)
+ if err != nil {
+ return path, err
+ }
+ return strings.Replace(path, path[:firstSlash], userAccount.HomeDir, 1), nil
+ }
+ }
+
+ return path, nil
+}
diff --git a/internal/revision/parser.go b/internal/revision/parser.go
index 8facf17..8a2a719 100644
--- a/internal/revision/parser.go
+++ b/internal/revision/parser.go
@@ -322,6 +322,8 @@ func (p *Parser) parseAt() (Revisioner, error) {
}
return AtDate{t}, nil
+ case tok == eof:
+ return nil, &ErrInvalidRevision{s: `missing "}" in @{<data>} structure`}
default:
date += lit
}
@@ -424,6 +426,8 @@ func (p *Parser) parseCaretBraces() (Revisioner, error) {
p.unscan()
case tok != slash && start:
return nil, &ErrInvalidRevision{fmt.Sprintf(`"%s" is not a valid revision suffix brace component`, lit)}
+ case tok == eof:
+ return nil, &ErrInvalidRevision{s: `missing "}" in ^{<data>} structure`}
case tok != cbrace:
p.unscan()
re += lit
diff --git a/internal/revision/parser_test.go b/internal/revision/parser_test.go
index 98403cc..3a77b2f 100644
--- a/internal/revision/parser_test.go
+++ b/internal/revision/parser_test.go
@@ -183,7 +183,7 @@ func (s *ParserSuite) TestParseWithValidExpression(c *C) {
}
}
-func (s *ParserSuite) TestParseWithUnValidExpression(c *C) {
+func (s *ParserSuite) TestParseWithInvalidExpression(c *C) {
datas := map[string]error{
"..": &ErrInvalidRevision{`must not start with "."`},
"master^1master": &ErrInvalidRevision{`reference must be defined once at the beginning`},
@@ -198,6 +198,9 @@ func (s *ParserSuite) TestParseWithUnValidExpression(c *C) {
"~1": &ErrInvalidRevision{`"~" or "^" statement must have a reference defined at the beginning`},
"master:/test": &ErrInvalidRevision{`":" statement is not valid, could be : :/<regexp>`},
"master:0:README": &ErrInvalidRevision{`":" statement is not valid, could be : :<n>:<path>`},
+ "^{/": &ErrInvalidRevision{`missing "}" in ^{<data>} structure`},
+ "~@{": &ErrInvalidRevision{`missing "}" in @{<data>} structure`},
+ "@@{{0": &ErrInvalidRevision{`missing "}" in @{<data>} structure`},
}
for s, e := range datas {
@@ -230,7 +233,7 @@ func (s *ParserSuite) TestParseAtWithValidExpression(c *C) {
}
}
-func (s *ParserSuite) TestParseAtWithUnValidExpression(c *C) {
+func (s *ParserSuite) TestParseAtWithInvalidExpression(c *C) {
datas := map[string]error{
"{test}": &ErrInvalidRevision{`wrong date "test" must fit ISO-8601 format : 2006-01-02T15:04:05Z`},
"{-1": &ErrInvalidRevision{`missing "}" in @{-n} structure`},
diff --git a/internal/url/url.go b/internal/url/url.go
index 14cf133..2662448 100644
--- a/internal/url/url.go
+++ b/internal/url/url.go
@@ -5,8 +5,10 @@ import (
)
var (
- isSchemeRegExp = regexp.MustCompile(`^[^:]+://`)
- scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P<user>[^@]+)@)?(?P<host>[^:\s]+):(?:(?P<port>[0-9]{1,5})(?:\/|:))?(?P<path>[^\\].*\/[^\\].*)$`)
+ isSchemeRegExp = regexp.MustCompile(`^[^:]+://`)
+
+ // Ref: https://github.com/git/git/blob/master/Documentation/urls.txt#L37
+ scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P<user>[^@]+)@)?(?P<host>[^:\s]+):(?:(?P<port>[0-9]{1,5}):)?(?P<path>[^\\].*)$`)
)
// MatchesScheme returns true if the given string matches a URL-like
diff --git a/internal/url/url_test.go b/internal/url/url_test.go
index d168db6..29c3f3e 100755
--- a/internal/url/url_test.go
+++ b/internal/url/url_test.go
@@ -13,11 +13,27 @@ type URLSuite struct{}
var _ = Suite(&URLSuite{})
func (s *URLSuite) TestMatchesScpLike(c *C) {
+ // See https://github.com/git/git/blob/master/Documentation/urls.txt#L37
examples := []string{
+ // Most-extended case
"git@github.com:james/bond",
- "git@github.com:007/bond",
+ // Most-extended case with port
"git@github.com:22:james/bond",
+ // Most-extended case with numeric path
+ "git@github.com:007/bond",
+ // Most-extended case with port and numeric "username"
"git@github.com:22:007/bond",
+ // Single repo path
+ "git@github.com:bond",
+ // Single repo path with port
+ "git@github.com:22:bond",
+ // Single repo path with port and numeric repo
+ "git@github.com:22:007",
+ // Repo path ending with .git and starting with _
+ "git@github.com:22:_007.git",
+ "git@github.com:_007.git",
+ "git@github.com:_james.git",
+ "git@github.com:_james/bond.git",
}
for _, url := range examples {
@@ -26,35 +42,68 @@ func (s *URLSuite) TestMatchesScpLike(c *C) {
}
func (s *URLSuite) TestFindScpLikeComponents(c *C) {
- url := "git@github.com:james/bond"
- user, host, port, path := FindScpLikeComponents(url)
-
- c.Check(user, Equals, "git")
- c.Check(host, Equals, "github.com")
- c.Check(port, Equals, "")
- c.Check(path, Equals, "james/bond")
-
- url = "git@github.com:007/bond"
- user, host, port, path = FindScpLikeComponents(url)
-
- c.Check(user, Equals, "git")
- c.Check(host, Equals, "github.com")
- c.Check(port, Equals, "")
- c.Check(path, Equals, "007/bond")
-
- url = "git@github.com:22:james/bond"
- user, host, port, path = FindScpLikeComponents(url)
+ testCases := []struct {
+ url, user, host, port, path string
+ }{
+ {
+ // Most-extended case
+ url: "git@github.com:james/bond", user: "git", host: "github.com", port: "", path: "james/bond",
+ },
+ {
+ // Most-extended case with port
+ url: "git@github.com:22:james/bond", user: "git", host: "github.com", port: "22", path: "james/bond",
+ },
+ {
+ // Most-extended case with numeric path
+ url: "git@github.com:007/bond", user: "git", host: "github.com", port: "", path: "007/bond",
+ },
+ {
+ // Most-extended case with port and numeric path
+ url: "git@github.com:22:007/bond", user: "git", host: "github.com", port: "22", path: "007/bond",
+ },
+ {
+ // Single repo path
+ url: "git@github.com:bond", user: "git", host: "github.com", port: "", path: "bond",
+ },
+ {
+ // Single repo path with port
+ url: "git@github.com:22:bond", user: "git", host: "github.com", port: "22", path: "bond",
+ },
+ {
+ // Single repo path with port and numeric path
+ url: "git@github.com:22:007", user: "git", host: "github.com", port: "22", path: "007",
+ },
+ {
+ // Repo path ending with .git and starting with _
+ url: "git@github.com:22:_007.git", user: "git", host: "github.com", port: "22", path: "_007.git",
+ },
+ {
+ // Repo path ending with .git and starting with _
+ url: "git@github.com:_007.git", user: "git", host: "github.com", port: "", path: "_007.git",
+ },
+ {
+ // Repo path ending with .git and starting with _
+ url: "git@github.com:_james.git", user: "git", host: "github.com", port: "", path: "_james.git",
+ },
+ {
+ // Repo path ending with .git and starting with _
+ url: "git@github.com:_james/bond.git", user: "git", host: "github.com", port: "", path: "_james/bond.git",
+ },
+ }
- c.Check(user, Equals, "git")
- c.Check(host, Equals, "github.com")
- c.Check(port, Equals, "22")
- c.Check(path, Equals, "james/bond")
+ for _, tc := range testCases {
+ user, host, port, path := FindScpLikeComponents(tc.url)
- url = "git@github.com:22:007/bond"
- user, host, port, path = FindScpLikeComponents(url)
+ logf := func(ok bool) {
+ if ok {
+ return
+ }
+ c.Logf("%q check failed", tc.url)
+ }
- c.Check(user, Equals, "git")
- c.Check(host, Equals, "github.com")
- c.Check(port, Equals, "22")
- c.Check(path, Equals, "007/bond")
+ logf(c.Check(user, Equals, tc.user))
+ logf(c.Check(host, Equals, tc.host))
+ logf(c.Check(port, Equals, tc.port))
+ logf(c.Check(path, Equals, tc.path))
+ }
}