Skip to content

Commit

Permalink
cmd/server/commands: use relative path as id instead of last part (#816)
Browse files Browse the repository at this point in the history
cmd/server/commands: use relative path as id instead of last part
  • Loading branch information
ajnavarro authored May 20, 2019
2 parents 7dfd1e0 + d42dde8 commit 7a1da95
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 10 deletions.
29 changes: 20 additions & 9 deletions cmd/gitbase/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func (c *Server) addDirectory(directory string) error {
}

for _, match := range matches {
if err := c.addMatch(match); err != nil {
if err := c.addMatch(directory, match); err != nil {
logrus.WithFields(logrus.Fields{
"path": match,
"error": err,
Expand All @@ -296,11 +296,12 @@ func (c *Server) addDirectory(directory string) error {
return nil
}

func (c *Server) addMatch(match string) error {
func (c *Server) addMatch(prefix, match string) error {
root, err := filepath.Abs(match)
if err != nil {
return err
}

root, err = filepath.EvalSymlinks(root)
if err != nil {
return err
Expand All @@ -316,7 +317,7 @@ func (c *Server) addMatch(match string) error {
}

if info.IsDir() {
if err := c.addIfGitRepo(path); err != nil {
if err := c.addIfGitRepo(prefix, path); err != nil {
return err
}

Expand All @@ -329,8 +330,14 @@ func (c *Server) addMatch(match string) error {
}

if !c.DisableSiva &&
info.Mode().IsRegular() && gitbase.IsSivaFile(info.Name()) {
if err := c.pool.AddSivaFileWithID(info.Name(), path); err != nil {
info.Mode().IsRegular() &&
gitbase.IsSivaFile(info.Name()) {
id, err := gitbase.StripPrefix(prefix, path)
if err != nil {
return err
}

if err := c.pool.AddSivaFileWithID(id, path); err != nil {
logrus.WithFields(logrus.Fields{
"path": path,
"error": err,
Expand All @@ -346,7 +353,7 @@ func (c *Server) addMatch(match string) error {
})
}

func (c *Server) addIfGitRepo(path string) error {
func (c *Server) addIfGitRepo(prefix, path string) error {
ok, err := gitbase.IsGitRepo(path)
if err != nil {
logrus.WithFields(logrus.Fields{
Expand All @@ -359,10 +366,14 @@ func (c *Server) addIfGitRepo(path string) error {

if ok {
if !c.DisableGit {
base := filepath.Base(path)
if err := c.pool.AddGitWithID(base, path); err != nil {
id, err := gitbase.StripPrefix(prefix, path)
if err != nil {
return err
}

if err := c.pool.AddGitWithID(id, path); err != nil {
logrus.WithFields(logrus.Fields{
"id": base,
"id": id,
"path": path,
"error": err,
}).Error("repository could not be added")
Expand Down
31 changes: 30 additions & 1 deletion cmd/gitbase/command/server_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package command

import (
"io"
"os"
"sort"
"testing"

"github.com/src-d/gitbase"
Expand Down Expand Up @@ -31,6 +33,33 @@ func TestAddMatch(t *testing.T) {
}
c := &Server{pool: gitbase.NewRepositoryPool(0)}
for _, e := range expected {
e.err(c.addMatch(e.path))
e.err(c.addMatch("../../../_testdata", e.path))
}
}

func TestAddDirectory(t *testing.T) {
require := require.New(t)
c := &Server{pool: gitbase.NewRepositoryPool(0), Depth: 5}
require.NoError(c.addDirectory("../../../_testdata/*"))
i, err := c.pool.RepoIter()
require.NoError(err)

var repositories []string
for {
r, err := i.Next()
if err == io.EOF {
require.NoError(i.Close())
break
}

repositories = append(repositories, r.ID)
}

sort.Strings(repositories)
expected := []string{
"05893125684f2d3943cd84a7ab2b75e53668fba1.siva",
"ff/fff840f8784ef162dc83a1465fc5763d890b68ba.siva",
"fff7062de8474d10a67d417ccea87ba6f58ca81d.siva",
}
require.Equal(expected, repositories)
}
37 changes: 37 additions & 0 deletions path_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,43 @@ import (
// RegMatchChars matches a string with a glob expression inside.
var RegMatchChars = regexp.MustCompile(`(^|[^\\])([*[?])`)

// StripPrefix removes the root path from the given path. Root may be a glob.
// The returned string has all backslashes replaced with slashes.
func StripPrefix(root, path string) (string, error) {
var err error
root, err = filepath.Abs(cleanGlob(root))
if err != nil {
return "", err
}

if !strings.HasSuffix(root, "/") {
root += string(filepath.Separator)
}

path, err = filepath.Abs(path)
if err != nil {
return "", err
}

return strings.TrimPrefix(filepath.ToSlash(path), root), nil
}

// cleanGlob removes all the parts of a glob that are not fixed. It also
// converts all slashes or backslashes to /.
func cleanGlob(pattern string) string {
pattern = filepath.ToSlash(pattern)
var parts []string
for _, part := range strings.Split(pattern, "/") {
if strings.ContainsAny(part, "*?[\\") {
break
}

parts = append(parts, part)
}

return strings.Join(parts, "/")
}

// PatternMatches returns the paths matched and any error found.
func PatternMatches(pattern string) ([]string, error) {
abs, err := filepath.Abs(pattern)
Expand Down
48 changes: 48 additions & 0 deletions path_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,51 @@ func TestIsSivaFile(t *testing.T) {
require.True(IsSivaFile("is.siva"))
require.False(IsSivaFile("not-siva"))
}

func TestStripPrefix(t *testing.T) {
testCases := []struct {
root string
path string
expected string
}{
{
"_testdata/*",
"_testdata/05893125684f2d3943cd84a7ab2b75e53668fba1.siva",
"05893125684f2d3943cd84a7ab2b75e53668fba1.siva",
},
{
"_testdata/*",
"_testdata/foo/05893125684f2d3943cd84a7ab2b75e53668fba1.siva",
"foo/05893125684f2d3943cd84a7ab2b75e53668fba1.siva",
},
}

for _, tt := range testCases {
t.Run(tt.path, func(t *testing.T) {
output, err := StripPrefix(tt.root, tt.path)
require.NoError(t, err)
require.Equal(t, tt.expected, output)
})
}
}

func TestCleanGlob(t *testing.T) {
testCases := []struct {
pattern string
expected string
}{
{"../../../_testdata/?epositories", "../../../_testdata"},
{"../../../_testdata/**/repositories", "../../../_testdata"},
{"../../../_testdata/*/repositories", "../../../_testdata"},
{"../../../_testdata/*", "../../../_testdata"},
{"../../../_testdata/\\*/foo", "../../../_testdata"},
{"../../../_testdata/[a-z]/foo", "../../../_testdata"},
}

for _, tt := range testCases {
t.Run(tt.pattern, func(t *testing.T) {
output := cleanGlob(tt.pattern)
require.Equal(t, tt.expected, output)
})
}
}

0 comments on commit 7a1da95

Please sign in to comment.