Initial commit
This commit is contained in:
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{}
|
||||
}
|
Reference in New Issue
Block a user