Initial commit
This commit is contained in:
12
internal/project/fetcher.go
Normal file
12
internal/project/fetcher.go
Normal file
@ -0,0 +1,12 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"gopkg.in/src-d/go-billy.v4"
|
||||
)
|
||||
|
||||
type Fetcher interface {
|
||||
Match(*url.URL) bool
|
||||
Fetch(*url.URL) (billy.Filesystem, error)
|
||||
}
|
98
internal/project/git.go
Normal file
98
internal/project/git.go
Normal file
@ -0,0 +1,98 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/url"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/src-d/go-billy.v4"
|
||||
"gopkg.in/src-d/go-billy.v4/memfs"
|
||||
git "gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
||||
"gopkg.in/src-d/go-git.v4/storage/memory"
|
||||
)
|
||||
|
||||
const GitScheme = "git"
|
||||
|
||||
type GitFetcher struct{}
|
||||
|
||||
func (f *GitFetcher) Fetch(url *url.URL) (billy.Filesystem, error) {
|
||||
fs := memfs.New()
|
||||
|
||||
var auth transport.AuthMethod
|
||||
|
||||
if user := url.User; user != nil {
|
||||
user := url.User
|
||||
basicAuth := &http.BasicAuth{
|
||||
Username: user.Username(),
|
||||
}
|
||||
|
||||
password, exists := user.Password()
|
||||
if exists {
|
||||
basicAuth.Password = password
|
||||
}
|
||||
|
||||
auth = basicAuth
|
||||
}
|
||||
|
||||
if url.Scheme == "" {
|
||||
url.Scheme = "https"
|
||||
}
|
||||
|
||||
branchName := plumbing.NewBranchReferenceName("master")
|
||||
if url.Fragment != "" {
|
||||
branchName = plumbing.NewBranchReferenceName(url.Fragment)
|
||||
url.Fragment = ""
|
||||
}
|
||||
|
||||
log.Printf("Cloning repository '%s'...", url.String())
|
||||
|
||||
repo, err := git.Clone(memory.NewStorage(), fs, &git.CloneOptions{
|
||||
URL: url.String(),
|
||||
Auth: auth,
|
||||
ReferenceName: branchName,
|
||||
})
|
||||
if err != nil {
|
||||
if err == transport.ErrRepositoryNotFound {
|
||||
return nil, errors.Wrapf(err, "could not find repository")
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(err, "could not clone repository")
|
||||
}
|
||||
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve worktree")
|
||||
}
|
||||
|
||||
log.Printf("Checking out branch '%s'...", branchName)
|
||||
|
||||
err = worktree.Checkout(&git.CheckoutOptions{
|
||||
Force: true,
|
||||
Branch: branchName,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not checkout branch '%s'", branchName)
|
||||
}
|
||||
|
||||
return fs, nil
|
||||
}
|
||||
|
||||
func (f *GitFetcher) Match(url *url.URL) bool {
|
||||
if url.Scheme == GitScheme {
|
||||
return true
|
||||
}
|
||||
|
||||
isFilesystemPath := isFilesystemPath(url.Path)
|
||||
if url.Scheme == "" && !isFilesystemPath {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func NewGitFetcher() *GitFetcher {
|
||||
return &GitFetcher{}
|
||||
}
|
51
internal/project/git_test.go
Normal file
51
internal/project/git_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGitFetcher(t *testing.T) {
|
||||
git := NewGitFetcher()
|
||||
|
||||
projectURL, err := url.Parse("forge.cadoles.com/wpetit/goweb")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fs, err := git.Fetch(projectURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if fs == nil {
|
||||
t.Fatal("fs should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitMatch(t *testing.T) {
|
||||
testCases := []struct {
|
||||
RawURL string
|
||||
ShouldMatch bool
|
||||
}{
|
||||
{"git://wpetit/scaffold", true},
|
||||
{"forge.cadoles.com/wpetit/scaffold", true},
|
||||
}
|
||||
|
||||
git := NewGitFetcher()
|
||||
|
||||
for _, tc := range testCases {
|
||||
func(rawURL string, shouldMatch bool) {
|
||||
t.Run(rawURL, func(t *testing.T) {
|
||||
projectURL, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if e, g := shouldMatch, git.Match(projectURL); g != e {
|
||||
t.Errorf("git.Match(url): expected '%v', got '%v'", e, g)
|
||||
}
|
||||
})
|
||||
}(tc.RawURL, tc.ShouldMatch)
|
||||
}
|
||||
}
|
33
internal/project/local.go
Normal file
33
internal/project/local.go
Normal file
@ -0,0 +1,33 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/src-d/go-billy.v4"
|
||||
)
|
||||
|
||||
const LocalScheme = "local"
|
||||
const FileScheme = "file"
|
||||
|
||||
type LocalFetcher struct{}
|
||||
|
||||
func (f *LocalFetcher) Fetch(url *url.URL) (billy.Filesystem, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *LocalFetcher) Match(url *url.URL) bool {
|
||||
if url.Scheme == LocalScheme || url.Scheme == FileScheme {
|
||||
return true
|
||||
}
|
||||
|
||||
return isFilesystemPath(url.Path)
|
||||
}
|
||||
|
||||
func NewLocalFetcher() *LocalFetcher {
|
||||
return &LocalFetcher{}
|
||||
}
|
||||
|
||||
func isFilesystemPath(path string) bool {
|
||||
return strings.HasPrefix(path, "./") || strings.HasPrefix(path, "/")
|
||||
}
|
33
internal/project/local_test.go
Normal file
33
internal/project/local_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalMatch(t *testing.T) {
|
||||
testCases := []struct {
|
||||
RawURL string
|
||||
ShouldMatch bool
|
||||
}{
|
||||
{"local://wpetit/scaffold", true},
|
||||
{"./forge.cadoles.com/wpetit/scaffold", true},
|
||||
}
|
||||
|
||||
local := NewLocalFetcher()
|
||||
|
||||
for _, tc := range testCases {
|
||||
func(rawURL string, shouldMatch bool) {
|
||||
t.Run(rawURL, func(t *testing.T) {
|
||||
projectURL, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if e, g := shouldMatch, local.Match(projectURL); g != e {
|
||||
t.Errorf("local.Match(url): expected '%v', got '%v'", e, g)
|
||||
}
|
||||
})
|
||||
}(tc.RawURL, tc.ShouldMatch)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user