This repository was archived by the owner on Aug 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 605
Expand file tree
/
Copy pathcommand.go
More file actions
171 lines (137 loc) · 3.76 KB
/
Copy pathcommand.go
File metadata and controls
171 lines (137 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package open
import (
"errors"
"fmt"
"io"
"koding/klient/kiteerrortypes"
"koding/klientctl/ctlcli"
"koding/klientctl/klient"
"koding/klientctl/klientctlerrors"
"koding/klientctl/util"
"strings"
"github.com/koding/logging"
)
// CLI options for the given command.
type Options struct {
Debug bool
Filepaths []string
}
// Init contains various instances required for a Command instance to be initialized.
type Init struct {
Stdout io.Writer
Log logging.Logger
// The options to use if this struct needs to dial Klient.
//
// Note! These will be ignored if c.Klient is already defined before Run() is
// called.
KlientOptions klient.KlientOptions
// The klient instance this struct will use.
Klient interface {
LocalOpenFiles(...string) error
}
// The ctlcli Helper. See the type docs for a better understanding of this.
Helper ctlcli.Helper
}
func (i Init) CheckValid() error {
if i.Stdout == nil {
return errors.New("missing argument: Stdout")
}
if i.Log == nil {
return errors.New("missing argument: Log")
}
if i.Helper == nil {
return errors.New("missing argument: Helper")
}
return nil
}
// Command implements the klientctl.Command interface for `kd open`
type Command struct {
// Embedded Init gives us our Klient/etc instances.
Init
Options Options
Stdout *util.Fprint
// do not print an error's err.Error() string at the end of running. This
// is useful to use a custom error message for specific errors.
dontPrintErr bool
}
func NewCommand(i Init, o Options) (*Command, error) {
if err := i.CheckValid(); err != nil {
return nil, err
}
if o.Debug {
i.Log.SetLevel(logging.DEBUG)
}
c := &Command{
Init: i,
Options: o,
// Override the init stdout writer with an Fprint writer
Stdout: util.NewFprint(i.Stdout),
}
return c, nil
}
// Help prints help to the caller.
func (c *Command) Help() {
c.Helper(c.Stdout)
}
func (c *Command) Run() (exit int, err error) {
defer func() {
if err != nil && !c.dontPrintErr {
c.Stdout.Printlnf(err.Error())
}
}()
if err := c.setupKlient(); err != nil {
return 1, err
}
if err := c.runOpen(); err != nil {
return 1, err
}
return 0, nil
}
// setupKlient creates and dials our Kite interface *only* if it is nil. If it is
// not nil, someone else gave a kite to this Command, and it is expected to be
// dialed and working.
func (c *Command) setupKlient() error {
// if c.klient isnt nil, don't overrite it. Another command may have provided
// a pre-dialed klient.
if c.Klient != nil {
return nil
}
k, err := klient.NewDialedKlient(c.KlientOptions)
if err != nil {
return fmt.Errorf("failed to get working klient instance: %s", err)
}
c.Klient = k
return nil
}
func (c *Command) runOpen() error {
paths, err := PreparePaths(c.Options.Filepaths)
if err != nil {
return fmt.Errorf("failed to parse files and directories: %s", err)
}
if err := Mkfiles(paths, 0644); err != nil {
return fmt.Errorf("failed to create files or directories: %s", err)
}
files, dirs, err := FileOrDir(paths)
if err != nil {
return fmt.Errorf("failed to split files and directories: %s", err)
}
if len(dirs) != 0 {
c.Stdout.Printlnf(
`Directories cannot be opened in the WebIDE.
Ignoring the following directories:
%s`,
strings.Join(dirs, "\n "))
}
if err := c.Klient.LocalOpenFiles(files...); err != nil {
if klientctlerrors.IsKiteOfTypeErr(err, kiteerrortypes.NoSubscribers) {
c.dontPrintErr = true
c.Stdout.Printlnf(`Unable to open the requested files on the Koding UI.
Please make sure this machine is visible on the Koding UI, and that you're
viewing it. If needed, refresh your browser so that Koding UI properly listens for
this "open files" request.`)
return err
}
return fmt.Errorf("failed to talk to open files: %s", err)
}
return nil
}