Skip to content

Commit 4d99164

Browse files
authored
Merge pull request #416 from mcarmonaa/improvement/load-siva-git-depth
cmd/gitbase: load siva files and git indistinctly
2 parents 93e2292 + dad44aa commit 4d99164

File tree

11 files changed

+203
-339
lines changed

11 files changed

+203
-339
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ CMD gitbase server -v \
3636
--port=3306 \
3737
--user="$GITBASE_USER" \
3838
--password="$GITBASE_PASSWORD" \
39-
--git="$GITBASE_REPOS"
39+
--directories="$GITBASE_REPOS"

cmd/gitbase/command/server.go

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"path/filepath"
77
"strconv"
8+
"strings"
89

910
"github.com/src-d/gitbase"
1011
"github.com/src-d/gitbase/internal/function"
@@ -34,8 +35,10 @@ const (
3435
// Server represents the `server` command of gitbase cli tool.
3536
type Server struct {
3637
Verbose bool `short:"v" description:"Activates the verbose mode"`
37-
Git []string `short:"g" long:"git" description:"Path where the git repositories are located, multiple directories can be defined. Accepts globs."`
38-
Siva []string `long:"siva" description:"Path where the siva repositories are located, multiple directories can be defined. Accepts globs."`
38+
Directories []string `short:"d" long:"directories" description:"Path where the git repositories are located (standard and siva), multiple directories can be defined. Accepts globs."`
39+
Depth int `long:"depth" default:"1000" description:"load repositories looking at less than <depth> nested subdirectories."`
40+
DisableGit bool `long:"no-git" description:"disable the load of git standard repositories."`
41+
DisableSiva bool `long:"no-siva" description:"disable the load of siva files."`
3942
Host string `long:"host" default:"localhost" description:"Host where the server is going to listen"`
4043
Port int `short:"p" long:"port" default:"3306" description:"Port where the server is going to listen"`
4144
User string `short:"u" long:"user" default:"root" description:"User name used for connection"`
@@ -196,52 +199,121 @@ func (c *Server) registerDrivers() error {
196199
}
197200

198201
func (c *Server) addDirectories() error {
199-
if len(c.Git) == 0 && len(c.Siva) == 0 {
200-
logrus.Error("At least one git folder or siva folder should be provided.")
202+
if len(c.Directories) == 0 {
203+
logrus.Error("At least one folder should be provided.")
201204
}
202205

203-
for _, pattern := range c.Git {
204-
if err := c.addGitPattern(pattern); err != nil {
205-
return err
206-
}
206+
if c.DisableGit && c.DisableSiva {
207+
logrus.Warn("The load of git repositories and siva files are disabled," +
208+
" no repository will be added.")
209+
210+
return nil
207211
}
208212

209-
for _, pattern := range c.Siva {
210-
if err := c.addSivaPattern(pattern); err != nil {
213+
if c.Depth < 1 {
214+
logrus.Warn("--depth flag set to a number less than 1," +
215+
" no repository will be added.")
216+
217+
return nil
218+
}
219+
220+
for _, directory := range c.Directories {
221+
if err := c.addDirectory(directory); err != nil {
211222
return err
212223
}
213224
}
214225

215226
return nil
216227
}
217228

218-
func (c *Server) addGitPattern(pattern string) error {
219-
prefix, matches, err := gitbase.PatternMatches(pattern)
229+
func (c *Server) addDirectory(directory string) error {
230+
matches, err := gitbase.PatternMatches(directory)
220231
if err != nil {
221232
return err
222233
}
223234

224-
for _, m := range matches {
225-
logrus.WithField("dir", m).Debug("git repositories directory added")
226-
if err := c.pool.AddDir(prefix, m); err != nil {
227-
return err
235+
for _, match := range matches {
236+
if err := c.addMatch(match); err != nil {
237+
logrus.WithFields(logrus.Fields{
238+
"path": match,
239+
"error": err,
240+
}).Error("path couldn't be inspected")
228241
}
229242
}
230243

231244
return nil
232245
}
233246

234-
func (c *Server) addSivaPattern(pattern string) error {
235-
matches, err := filepath.Glob(pattern)
247+
func (c *Server) addMatch(match string) error {
248+
root, err := filepath.Abs(match)
236249
if err != nil {
237250
return err
238251
}
239252

240-
for _, m := range matches {
241-
logrus.WithField("dir", m).Debug("siva repositories directory added")
242-
if err := c.pool.AddSivaDir(m); err != nil {
253+
initDepth := strings.Count(root, string(os.PathSeparator))
254+
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
255+
if err != nil {
243256
return err
244257
}
258+
259+
if info.IsDir() {
260+
if err := c.addIfGitRepo(path); err != nil {
261+
return err
262+
}
263+
264+
depth := strings.Count(path, string(os.PathSeparator)) - initDepth
265+
if depth >= c.Depth {
266+
return filepath.SkipDir
267+
}
268+
269+
return nil
270+
}
271+
272+
if !c.DisableSiva &&
273+
info.Mode().IsRegular() && gitbase.IsSivaFile(info.Name()) {
274+
if err := c.pool.AddSivaFile(path); err != nil {
275+
logrus.WithFields(logrus.Fields{
276+
"path": path,
277+
"error": err,
278+
}).Error("repository could not be addded")
279+
280+
return nil
281+
}
282+
283+
logrus.WithField("path", path).Debug("repository added")
284+
}
285+
286+
return nil
287+
})
288+
}
289+
290+
func (c *Server) addIfGitRepo(path string) error {
291+
ok, err := gitbase.IsGitRepo(path)
292+
if err != nil {
293+
logrus.WithFields(logrus.Fields{
294+
"path": path,
295+
"error": err,
296+
}).Error("path couldn't be inspected")
297+
298+
return filepath.SkipDir
299+
}
300+
301+
if ok {
302+
if !c.DisableGit {
303+
base := filepath.Base(path)
304+
if err := c.pool.AddGitWithID(base, path); err != nil {
305+
logrus.WithFields(logrus.Fields{
306+
"id": base,
307+
"path": path,
308+
"error": err,
309+
}).Error("repository could not be added")
310+
}
311+
312+
logrus.WithField("path", path).Debug("repository added")
313+
}
314+
315+
// either the repository is added or not, the path must be skipped
316+
return filepath.SkipDir
245317
}
246318

247319
return nil

common_test.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ func buildSession(t *testing.T, repos fixtures.Fixtures,
3838
pool := NewRepositoryPool()
3939
for _, fixture := range repos {
4040
path := fixture.Worktree().Root()
41-
_, err := pool.AddGit(path)
42-
if err == nil {
43-
_, err := pool.GetRepo(path)
44-
require.NoError(err)
45-
paths = append(paths, path)
41+
ok, err := IsGitRepo(path)
42+
require.NoError(err)
43+
if ok {
44+
if err := pool.AddGit(path); err == nil {
45+
_, err := pool.GetRepo(path)
46+
require.NoError(err)
47+
paths = append(paths, path)
48+
}
4649
}
4750
}
4851

docs/using-gitbase/configuration.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,27 @@ Usage:
5757
5858
Starts a gitbase server instance
5959
60-
By default when gitbase encounters and error in a repository it
60+
By default when gitbase encounters an error in a repository it
6161
stops the query. With GITBASE_SKIP_GIT_ERRORS variable it won't
6262
complain and just skip those rows or repositories.
6363
6464
Help Options:
65-
-h, --help Show this help message
65+
-h, --help Show this help message
6666
6767
[server command options]
68-
-v Activates the verbose mode
69-
-g, --git= Path where the git repositories are located, multiple directories can
70-
be defined. Accepts globs.
71-
--siva= Path where the siva repositories are located, multiple directories can
72-
be defined. Accepts globs.
73-
--host= Host where the server is going to listen (default: localhost)
74-
-p, --port= Port where the server is going to listen (default: 3306)
75-
-u, --user= User name used for connection (default: root)
76-
-P, --password= Password used for connection
77-
--pilosa= URL to your pilosa server (default: http://localhost:10101)
78-
[$PILOSA_ENDPOINT]
79-
-i, --index= Directory where the gitbase indexes information will be persisted.
80-
(default: /var/lib/gitbase/index) [$GITBASE_INDEX_DIR]
81-
--no-squash Disables the table squashing.
82-
--trace Enables jaeger tracing [$GITBASE_TRACE]
83-
```
68+
-v Activates the verbose mode
69+
-d, --directories= Path where the git repositories are located (standard and siva), multiple directories can be defined. Accepts globs.
70+
--depth= load repositories looking at less than <depth> nested subdirectories. (default: 1000)
71+
--no-git disable the load of git standard repositories.
72+
--no-siva disable the load of siva files.
73+
--host= Host where the server is going to listen (default: localhost)
74+
-p, --port= Port where the server is going to listen (default: 3306)
75+
-u, --user= User name used for connection (default: root)
76+
-P, --password= Password used for connection
77+
--pilosa= URL to your pilosa server (default: http://localhost:10101) [$PILOSA_ENDPOINT]
78+
-i, --index= Directory where the gitbase indexes information will be persisted. (default: /var/lib/gitbase/index) [$GITBASE_INDEX_DIR]
79+
--no-squash Disables the table squashing.
80+
--trace Enables jaeger tracing [$GITBASE_TRACE]
81+
-r, --readonly Only allow read queries. This disables creating and deleting indexes as well. [$GITBASE_READONLY]
82+
83+
```

docs/using-gitbase/getting-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ For more info about command line arguments, [go here](/docs/using-gitbase/config
1616
You can start a server by providing a path which contains multiple git repositories `/path/to/repositories` with this command:
1717

1818
```
19-
$ gitbase server -v -g /path/to/repositories
19+
$ gitbase server -v -d /path/to/repositories
2020
```
2121

2222
## Installing from source
@@ -83,4 +83,4 @@ As of MySQL 8.0 [the default authentication method is `caching_sha2_password`](h
8383

8484
```
8585
mysql -q -u root -h 127.0.0.1 --default-auth=mysql_native_password
86-
```
86+
```

integration_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ func TestIntegration(t *testing.T) {
3333
path := fixtures.ByTag("worktree").One().Worktree().Root()
3434

3535
pool := gitbase.NewRepositoryPool()
36-
_, err := pool.AddGitWithID("worktree", path)
37-
require.NoError(t, err)
36+
require.NoError(t, pool.AddGitWithID("worktree", path))
3837

3938
testCases := []struct {
4039
query string
@@ -357,8 +356,8 @@ func TestSquashCorrectness(t *testing.T) {
357356
`SELECT repository_id, num_files FROM (
358357
SELECT COUNT(f.*) num_files, f.repository_id
359358
FROM ref_commits r
360-
INNER JOIN commit_files cf
361-
ON r.commit_hash = cf.commit_hash
359+
INNER JOIN commit_files cf
360+
ON r.commit_hash = cf.commit_hash
362361
AND r.repository_id = cf.repository_id
363362
INNER JOIN files f
364363
ON cf.repository_id = f.repository_id
@@ -414,7 +413,19 @@ func TestMissingHeadRefs(t *testing.T) {
414413
)
415414

416415
pool := gitbase.NewRepositoryPool()
417-
require.NoError(pool.AddSivaDir(path))
416+
require.NoError(
417+
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
418+
if err != nil {
419+
return err
420+
}
421+
422+
if gitbase.IsSivaFile(path) {
423+
require.NoError(pool.AddSivaFile(path))
424+
}
425+
426+
return nil
427+
}),
428+
)
418429

419430
engine := newBaseEngine()
420431

path_utils.go

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
package gitbase
22

33
import (
4-
"os"
54
"path/filepath"
65
"regexp"
76
"strings"
7+
8+
git "gopkg.in/src-d/go-git.v4"
89
)
910

1011
// RegMatchChars matches a string with a glob expression inside.
1112
var RegMatchChars = regexp.MustCompile(`(^|[^\\])([*[?])`)
1213

13-
// PatternMatches returns the depth of the fixed part of a patters, the paths
14-
// matched and any error found.
15-
func PatternMatches(pattern string) (int, []string, error) {
14+
// PatternMatches returns the paths matched and any error found.
15+
func PatternMatches(pattern string) ([]string, error) {
1616
abs, err := filepath.Abs(pattern)
1717
if err != nil {
18-
return 0, nil, err
18+
return nil, err
1919
}
2020

2121
matches, err := filepath.Glob(abs)
2222
if err != nil {
23-
return 0, nil, err
23+
return nil, err
2424
}
2525

26-
depth := PatternPrefixDepth(abs)
27-
28-
return depth, removeDsStore(matches), nil
26+
return removeDsStore(matches), nil
2927
}
3028

3129
func removeDsStore(matches []string) []string {
@@ -38,46 +36,20 @@ func removeDsStore(matches []string) []string {
3836
return result
3937
}
4038

41-
// PatternPrefixDepth returns the number of directories before the first
42-
// glob expression is found.
43-
func PatternPrefixDepth(pattern string) int {
44-
if pattern == "" {
45-
return 0
46-
}
47-
48-
parts := SplitPath(pattern)
49-
50-
for i, part := range parts {
51-
if RegMatchChars.MatchString(part) {
52-
return i
39+
// IsGitRepo checks that the given path is a git repository.
40+
func IsGitRepo(path string) (bool, error) {
41+
if _, err := git.PlainOpen(path); err != nil {
42+
if git.ErrRepositoryNotExists == err {
43+
return false, nil
5344
}
54-
}
5545

56-
return len(parts)
57-
}
58-
59-
// IDFromPath returns a repository ID from a path stripping a number of
60-
// directories from it.
61-
func IDFromPath(prefix int, path string) string {
62-
parts := SplitPath(path)
63-
64-
if prefix >= len(parts) {
65-
return path
46+
return false, err
6647
}
6748

68-
return filepath.Join(parts[prefix:]...)
49+
return true, nil
6950
}
7051

71-
// SplitPath slices a path in its components.
72-
func SplitPath(path string) []string {
73-
parts := strings.Split(path, string(os.PathSeparator))
74-
saneParts := make([]string, 0, len(parts))
75-
76-
for _, p := range parts {
77-
if p != "" {
78-
saneParts = append(saneParts, p)
79-
}
80-
}
81-
82-
return saneParts
52+
//IsSivaFile checks that the given file is a siva file.
53+
func IsSivaFile(file string) bool {
54+
return strings.HasSuffix(file, ".siva")
8355
}

0 commit comments

Comments
 (0)