Skip to content

Commit cb49b64

Browse files
committed
feat(golang-rewrite): move all Git code to git package
* Move plugins/git package to /git. * Update repoer interface in pluginindex package to match interface in git package * Use git package's Repo struct in pluginindex package
1 parent 202cdae commit cb49b64

File tree

5 files changed

+74
-129
lines changed

5 files changed

+74
-129
lines changed

plugins/git/git.go renamed to git/git.go

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Package git contains all the Git operations that can be applied to asdf
2-
// plugins
2+
// Git repositories like the plugin index repo and individual asdf plugins.
33
package git
44

55
import (
@@ -10,34 +10,36 @@ import (
1010
"github.com/go-git/go-git/v5/plumbing"
1111
)
1212

13-
const remoteName = "origin"
13+
// DefaultRemoteName for Git repositories in asdf
14+
const DefaultRemoteName = "origin"
1415

15-
// Plugin is a struct to contain the plugin Git details
16-
type Plugin struct {
17-
directory string
18-
}
19-
20-
// PluginOps is an interface for operations that can be applied to asdf plugins.
16+
// Repoer is an interface for operations that can be applied to asdf plugins.
2117
// Right now we only support Git, but in the future we might have other
2218
// mechanisms to install and upgrade plugins. asdf doesn't require a plugin
2319
// to be a Git repository when asdf uses it, but Git is the only way to install
2420
// and upgrade plugins. If other approaches are supported this will be
2521
// extracted into the `plugins` module.
26-
type PluginOps interface {
22+
type Repoer interface {
2723
Clone(pluginURL string) error
2824
Head() (string, error)
2925
RemoteURL() (string, error)
3026
Update(ref string) (string, error)
3127
}
3228

33-
// NewPlugin builds a new Plugin instance
34-
func NewPlugin(directory string) Plugin {
35-
return Plugin{directory: directory}
29+
// Repo is a struct to contain the Git repository details
30+
type Repo struct {
31+
Directory string
32+
URL string
33+
}
34+
35+
// NewRepo builds a new Repo instance
36+
func NewRepo(directory string) Repo {
37+
return Repo{Directory: directory}
3638
}
3739

3840
// Clone installs a plugin via Git
39-
func (g Plugin) Clone(pluginURL string) error {
40-
_, err := git.PlainClone(g.directory, false, &git.CloneOptions{
41+
func (r Repo) Clone(pluginURL string) error {
42+
_, err := git.PlainClone(r.Directory, false, &git.CloneOptions{
4143
URL: pluginURL,
4244
})
4345
if err != nil {
@@ -48,8 +50,8 @@ func (g Plugin) Clone(pluginURL string) error {
4850
}
4951

5052
// Head returns the current HEAD ref of the plugin's Git repository
51-
func (g Plugin) Head() (string, error) {
52-
repo, err := gitOpen(g.directory)
53+
func (r Repo) Head() (string, error) {
54+
repo, err := gitOpen(r.Directory)
5355
if err != nil {
5456
return "", err
5557
}
@@ -63,8 +65,8 @@ func (g Plugin) Head() (string, error) {
6365
}
6466

6567
// RemoteURL returns the URL of the default remote for the plugin's Git repository
66-
func (g Plugin) RemoteURL() (string, error) {
67-
repo, err := gitOpen(g.directory)
68+
func (r Repo) RemoteURL() (string, error) {
69+
repo, err := gitOpen(r.Directory)
6870
if err != nil {
6971
return "", err
7072
}
@@ -79,8 +81,8 @@ func (g Plugin) RemoteURL() (string, error) {
7981

8082
// Update updates the plugin's Git repository to the ref if provided, or the
8183
// latest commit on the current branch
82-
func (g Plugin) Update(ref string) (string, error) {
83-
repo, err := gitOpen(g.directory)
84+
func (r Repo) Update(ref string) (string, error) {
85+
repo, err := gitOpen(r.Directory)
8486
if err != nil {
8587
return "", err
8688
}
@@ -107,7 +109,7 @@ func (g Plugin) Update(ref string) (string, error) {
107109
checkoutOptions = git.CheckoutOptions{Hash: plumbing.NewHash(ref), Force: true}
108110
}
109111

110-
fetchOptions := git.FetchOptions{RemoteName: remoteName, Force: true, RefSpecs: []config.RefSpec{
112+
fetchOptions := git.FetchOptions{RemoteName: DefaultRemoteName, Force: true, RefSpecs: []config.RefSpec{
111113
config.RefSpec(ref + ":" + ref),
112114
}}
113115

plugins/git/git_test.go renamed to git/git_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestPluginClone(t *testing.T) {
2121
tempDir := t.TempDir()
2222
directory := filepath.Join(tempDir, testPluginName)
2323

24-
plugin := NewPlugin(directory)
24+
plugin := NewRepo(directory)
2525
err := plugin.Clone("foobar")
2626

2727
assert.ErrorContains(t, err, "unable to clone plugin: repository not found")
@@ -31,7 +31,7 @@ func TestPluginClone(t *testing.T) {
3131
tempDir := t.TempDir()
3232
directory := filepath.Join(tempDir, testPluginName)
3333

34-
plugin := NewPlugin(directory)
34+
plugin := NewRepo(directory)
3535
err := plugin.Clone(testRepo)
3636

3737
assert.Nil(t, err)
@@ -50,7 +50,7 @@ func TestPluginHead(t *testing.T) {
5050
tempDir := t.TempDir()
5151
directory := filepath.Join(tempDir, testPluginName)
5252

53-
plugin := NewPlugin(directory)
53+
plugin := NewRepo(directory)
5454

5555
err := plugin.Clone(testRepo)
5656
assert.Nil(t, err)
@@ -64,7 +64,7 @@ func TestPluginRemoteURL(t *testing.T) {
6464
tempDir := t.TempDir()
6565
directory := filepath.Join(tempDir, testPluginName)
6666

67-
plugin := NewPlugin(directory)
67+
plugin := NewRepo(directory)
6868

6969
err := plugin.Clone(testRepo)
7070
assert.Nil(t, err)
@@ -78,14 +78,14 @@ func TestPluginUpdate(t *testing.T) {
7878
tempDir := t.TempDir()
7979
directory := filepath.Join(tempDir, testPluginName)
8080

81-
plugin := NewPlugin(directory)
81+
plugin := NewRepo(directory)
8282

8383
err := plugin.Clone(testRepo)
8484
assert.Nil(t, err)
8585

8686
t.Run("returns error when plugin with name does not exist", func(t *testing.T) {
8787
nonexistantPath := filepath.Join(tempDir, "nonexistant")
88-
nonexistantPlugin := NewPlugin(nonexistantPath)
88+
nonexistantPlugin := NewRepo(nonexistantPath)
8989
updatedToRef, err := nonexistantPlugin.Update("")
9090

9191
assert.NotNil(t, err)
@@ -100,7 +100,7 @@ func TestPluginUpdate(t *testing.T) {
100100
err := os.MkdirAll(badPluginDir, 0o777)
101101
assert.Nil(t, err)
102102

103-
badPlugin := NewPlugin(badPluginDir)
103+
badPlugin := NewRepo(badPluginDir)
104104

105105
updatedToRef, err := badPlugin.Update("")
106106

pluginindex/pluginindex.go

Lines changed: 10 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
package pluginindex
44

55
import (
6-
"errors"
76
"fmt"
87
"os"
98
"path/filepath"
109
"time"
1110

12-
"github.com/go-git/go-git/v5"
13-
"github.com/go-git/go-git/v5/config"
14-
"github.com/go-git/go-git/v5/plumbing"
11+
"asdf/git"
12+
1513
"gopkg.in/ini.v1"
1614
)
1715

@@ -20,90 +18,22 @@ const (
2018
repoUpdatedFilename = "repo-updated"
2119
)
2220

23-
type repoer interface {
24-
Install() error
25-
Update() error
26-
}
27-
28-
type gitRepoIndex struct {
29-
directory string
30-
URL string
31-
}
32-
33-
func (g *gitRepoIndex) Install() error {
34-
opts := git.CloneOptions{
35-
URL: g.URL,
36-
}
37-
38-
if _, err := git.PlainClone(g.directory, false, &opts); err != nil {
39-
return fmt.Errorf("unable to clone: %w", err)
40-
}
41-
42-
return nil
43-
}
44-
45-
func (g *gitRepoIndex) Update() error {
46-
repo, err := git.PlainOpen(g.directory)
47-
if err != nil {
48-
return fmt.Errorf("unable to open plugin Git repository: %w", err)
49-
}
50-
51-
var checkoutOptions git.CheckoutOptions
52-
53-
// If no ref is provided checkout latest commit on current branch
54-
head, err := repo.Head()
55-
if err != nil {
56-
return fmt.Errorf("unable to get repo HEAD: %w", err)
57-
}
58-
59-
if !head.Name().IsBranch() {
60-
return fmt.Errorf("not on a branch, unable to update")
61-
}
62-
63-
// If on a branch checkout the latest version of it from the remote
64-
branch := head.Name()
65-
ref := branch.String()
66-
checkoutOptions = git.CheckoutOptions{Branch: branch, Force: true}
67-
68-
fetchOptions := git.FetchOptions{RemoteName: "origin", Force: true, RefSpecs: []config.RefSpec{
69-
config.RefSpec(ref + ":" + ref),
70-
}}
71-
72-
if err = repo.Fetch(&fetchOptions); err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
73-
return fmt.Errorf("unable to fetch from remote: %w", err)
74-
}
75-
76-
worktree, err := repo.Worktree()
77-
if err != nil {
78-
return fmt.Errorf("unable to open worktree: %w", err)
79-
}
80-
81-
err = worktree.Checkout(&checkoutOptions)
82-
if err != nil {
83-
return fmt.Errorf("unable to checkout commit: %w", err)
84-
}
85-
86-
_, err = repo.ResolveRevision(plumbing.Revision("HEAD"))
87-
if err != nil {
88-
return fmt.Errorf("unable to get new HEAD: %w", err)
89-
}
90-
return nil
91-
}
92-
9321
// PluginIndex is a struct representing the user's preferences for plugin index
9422
// and the plugin index on disk.
9523
type PluginIndex struct {
96-
repo repoer
24+
repo git.Repoer
9725
directory string
26+
url string
9827
disableUpdate bool
9928
updateDurationMinutes int
10029
}
10130

10231
// New initializes a new PluginIndex instance with the options passed in.
103-
func New(directory string, disableUpdate bool, updateDurationMinutes int, repo repoer) PluginIndex {
32+
func New(directory, url string, disableUpdate bool, updateDurationMinutes int, repo git.Repoer) PluginIndex {
10433
return PluginIndex{
10534
repo: repo,
10635
directory: directory,
36+
url: url,
10737
disableUpdate: disableUpdate,
10838
updateDurationMinutes: updateDurationMinutes,
10939
}
@@ -125,7 +55,7 @@ func (p PluginIndex) Refresh() (bool, error) {
12555

12656
if len(files) == 0 {
12757
// directory empty, clone down repo
128-
err := p.repo.Install()
58+
err := p.repo.Clone(p.url)
12959
if err != nil {
13060
return false, err
13161
}
@@ -150,7 +80,9 @@ func (p PluginIndex) Refresh() (bool, error) {
15080
}
15181

15282
func (p PluginIndex) doUpdate() (bool, error) {
153-
err := p.repo.Update()
83+
// pass in empty string as we want the repo to figure out what the latest
84+
// commit is
85+
_, err := p.repo.Update("")
15486
if err != nil {
15587
return false, err
15688
}

0 commit comments

Comments
 (0)