@@ -2,6 +2,7 @@ package extensions
2
2
3
3
import (
4
4
"errors"
5
+ "fmt"
5
6
"io"
6
7
"io/ioutil"
7
8
"os"
@@ -17,14 +18,12 @@ import (
17
18
type Manager struct {
18
19
dataDir func () string
19
20
lookPath func (string ) (string , error )
20
- pathEnv string
21
21
}
22
22
23
23
func NewManager () * Manager {
24
24
return & Manager {
25
25
dataDir : config .ConfigDir ,
26
26
lookPath : safeexec .LookPath ,
27
- pathEnv : os .Getenv ("PATH" ),
28
27
}
29
28
}
30
29
@@ -37,18 +36,14 @@ func (m *Manager) Dispatch(args []string, stdin io.Reader, stdout, stderr io.Wri
37
36
extName := "gh-" + args [0 ]
38
37
forwardArgs := args [1 :]
39
38
40
- for _ , e := range m .listInstalled () {
39
+ for _ , e := range m .List () {
41
40
if filepath .Base (e ) == extName {
42
41
exe = e
43
42
break
44
43
}
45
44
}
46
45
if exe == "" {
47
- var err error
48
- exe , err = m .lookPath (extName )
49
- if err != nil {
50
- return false , nil
51
- }
46
+ return false , nil
52
47
}
53
48
54
49
// TODO: parse the shebang on Windows and invoke the correct interpreter instead of invoking directly
@@ -59,7 +54,7 @@ func (m *Manager) Dispatch(args []string, stdin io.Reader, stdout, stderr io.Wri
59
54
return true , externalCmd .Run ()
60
55
}
61
56
62
- func (m * Manager ) listInstalled () []string {
57
+ func (m * Manager ) List () []string {
63
58
dir := m .installDir ()
64
59
entries , err := ioutil .ReadDir (dir )
65
60
if err != nil {
@@ -68,39 +63,18 @@ func (m *Manager) listInstalled() []string {
68
63
69
64
var results []string
70
65
for _ , f := range entries {
71
- if ! strings .HasPrefix (f .Name (), "gh-" ) || ! f .IsDir () {
66
+ if ! strings .HasPrefix (f .Name (), "gh-" ) || ! ( f .IsDir () || f . Mode () & os . ModeSymlink != 0 ) {
72
67
continue
73
68
}
74
69
results = append (results , filepath .Join (dir , f .Name (), f .Name ()))
75
70
}
76
71
return results
77
72
}
78
73
79
- func (m * Manager ) List () []string {
80
- results := m .listInstalled ()
81
- seen := make (map [string ]struct {})
82
- for _ , f := range results {
83
- seen [filepath .Base (f )] = struct {}{}
84
- }
85
-
86
- for _ , p := range filepath .SplitList (m .pathEnv ) {
87
- entries , err := ioutil .ReadDir (p )
88
- if err != nil {
89
- continue
90
- }
91
- for _ , f := range entries {
92
- if _ , ok := seen [f .Name ()]; ok {
93
- continue
94
- }
95
- if ! strings .HasPrefix (f .Name (), "gh-" ) || ! isExecutable (f ) {
96
- continue
97
- }
98
- results = append (results , filepath .Join (p , f .Name ()))
99
- seen [f .Name ()] = struct {}{}
100
- }
101
- }
102
-
103
- return results
74
+ func (m * Manager ) InstallLocal (dir string ) error {
75
+ name := filepath .Base (dir )
76
+ targetDir := filepath .Join (m .installDir (), name )
77
+ return os .Symlink (dir , targetDir )
104
78
}
105
79
106
80
func (m * Manager ) Install (cloneURL string , stdout , stderr io.Writer ) error {
@@ -124,13 +98,15 @@ func (m *Manager) Upgrade(stdout, stderr io.Writer) error {
124
98
return err
125
99
}
126
100
127
- exts := m .listInstalled ()
101
+ exts := m .List ()
128
102
if len (exts ) == 0 {
129
103
return errors .New ("no extensions installed" )
130
104
}
131
105
132
106
for _ , f := range exts {
133
- externalCmd := exec .Command (exe , "-C" , filepath .Dir (f ), "pull" , "--ff-only" )
107
+ fmt .Fprintf (stdout , "[%s]: " , filepath .Base (f ))
108
+ dir := filepath .Dir (f )
109
+ externalCmd := exec .Command (exe , "-C" , dir , "--git-dir=" + filepath .Join (dir , ".git" ), "pull" , "--ff-only" )
134
110
externalCmd .Stdout = stdout
135
111
externalCmd .Stderr = stderr
136
112
if e := externalCmd .Run (); e != nil {
@@ -143,8 +119,3 @@ func (m *Manager) Upgrade(stdout, stderr io.Writer) error {
143
119
func (m * Manager ) installDir () string {
144
120
return filepath .Join (m .dataDir (), "extensions" )
145
121
}
146
-
147
- // TODO: ignore file mode on Windows
148
- func isExecutable (f os.FileInfo ) bool {
149
- return ! f .IsDir () && f .Mode ()& 0111 != 0
150
- }
0 commit comments