refactor(git): split / improve clone function
This commit is contained in:
parent
55c59e0164
commit
4aad919153
3 changed files with 189 additions and 88 deletions
|
@ -1,9 +1,13 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
"github.com/go-git/go-billy/v5/memfs"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||
"github.com/go-git/go-git/v5/storage/memory"
|
||||
|
@ -26,28 +30,21 @@ func WithBranch(branch string) ProjectOption {
|
|||
}
|
||||
}
|
||||
|
||||
func WithKey(path string) ProjectOption {
|
||||
return func(p *Project) {
|
||||
p.KeyFile = path
|
||||
}
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
Branch string
|
||||
Force bool
|
||||
RepoURL string
|
||||
KeyFile string
|
||||
|
||||
auth transport.AuthMethod
|
||||
fs billy.Filesystem
|
||||
storer *memory.Storage
|
||||
repository *git.Repository
|
||||
worktree *git.Worktree
|
||||
}
|
||||
|
||||
func NewProject(url string, options ...ProjectOption) *Project {
|
||||
project := &Project{
|
||||
Branch: "",
|
||||
RepoURL: url,
|
||||
KeyFile: "",
|
||||
fs: memfs.New(),
|
||||
storer: memory.NewStorage(),
|
||||
repository: nil,
|
||||
|
@ -60,20 +57,120 @@ func NewProject(url string, options ...ProjectOption) *Project {
|
|||
return project
|
||||
}
|
||||
|
||||
func (p *Project) Clone() error {
|
||||
func (p *Project) Checkout() error {
|
||||
branchRef := plumbing.NewBranchReferenceName(p.Branch)
|
||||
|
||||
_, err := p.repository.Reference(branchRef, true)
|
||||
if errors.Is(err, plumbing.ErrReferenceNotFound) {
|
||||
var headRef *plumbing.Reference
|
||||
headRef, err = p.repository.Head()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ref := plumbing.NewHashReference(branchRef, headRef.Hash())
|
||||
if err = p.repository.Storer.SetReference(ref); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.worktree, err = p.repository.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
checkoutOpts := git.CheckoutOptions{
|
||||
Branch: branchRef,
|
||||
Create: false,
|
||||
}
|
||||
|
||||
if err = checkoutOpts.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.worktree.Checkout(&checkoutOpts)
|
||||
}
|
||||
|
||||
func (p *Project) Clone(ctx context.Context) error {
|
||||
cloneOpts := git.CloneOptions{
|
||||
URL: p.RepoURL,
|
||||
URL: p.RepoURL,
|
||||
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
|
||||
}
|
||||
|
||||
if p.auth != nil {
|
||||
cloneOpts.Auth = p.auth
|
||||
}
|
||||
|
||||
if err := cloneOpts.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
p.repository, err = git.Clone(
|
||||
p.repository, err = git.CloneContext(
|
||||
ctx,
|
||||
p.storer,
|
||||
p.fs,
|
||||
&cloneOpts,
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Project) HasChanges() bool {
|
||||
remoteBranchRef := plumbing.NewRemoteReferenceName("origin", p.Branch)
|
||||
remoteBranch, err := p.repository.Reference(remoteBranchRef, true)
|
||||
if errors.Is(err, plumbing.ErrReferenceNotFound) {
|
||||
return true
|
||||
} else if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
localBranchRef, err := p.repository.Reference(plumbing.NewBranchReferenceName(p.Branch), true)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if localBranchRef.Hash() != remoteBranch.Hash() {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Project) Pull(ctx context.Context) error {
|
||||
pullOpts := git.PullOptions{
|
||||
ReferenceName: plumbing.NewBranchReferenceName(p.Branch),
|
||||
}
|
||||
|
||||
if err := pullOpts.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := p.worktree.PullContext(ctx, &pullOpts)
|
||||
if !errors.Is(err, plumbing.ErrReferenceNotFound) && err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Project) Push(ctx context.Context) error {
|
||||
pushOpts := git.PushOptions{
|
||||
RemoteName: "origin",
|
||||
}
|
||||
|
||||
if p.auth != nil {
|
||||
pushOpts.Auth = p.auth
|
||||
}
|
||||
|
||||
if err := pushOpts.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.repository.PushContext(ctx, &pushOpts)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue