@@ -3,22 +3,24 @@ package command
3
3
import (
4
4
"fmt"
5
5
"net"
6
+ "net/url"
6
7
"os"
7
8
"path/filepath"
9
+ "regexp"
8
10
"runtime"
9
11
"strconv"
10
12
"time"
11
13
12
14
"github.com/src-d/gitbase"
13
15
"github.com/src-d/gitbase/internal/function"
14
16
"github.com/src-d/gitbase/internal/rule"
15
- "github.com/src-d/go-borges/libraries"
16
- "github.com/src-d/go-borges/plain"
17
- "github.com/src-d/go-borges/siva"
18
17
19
18
"github.com/opentracing/opentracing-go"
20
19
"github.com/sirupsen/logrus"
21
20
"github.com/src-d/go-borges"
21
+ "github.com/src-d/go-borges/libraries"
22
+ "github.com/src-d/go-borges/plain"
23
+ "github.com/src-d/go-borges/siva"
22
24
sqle "github.com/src-d/go-mysql-server"
23
25
"github.com/src-d/go-mysql-server/auth"
24
26
"github.com/src-d/go-mysql-server/server"
@@ -53,8 +55,10 @@ type Server struct {
53
55
Name string `long:"db" default:"gitbase" description:"Database name"`
54
56
Version string // Version of the application.
55
57
Directories []string `short:"d" long:"directories" description:"Path where standard git repositories are located, multiple directories can be defined."`
56
- Siva [] string `short:"s" long:"siva" description:"Path where siva git repositories are located, multiple directories can be defined. "`
58
+ Format string `long:"format" default:"git" choice:"git" choice:" siva" description:"Library format "`
57
59
Bucket int `long:"bucket" default:"2" description:"Bucketing level to use with siva libraries"`
60
+ Bare bool `long:"bare" description:"Sets the library to use bare git repositories, used only with git format libraries"`
61
+ NonRooted bool `long:"non-rooted" description:"Disables treating siva files as rooted repositories"`
58
62
Host string `long:"host" default:"localhost" description:"Host where the server is going to listen"`
59
63
Port int `short:"p" long:"port" default:"3306" description:"Port where the server is going to listen"`
60
64
User string `short:"u" long:"user" default:"root" description:"User name used for connection"`
@@ -261,21 +265,45 @@ func (c *Server) registerDrivers() error {
261
265
}
262
266
263
267
func (c * Server ) addDirectories () error {
264
- if len (c .Directories ) == 0 && len ( c . Siva ) == 0 {
265
- logrus .Error ("At least one folder should be provided." )
268
+ if len (c .Directories ) == 0 {
269
+ logrus .Error ("at least one folder should be provided." )
266
270
}
267
271
268
- sivaOpts := siva.LibraryOptions {
269
- Transactional : true ,
270
- RootedRepo : true ,
271
- Cache : c .sharedCache ,
272
- Bucket : c .Bucket ,
273
- Performance : true ,
274
- RegistryCache : 100000 ,
272
+ for _ , d := range c .Directories {
273
+ dir := directory {
274
+ Path : d ,
275
+ Format : c .Format ,
276
+ Bare : c .Bare ,
277
+ Bucket : c .Bucket ,
278
+ Rooted : ! c .NonRooted ,
279
+ }
280
+
281
+ dir , err := parseDirectory (dir )
282
+ if err != nil {
283
+ return err
284
+ }
285
+
286
+ err = c .addDirectory (dir )
287
+ if err != nil {
288
+ return err
289
+ }
275
290
}
276
291
277
- for _ , d := range c .Siva {
278
- lib , err := siva .NewLibrary (d , osfs .New (d ), sivaOpts )
292
+ return nil
293
+ }
294
+
295
+ func (c * Server ) addDirectory (d directory ) error {
296
+ if d .Format == "siva" {
297
+ sivaOpts := siva.LibraryOptions {
298
+ Transactional : true ,
299
+ RootedRepo : d .Rooted ,
300
+ Cache : c .sharedCache ,
301
+ Bucket : d .Bucket ,
302
+ Performance : true ,
303
+ RegistryCache : 100000 ,
304
+ }
305
+
306
+ lib , err := siva .NewLibrary (d .Path , osfs .New (d .Path ), sivaOpts )
279
307
if err != nil {
280
308
return err
281
309
}
@@ -284,26 +312,116 @@ func (c *Server) addDirectories() error {
284
312
if err != nil {
285
313
return err
286
314
}
287
- }
288
315
289
- if len (c .Directories ) == 0 {
290
316
return nil
291
317
}
292
318
293
319
plainOpts := & plain.LocationOptions {
294
320
Cache : c .sharedCache ,
295
321
Performance : true ,
322
+ Bare : d .Bare ,
296
323
}
297
324
298
- p := plain . NewLibrary ( borges . LibraryID ( "plain" ))
299
- for _ , d := range c . Directories {
300
- loc , err := plain . NewLocation ( borges . LocationID ( d ), osfs . New ( d ), plainOpts )
325
+ if c . plainLibrary == nil {
326
+ c . plainLibrary = plain . NewLibrary ( borges . LibraryID ( "plain" ))
327
+ err := c . rootLibrary . Add ( c . plainLibrary )
301
328
if err != nil {
302
329
return err
303
330
}
331
+ }
332
+
333
+ loc , err := plain .NewLocation (
334
+ borges .LocationID (d .Path ),
335
+ osfs .New (d .Path ),
336
+ plainOpts )
337
+ if err != nil {
338
+ return err
339
+ }
340
+
341
+ c .plainLibrary .AddLocation (loc )
342
+
343
+ return nil
344
+ }
345
+
346
+ type directory struct {
347
+ Path string
348
+ Format string
349
+ Bucket int
350
+ Rooted bool
351
+ Bare bool
352
+ }
353
+
354
+ var (
355
+ uriReg = regexp .MustCompile (`^\w+:.*` )
356
+ ErrInvalid = fmt .Errorf ("invalid option" )
357
+ )
304
358
305
- p .AddLocation (loc )
359
+ func parseDirectory (dir directory ) (directory , error ) {
360
+ d := dir .Path
361
+
362
+ if ! uriReg .Match ([]byte (d )) {
363
+ return dir , nil
364
+ }
365
+
366
+ u , err := url .ParseRequestURI (d )
367
+ if err != nil {
368
+ logrus .Errorf ("invalid directory format %v" , d )
369
+ return dir , err
370
+ }
371
+
372
+ if u .Scheme != "file" {
373
+ logrus .Errorf ("only file scheme is supported: %v" , d )
374
+ return dir , fmt .Errorf ("scheme not suported in directory %v" , d )
375
+ }
376
+
377
+ dir .Path = filepath .Join (u .Hostname (), u .Path )
378
+ query := u .Query ()
379
+
380
+ for k , v := range query {
381
+ if len (v ) != 1 {
382
+ logrus .Errorf ("invalid number of options for %v" , v )
383
+ return dir , ErrInvalid
384
+ }
385
+
386
+ val := v [0 ]
387
+ switch k {
388
+ case "format" :
389
+ if val != "siva" && val != "git" {
390
+ logrus .Errorf ("invalid format in directory, it can only " +
391
+ "be siva or git %v" , val )
392
+ return dir , ErrInvalid
393
+ }
394
+ dir .Format = val
395
+
396
+ case "bare" :
397
+ if val != "true" && val != "false" {
398
+ logrus .Errorf ("invalid format in bare, it can only " +
399
+ "be true or false %v" , val )
400
+ return dir , ErrInvalid
401
+ }
402
+ dir .Bare = (val == "true" )
403
+
404
+ case "rooted" :
405
+ if val != "true" && val != "false" {
406
+ logrus .Errorf ("invalid format in rooted, it can only " +
407
+ "be true or false %v" , val )
408
+ return dir , ErrInvalid
409
+ }
410
+ dir .Rooted = (val == "true" )
411
+
412
+ case "bucket" :
413
+ num , err := strconv .Atoi (val )
414
+ if err != nil {
415
+ logrus .Errorf ("invalid number in bucket: %v" , val )
416
+ return dir , ErrInvalid
417
+ }
418
+ dir .Bucket = num
419
+
420
+ default :
421
+ logrus .Errorf ("invalid option: %v" , k )
422
+ return dir , ErrInvalid
423
+ }
306
424
}
307
425
308
- return c . rootLibrary . Add ( p )
426
+ return dir , nil
309
427
}
0 commit comments