Skip to content

Commit

Permalink
cli: detect bareness of git libraries (#897)
Browse files Browse the repository at this point in the history
cli: detect bareness of git libraries
  • Loading branch information
ajnavarro committed Jun 21, 2019
2 parents 35d6bc7 + 007c0fe commit 42ec285
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- git libraries bare or non bare format is automatically detected ([#897](https://github.com/src-d/gitbase/pull/897))

## [0.22.0-beta1] - 2019-06-20

### Added
Expand Down
65 changes: 59 additions & 6 deletions cmd/gitbase/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Server struct {
Format string `long:"format" default:"git" choice:"git" choice:"siva" description:"Library format"`
Bucket int `long:"bucket" default:"2" description:"Bucketing level to use with siva libraries"`
Bare bool `long:"bare" description:"Sets the library to use bare git repositories, used only with git format libraries"`
NonBare bool `long:"non-bare" description:"Sets the library to use non bare git repositories, used only with git format libraries"`
NonRooted bool `long:"non-rooted" description:"Disables treating siva files as rooted repositories"`
Host string `long:"host" default:"localhost" description:"Host where the server is going to listen"`
Port int `short:"p" long:"port" default:"3306" description:"Port where the server is going to listen"`
Expand Down Expand Up @@ -122,6 +123,10 @@ func (c *Server) Execute(args []string) error {
logrus.SetLevel(logrus.DebugLevel)
}

if c.Bare && c.NonBare {
return fmt.Errorf("cannot use both --bare and --non-bare")
}

// info is the default log level
if c.LogLevel != "info" {
level, err := logrus.ParseLevel(c.LogLevel)
Expand Down Expand Up @@ -270,11 +275,19 @@ func (c *Server) addDirectories() error {
logrus.Error("at least one folder should be provided.")
}

defaultBare := bareAuto
switch {
case c.Bare:
defaultBare = bareOn
case c.NonBare:
defaultBare = bareOff
}

for _, d := range c.Directories {
dir := directory{
Path: d,
Format: c.Format,
Bare: c.Bare,
Bare: defaultBare,
Bucket: c.Bucket,
Rooted: !c.NonRooted,
}
Expand Down Expand Up @@ -327,10 +340,15 @@ func (c *Server) addDirectory(d directory) error {
return nil
}

bare, err := discoverBare(d)
if err != nil {
return err
}

plainOpts := &plain.LocationOptions{
Cache: c.sharedCache,
Performance: true,
Bare: d.Bare,
Bare: bare,
}

if c.plainLibrary == nil {
Expand All @@ -354,12 +372,20 @@ func (c *Server) addDirectory(d directory) error {
return nil
}

type bareOpt int

const (
bareAuto bareOpt = iota
bareOn
bareOff
)

type directory struct {
Path string
Format string
Bucket int
Rooted bool
Bare bool
Bare bareOpt
}

var (
Expand Down Expand Up @@ -405,12 +431,18 @@ func parseDirectory(dir directory) (directory, error) {
dir.Format = val

case "bare":
if val != "true" && val != "false" {
switch val {
case "true":
dir.Bare = bareOn
case "false":
dir.Bare = bareOff
case "auto":
dir.Bare = bareAuto
default:
logrus.Errorf("invalid value in bare, it can only "+
"be true or false %v", val)
"be true, false, or auto %v", val)
return dir, ErrInvalid
}
dir.Bare = (val == "true")

case "rooted":
if val != "true" && val != "false" {
Expand All @@ -436,3 +468,24 @@ func parseDirectory(dir directory) (directory, error) {

return dir, nil
}

func discoverBare(d directory) (bool, error) {
fs := osfs.New(d.Path)

var bare bool
if d.Bare == bareAuto {
b, err := plain.IsFirstRepositoryBare(fs, "/")
if plain.ErrRepositoriesNotFound.Is(err) {
logrus.WithField("path", d.Path).
Errorf("could not find repositories, assuming non bare format")
} else if err != nil {
return false, err
}

bare = b
} else {
bare = d.Bare == bareOn
}

return bare, nil
}
132 changes: 129 additions & 3 deletions cmd/gitbase/command/server_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package command

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"

fixtures "github.com/src-d/go-git-fixtures"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -70,14 +75,14 @@ func TestDirectories(t *testing.T) {
path: "file:///siva/path?bare=true",
expected: directory{
Path: "/siva/path",
Bare: true,
Bare: bareOn,
},
},
{
path: "file:///siva/path?bare=false",
expected: directory{
Path: "/siva/path",
Bare: false,
Bare: bareOff,
},
},
{
Expand Down Expand Up @@ -118,7 +123,7 @@ func TestDirectories(t *testing.T) {
expected: directory{
Path: "/siva/path",
Format: "git",
Bare: false,
Bare: bareOff,
},
},
{
Expand Down Expand Up @@ -147,3 +152,124 @@ func TestDirectories(t *testing.T) {
})
}
}

func TestDiscoverBare(t *testing.T) {
defer func() {
require.NoError(t, fixtures.Clean())
}()

tmpDir, err := ioutil.TempDir("", "gitbase")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)

emptyDir := filepath.Join(tmpDir, "empty")
err = os.Mkdir(emptyDir, 0777)
require.NoError(t, err)

bareDir := filepath.Join(tmpDir, "bare")
err = os.Mkdir(bareDir, 0777)
require.NoError(t, err)
dir := fixtures.ByTag("worktree").One().DotGit().Root()
err = os.Rename(dir, filepath.Join(bareDir, "repo"))
require.NoError(t, err)

nonBareDir := filepath.Join(tmpDir, "non_bare")
err = os.Mkdir(nonBareDir, 0777)
require.NoError(t, err)
dir = fixtures.ByTag("worktree").One().Worktree().Root()
err = os.Rename(dir, filepath.Join(nonBareDir, "repo"))
require.NoError(t, err)

tests := []struct {
path string
bare bareOpt
expected bool
err bool
}{
{
path: "/does/not/exist",
err: true,
},
{
path: emptyDir,
bare: bareAuto,
expected: false,
},
{
path: emptyDir,
bare: bareOn,
expected: true,
},
{
path: emptyDir,
bare: bareOff,
expected: false,
},
{
path: bareDir,
bare: bareAuto,
expected: true,
},
{
path: bareDir,
bare: bareOn,
expected: true,
},
{
path: bareDir,
bare: bareOff,
expected: false,
},
{
path: nonBareDir,
bare: bareAuto,
expected: false,
},
{
path: nonBareDir,
bare: bareOn,
expected: true,
},
{
path: nonBareDir,
bare: bareOff,
expected: false,
},
}

for _, test := range tests {
dir := directory{
Path: test.path,
Bare: test.bare,
}

t.Run(bareTestName(dir, test.err), func(t *testing.T) {
bare, err := discoverBare(dir)
if test.err {
require.Error(t, err)
return
}

require.NoError(t, err)
require.Equal(t, test.expected, bare)
})
}
}

func bareTestName(d directory, err bool) string {
bare := ""
switch d.Bare {
case bareOn:
bare = "bare"
case bareOff:
bare = "non-bare"
case bareAuto:
bare = "auto"
}

if err {
bare = "error"
}

return fmt.Sprintf("%s_%s", d.Path, bare)
}
2 changes: 2 additions & 0 deletions docs/using-gitbase/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ Help Options:
--bucket= Bucketing level to use with siva libraries (default: 2)
--bare Sets the library to use bare git repositories, used
only with git format libraries
--non-bare Sets the library to use non bare git repositories,
used only with git format libraries
--non-rooted Disables treating siva files as rooted repositories
--host= Host where the server is going to listen (default:
localhost)
Expand Down
5 changes: 3 additions & 2 deletions docs/using-gitbase/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,20 @@ mysql -q -u root -h 127.0.0.1 --default-auth=mysql_native_password

## Library format specification

By default the directories added to github should contain normal git repositories. If the format of the repositories is different you have two ways to specify it.
By default the directories added to gitbase should contain git repositories and it detects if they are standard or bare format. Each directory added can only contain one type of repository. If you want to specify the format you have two ways to do it:

If all the directories are in the same format you can set it globally with these parameters:

* `--format`: it can be either `git` for filesystem repositories or `siva` for siva archives
* `--bare`: specifies that git archives are bare, can only be used with `git` format
* `--non-bare`: specifies that git archives are standard, can only be used with `git` format
* `--bucket`: sets the number of characters to use for bucketing, used with `siva` libraries
* `--non-rooted`: disables rooted repositories management in `siva` libraries

If you are mixing formats you can specify each directory as a `file://` URL with these parameters:

* `format`: can be `git` or `siva`
* `bare`: `true` or `false`
* `bare`: `true`, `false` or `auto`
* `bucket`: the characters to use for directory bucketing
* `rooted`: `true` or `false`

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/opentracing/opentracing-go v1.1.0
github.com/sirupsen/logrus v1.3.0
github.com/src-d/enry/v2 v2.0.0
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b
github.com/src-d/go-git v4.7.0+incompatible
github.com/src-d/go-git-fixtures v3.5.1-0.20190605154830-57f3972b0248+incompatible
github.com/src-d/go-mysql-server v0.4.1-0.20190620142646-9722f31e0f85
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ github.com/src-d/enry/v2 v2.0.0 h1:2ADqfDHhroFwL1RGhMS9e15NkEwln8P4AABwVvIdAlo=
github.com/src-d/enry/v2 v2.0.0/go.mod h1:qQeCMRwzMF3ckeGr+h0tJLdxXnq+NVZsIDMELj0t028=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581 h1:ZOJFuELokTVFnwpgD0tj9PMTXiBwutmGoH2WCaG5dts=
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581/go.mod h1:Myl/zHrk3iT/I5T08RTBpuGzchucytSsi6p7KzM2lOA=
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b h1:c2CSWoLOo1o2ija5OWDETzMUi9kncByT5GL7EkSpzxk=
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b/go.mod h1:Myl/zHrk3iT/I5T08RTBpuGzchucytSsi6p7KzM2lOA=
github.com/src-d/go-git v4.7.0+incompatible h1:IYSSnbAHeKmsfbQFi9ozbid+KNh0bKjlorMfQehQbcE=
github.com/src-d/go-git v4.7.0+incompatible/go.mod h1:1bQciz+hn0jzPQNsYj0hDFZHLJBdV7gXE2mWhC7EkFk=
github.com/src-d/go-git-fixtures v3.5.1-0.20190605154830-57f3972b0248+incompatible h1:A5bKevhs9C//Nh8QV0J+1KphEaIa25cDe1DTs/yPxDI=
Expand Down

0 comments on commit 42ec285

Please sign in to comment.