@@ -3,19 +3,18 @@ package cli
3
3
import (
4
4
"archive/tar"
5
5
"bytes"
6
+ "errors"
6
7
"fmt"
7
8
"io"
8
9
"os"
9
10
"path/filepath"
10
- "strings"
11
11
"time"
12
12
13
13
"github.com/briandowns/spinner"
14
14
"github.com/fatih/color"
15
15
"github.com/google/uuid"
16
16
"github.com/manifoldco/promptui"
17
17
"github.com/spf13/cobra"
18
- "github.com/xlab/treeprint"
19
18
"golang.org/x/xerrors"
20
19
21
20
"github.com/coder/coder/coderd"
@@ -27,7 +26,8 @@ import (
27
26
28
27
func projectCreate ()* cobra.Command {
29
28
var (
30
- directory string
29
+ directory string
30
+ provisioner string
31
31
)
32
32
cmd := & cobra.Command {
33
33
Use :"create" ,
@@ -41,16 +41,19 @@ func projectCreate() *cobra.Command {
41
41
if err != nil {
42
42
return err
43
43
}
44
- _ ,err = runPrompt (cmd ,& promptui.Prompt {
44
+ _ ,err = prompt (cmd ,& promptui.Prompt {
45
45
Default :"y" ,
46
46
IsConfirm :true ,
47
47
Label :fmt .Sprintf ("Set up %s in your organization?" ,color .New (color .FgHiCyan ).Sprintf ("%q" ,directory )),
48
48
})
49
49
if err != nil {
50
+ if errors .Is (err ,promptui .ErrAbort ) {
51
+ return nil
52
+ }
50
53
return err
51
54
}
52
55
53
- name ,err := runPrompt (cmd ,& promptui.Prompt {
56
+ name ,err := prompt (cmd ,& promptui.Prompt {
54
57
Default :filepath .Base (directory ),
55
58
Label :"What's your project's name?" ,
56
59
Validate :func (s string )error {
@@ -65,7 +68,7 @@ func projectCreate() *cobra.Command {
65
68
return err
66
69
}
67
70
68
- job ,err := doProjectLoop (cmd ,client ,organization ,directory , []coderd. CreateParameterValueRequest {} )
71
+ job ,err := validateProjectVersionSource (cmd ,client ,organization ,database . ProvisionerType ( provisioner ), directory )
69
72
if err != nil {
70
73
return err
71
74
}
@@ -77,27 +80,44 @@ func projectCreate() *cobra.Command {
77
80
return err
78
81
}
79
82
83
+ _ ,err = prompt (cmd ,& promptui.Prompt {
84
+ Label :"Create project?" ,
85
+ IsConfirm :true ,
86
+ Default :"y" ,
87
+ })
88
+ if err != nil {
89
+ if errors .Is (err ,promptui .ErrAbort ) {
90
+ return nil
91
+ }
92
+ return err
93
+ }
94
+
80
95
_ ,_ = fmt .Fprintf (cmd .OutOrStdout (),"%s The %s project has been created!\n " ,color .HiBlackString (">" ),color .HiCyanString (project .Name ))
81
- _ ,err = runPrompt (cmd ,& promptui.Prompt {
96
+ _ ,err = prompt (cmd ,& promptui.Prompt {
82
97
Label :"Create a new workspace?" ,
83
98
IsConfirm :true ,
84
99
Default :"y" ,
85
100
})
86
101
if err != nil {
102
+ if errors .Is (err ,promptui .ErrAbort ) {
103
+ return nil
104
+ }
87
105
return err
88
106
}
89
107
90
- fmt .Printf ("Create a new workspace now!\n " )
91
108
return nil
92
109
},
93
110
}
94
111
currentDirectory ,_ := os .Getwd ()
95
112
cmd .Flags ().StringVarP (& directory ,"directory" ,"d" ,currentDirectory ,"Specify the directory to create from" )
113
+ cmd .Flags ().StringVarP (& provisioner ,"provisioner" ,"p" ,"terraform" ,"Customize the provisioner backend" )
114
+ // This is for testing! There's only 1 provisioner type right now.
115
+ cmd .Flags ().MarkHidden ("provisioner" )
96
116
97
117
return cmd
98
118
}
99
119
100
- func doProjectLoop (cmd * cobra.Command ,client * codersdk.Client ,organization coderd.Organization ,directory string ,params [] coderd.CreateParameterValueRequest ) (* coderd.ProvisionerJob ,error ) {
120
+ func validateProjectVersionSource (cmd * cobra.Command ,client * codersdk.Client ,organization coderd.Organization ,provisioner database. ProvisionerType , directory string ,parameters ... coderd.CreateParameterValueRequest ) (* coderd.ProvisionerJob ,error ) {
101
121
spin := spinner .New (spinner .CharSets [5 ],100 * time .Millisecond )
102
122
spin .Writer = cmd .OutOrStdout ()
103
123
spin .Suffix = " Uploading current directory..."
@@ -118,8 +138,8 @@ func doProjectLoop(cmd *cobra.Command, client *codersdk.Client, organization cod
118
138
job ,err := client .CreateProjectVersionImportProvisionerJob (cmd .Context (),organization .Name , coderd.CreateProjectImportJobRequest {
119
139
StorageMethod :database .ProvisionerStorageMethodFile ,
120
140
StorageSource :resp .Hash ,
121
- Provisioner :database . ProvisionerTypeTerraform ,
122
- ParameterValues :params ,
141
+ Provisioner :provisioner ,
142
+ ParameterValues :parameters ,
123
143
})
124
144
if err != nil {
125
145
return nil ,err
@@ -168,20 +188,20 @@ func doProjectLoop(cmd *cobra.Command, client *codersdk.Client, organization cod
168
188
if parameterSchema .Name == parameter .CoderWorkspaceTransition {
169
189
continue
170
190
}
171
- value ,err := runPrompt (cmd ,& promptui.Prompt {
191
+ value ,err := prompt (cmd ,& promptui.Prompt {
172
192
Label :fmt .Sprintf ("Enter value for %s:" ,color .HiCyanString (parameterSchema .Name )),
173
193
})
174
194
if err != nil {
175
195
return nil ,err
176
196
}
177
- params = append (params , coderd.CreateParameterValueRequest {
197
+ parameters = append (parameters , coderd.CreateParameterValueRequest {
178
198
Name :parameterSchema .Name ,
179
199
SourceValue :value ,
180
200
SourceScheme :database .ParameterSourceSchemeData ,
181
201
DestinationScheme :parameterSchema .DefaultDestinationScheme ,
182
202
})
183
203
}
184
- return doProjectLoop (cmd ,client ,organization ,directory ,params )
204
+ return validateProjectVersionSource (cmd ,client ,organization ,provisioner , directory ,parameters ... )
185
205
}
186
206
187
207
if job .Status != coderd .ProvisionerJobStatusSucceeded {
@@ -198,50 +218,7 @@ func doProjectLoop(cmd *cobra.Command, client *codersdk.Client, organization cod
198
218
if err != nil {
199
219
return nil ,err
200
220
}
201
- return & job ,outputProjectInformation (cmd ,parameterSchemas ,parameterValues ,resources )
202
- }
203
-
204
- func outputProjectInformation (cmd * cobra.Command ,parameterSchemas []coderd.ParameterSchema ,parameterValues []coderd.ComputedParameterValue ,resources []coderd.ProjectImportJobResource )error {
205
- schemaByID := map [string ]coderd.ParameterSchema {}
206
- for _ ,schema := range parameterSchemas {
207
- schemaByID [schema .ID .String ()]= schema
208
- }
209
-
210
- _ ,_ = fmt .Fprintf (cmd .OutOrStdout (),"\n %s\n \n " ,color .HiBlackString ("Parameters" ))
211
- for _ ,value := range parameterValues {
212
- schema ,ok := schemaByID [value .SchemaID .String ()]
213
- if ! ok {
214
- return xerrors .Errorf ("schema not found: %s" ,value .Name )
215
- }
216
- displayValue := value .SourceValue
217
- if ! schema .RedisplayValue {
218
- displayValue = "<redacted>"
219
- }
220
- output := fmt .Sprintf ("%s %s %s" ,color .HiCyanString (value .Name ),color .HiBlackString ("=" ),displayValue )
221
- if value .DefaultSourceValue {
222
- output += " (default value)"
223
- }else if value .Scope != database .ParameterScopeImportJob {
224
- output += fmt .Sprintf (" (inherited from %s)" ,value .Scope )
225
- }
226
-
227
- root := treeprint .NewWithRoot (output )
228
- if schema .Description != "" {
229
- root .AddBranch (fmt .Sprintf ("%s\n %s\n " ,color .HiBlackString ("Description" ),schema .Description ))
230
- }
231
- if schema .AllowOverrideSource {
232
- root .AddBranch (fmt .Sprintf ("%s Users can customize this value!" ,color .HiYellowString ("+" )))
233
- }
234
- _ ,_ = fmt .Fprintln (cmd .OutOrStdout ()," " + strings .Join (strings .Split (root .String (),"\n " ),"\n " ))
235
- }
236
- _ ,_ = fmt .Fprintf (cmd .OutOrStdout ()," %s\n \n " ,color .HiBlackString ("Resources" ))
237
- for _ ,resource := range resources {
238
- transition := color .HiGreenString ("start" )
239
- if resource .Transition == database .WorkspaceTransitionStop {
240
- transition = color .HiRedString ("stop" )
241
- }
242
- _ ,_ = fmt .Fprintf (cmd .OutOrStdout ()," %s %s on %s\n \n " ,color .HiCyanString (resource .Type ),color .HiCyanString (resource .Name ),transition )
243
- }
244
- return nil
221
+ return & job ,displayProjectImportInfo (cmd ,parameterSchemas ,parameterValues ,resources )
245
222
}
246
223
247
224
func tarDirectory (directory string ) ([]byte ,error ) {