@@ -7,16 +7,19 @@ import (
7
7
"io"
8
8
"os"
9
9
"path/filepath"
10
+ "strings"
10
11
"time"
11
12
12
13
"github.com/briandowns/spinner"
13
14
"github.com/fatih/color"
14
15
"github.com/google/uuid"
15
16
"github.com/manifoldco/promptui"
16
17
"github.com/spf13/cobra"
18
+ "github.com/xlab/treeprint"
17
19
"golang.org/x/xerrors"
18
20
19
21
"github.com/coder/coder/coderd"
22
+ "github.com/coder/coder/coderd/parameter"
20
23
"github.com/coder/coder/codersdk"
21
24
"github.com/coder/coder/database"
22
25
"github.com/coder/coder/provisionerd"
@@ -62,150 +65,178 @@ func projectCreate() *cobra.Command {
62
65
return err
63
66
}
64
67
65
- spin := spinner .New (spinner .CharSets [0 ], 25 * time .Millisecond )
66
- spin .Suffix = " Uploading current directory..."
67
- spin .Start ()
68
-
69
- defer spin .Stop ()
70
-
71
- bytes , err := tarDirectory (directory )
68
+ job , err := doProjectLoop (cmd , client , organization , directory , []coderd.CreateParameterValueRequest {})
72
69
if err != nil {
73
70
return err
74
71
}
75
-
76
- resp , err := client .UploadFile (cmd .Context (), codersdk .ContentTypeTar , bytes )
72
+ project , err := client .CreateProject (cmd .Context (), organization .Name , coderd.CreateProjectRequest {
73
+ Name : name ,
74
+ VersionImportJobID : job .ID ,
75
+ })
77
76
if err != nil {
78
77
return err
79
78
}
80
79
81
- job , err := client .CreateProjectVersionImportProvisionerJob (cmd .Context (), organization .Name , coderd.CreateProjectImportJobRequest {
82
- StorageMethod : database .ProvisionerStorageMethodFile ,
83
- StorageSource : resp .Hash ,
84
- Provisioner : database .ProvisionerTypeTerraform ,
80
+ _ , _ = fmt .Fprintf (cmd .OutOrStdout (), "%s The %s project has been created!\n " , color .HiBlackString (">" ), color .HiCyanString (project .Name ))
81
+ _ , err = runPrompt (cmd , & promptui.Prompt {
82
+ Label : "Create a new workspace?" ,
83
+ IsConfirm : true ,
84
+ Default : "y" ,
85
85
})
86
86
if err != nil {
87
87
return err
88
88
}
89
- spin .Stop ()
90
89
91
- logs , err := client .FollowProvisionerJobLogsAfter (cmd .Context (), organization .Name , job .ID , time.Time {})
92
- if err != nil {
93
- return err
94
- }
95
- for {
96
- log , ok := <- logs
97
- if ! ok {
98
- break
99
- }
100
- _ , _ = fmt .Fprintf (cmd .OutOrStdout (), "%s %s\n " , color .HiGreenString ("[tf]" ), log .Output )
101
- }
90
+ fmt .Printf ("Create a new workspace now!\n " )
91
+ return nil
92
+ },
93
+ }
94
+ currentDirectory , _ := os .Getwd ()
95
+ cmd .Flags ().StringVarP (& directory , "directory" , "d" , currentDirectory , "Specify the directory to create from" )
102
96
103
- job , err = client .ProvisionerJob (cmd .Context (), organization .Name , job .ID )
104
- if err != nil {
105
- return err
106
- }
97
+ return cmd
98
+ }
107
99
108
- if provisionerd .IsMissingParameterError (job .Error ) {
109
- fmt .Printf ("Missing something!\n " )
110
- return nil
111
- }
100
+ func doProjectLoop (cmd * cobra.Command , client * codersdk.Client , organization coderd.Organization , directory string , params []coderd.CreateParameterValueRequest ) (* coderd.ProvisionerJob , error ) {
101
+ spin := spinner .New (spinner .CharSets [5 ], 100 * time .Millisecond )
102
+ spin .Writer = cmd .OutOrStdout ()
103
+ spin .Suffix = " Uploading current directory..."
104
+ spin .Color ("fgHiGreen" )
105
+ spin .Start ()
106
+ defer spin .Stop ()
112
107
113
- resources , err := client .ProvisionerJobResources (cmd .Context (), organization .Name , job .ID )
114
- if err != nil {
115
- return err
116
- }
108
+ bytes , err := tarDirectory (directory )
109
+ if err != nil {
110
+ return nil , err
111
+ }
112
+
113
+ resp , err := client .UploadFile (cmd .Context (), codersdk .ContentTypeTar , bytes )
114
+ if err != nil {
115
+ return nil , err
116
+ }
117
117
118
- fmt .Printf ("Resources: %+v\n " , resources )
118
+ job , err := client .CreateProjectVersionImportProvisionerJob (cmd .Context (), organization .Name , coderd.CreateProjectImportJobRequest {
119
+ StorageMethod : database .ProvisionerStorageMethodFile ,
120
+ StorageSource : resp .Hash ,
121
+ Provisioner : database .ProvisionerTypeTerraform ,
122
+ ParameterValues : params ,
123
+ })
124
+ if err != nil {
125
+ return nil , err
126
+ }
119
127
120
- project , err := client .CreateProject (cmd .Context (), organization .Name , coderd.CreateProjectRequest {
121
- Name : name ,
122
- VersionImportJobID : job .ID ,
128
+ spin .Suffix = " Waiting for the import to complete..."
129
+
130
+ logs , err := client .FollowProvisionerJobLogsAfter (cmd .Context (), organization .Name , job .ID , time.Time {})
131
+ if err != nil {
132
+ return nil , err
133
+ }
134
+ for {
135
+ _ , ok := <- logs
136
+ if ! ok {
137
+ break
138
+ }
139
+ // _, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s %s\n", color.HiGreenString("[tf]"), log.Output)
140
+ }
141
+
142
+ job , err = client .ProvisionerJob (cmd .Context (), organization .Name , job .ID )
143
+ if err != nil {
144
+ return nil , err
145
+ }
146
+
147
+ parameterSchemas , err := client .ProvisionerJobParameterSchemas (cmd .Context (), organization .Name , job .ID )
148
+ if err != nil {
149
+ return nil , err
150
+ }
151
+ parameterValues , err := client .ProvisionerJobParameterValues (cmd .Context (), organization .Name , job .ID )
152
+ if err != nil {
153
+ return nil , err
154
+ }
155
+ spin .Stop ()
156
+
157
+ if provisionerd .IsMissingParameterError (job .Error ) {
158
+ valuesBySchemaID := map [string ]coderd.ComputedParameterValue {}
159
+ for _ , parameterValue := range parameterValues {
160
+ valuesBySchemaID [parameterValue .SchemaID .String ()] = parameterValue
161
+ }
162
+ for _ , parameterSchema := range parameterSchemas {
163
+ _ , ok := valuesBySchemaID [parameterSchema .ID .String ()]
164
+ if ok {
165
+ continue
166
+ }
167
+ if parameterSchema .Name == parameter .CoderWorkspaceTransition {
168
+ continue
169
+ }
170
+ value , err := runPrompt (cmd , & promptui.Prompt {
171
+ Label : fmt .Sprintf ("Enter value for %s:" , color .HiCyanString (parameterSchema .Name )),
123
172
})
124
173
if err != nil {
125
- return err
174
+ return nil , err
126
175
}
176
+ params = append (params , coderd.CreateParameterValueRequest {
177
+ Name : parameterSchema .Name ,
178
+ SourceValue : value ,
179
+ SourceScheme : database .ParameterSourceSchemeData ,
180
+ DestinationScheme : parameterSchema .DefaultDestinationScheme ,
181
+ })
182
+ }
183
+ return doProjectLoop (cmd , client , organization , directory , params )
184
+ }
127
185
128
- fmt .Printf ("Project: %+v\n " , project )
129
-
130
- // _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Parsed project source... displaying parameters:")
131
-
132
- // schemas, err := client.ProvisionerJobParameterSchemas(cmd.Context(), organization.Name, job.ID)
133
- // if err != nil {
134
- // return err
135
- // }
136
-
137
- // values, err := client.ProvisionerJobParameterValues(cmd.Context(), organization.Name, job.ID)
138
- // if err != nil {
139
- // return err
140
- // }
141
- // valueBySchemaID := map[string]coderd.ComputedParameterValue{}
142
- // for _, value := range values {
143
- // valueBySchemaID[value.SchemaID.String()] = value
144
- // }
145
-
146
- // for _, schema := range schemas {
147
- // if value, ok := valueBySchemaID[schema.ID.String()]; ok {
148
- // fmt.Printf("Value for: %s %s\n", value.Name, value.SourceValue)
149
- // continue
150
- // }
151
- // fmt.Printf("No value for: %s\n", schema.Name)
152
- // }
153
-
154
- // schemas, err := client.ProvisionerJobParameterSchemas(cmd.Context(), organization.Name, job.ID)
155
- // if err != nil {
156
- // return err
157
- // }
158
- // _, _ = fmt.Fprintf(cmd.OutOrStdout(), "\n %s\n\n", color.HiBlackString("Parameters"))
159
-
160
- // for _, param := range params {
161
- // if param.Value == nil {
162
- // _, _ = fmt.Fprintf(cmd.OutOrStdout(), " %s = must be set\n", color.HiRedString(param.Schema.Name))
163
- // continue
164
- // }
165
- // value := param.Value.DestinationValue
166
- // if !param.Schema.RedisplayValue {
167
- // value = "<redacted>"
168
- // }
169
- // output := fmt.Sprintf(" %s = %s", color.HiGreenString(param.Value.SourceValue), color.CyanString(value))
170
- // param.Value.DefaultSourceValue = false
171
- // param.Value.Scope = database.ParameterScopeOrganization
172
- // param.Value.ScopeID = organization.ID
173
- // if param.Value.DefaultSourceValue {
174
- // output += " (default value)"
175
- // } else {
176
- // output += fmt.Sprintf(" (inherited from %s)", param.Value.Scope)
177
- // }
178
- // root := treeprint.NewWithRoot(output)
179
- // root.AddNode(color.HiBlackString("Description") + "\n" + param.Schema.Description)
180
- // fmt.Fprintln(cmd.OutOrStdout(), strings.Join(strings.Split(root.String(), "\n"), "\n "))
181
- // }
182
-
183
- // for _, param := range params {
184
- // if param.Value != nil {
185
- // continue
186
- // }
187
-
188
- // value, err := runPrompt(cmd, &promptui.Prompt{
189
- // Label: "Specify value for " + color.HiCyanString(param.Schema.Name),
190
- // Validate: func(s string) error {
191
- // // param.Schema.Vali
192
- // return nil
193
- // },
194
- // })
195
- // if err != nil {
196
- // continue
197
- // }
198
- // fmt.Printf(": %s\n", value)
199
- // }
200
-
201
- _ , _ = fmt .Fprintf (cmd .OutOrStdout (), "Create project %q!\n " , name )
202
- return nil
203
- },
186
+ if job .Status != coderd .ProvisionerJobStatusSucceeded {
187
+ return nil , xerrors .New (job .Error )
204
188
}
205
- currentDirectory , _ := os .Getwd ()
206
- cmd .Flags ().StringVarP (& directory , "directory" , "d" , currentDirectory , "Specify the directory to create from" )
207
189
208
- return cmd
190
+ _ , _ = fmt .Fprintf (cmd .OutOrStdout (), "%s Successfully imported project source!\n " , color .HiGreenString ("✓" ))
191
+
192
+ resources , err := client .ProvisionerJobResources (cmd .Context (), organization .Name , job .ID )
193
+ if err != nil {
194
+ return nil , err
195
+ }
196
+ return & job , outputProjectInformation (cmd , parameterSchemas , parameterValues , resources )
197
+ }
198
+
199
+ func outputProjectInformation (cmd * cobra.Command , parameterSchemas []coderd.ParameterSchema , parameterValues []coderd.ComputedParameterValue , resources []coderd.ProjectImportJobResource ) error {
200
+ schemaByID := map [string ]coderd.ParameterSchema {}
201
+ for _ , schema := range parameterSchemas {
202
+ schemaByID [schema .ID .String ()] = schema
203
+ }
204
+
205
+ _ , _ = fmt .Fprintf (cmd .OutOrStdout (), "\n %s\n \n " , color .HiBlackString ("Parameters" ))
206
+ for _ , value := range parameterValues {
207
+ schema , ok := schemaByID [value .SchemaID .String ()]
208
+ if ! ok {
209
+ return xerrors .Errorf ("schema not found: %s" , value .Name )
210
+ }
211
+ displayValue := value .SourceValue
212
+ if ! schema .RedisplayValue {
213
+ displayValue = "<redacted>"
214
+ }
215
+ output := fmt .Sprintf ("%s %s %s" , color .HiCyanString (value .Name ), color .HiBlackString ("=" ), displayValue )
216
+ if value .DefaultSourceValue {
217
+ output += " (default value)"
218
+ } else if value .Scope != database .ParameterScopeImportJob {
219
+ output += fmt .Sprintf (" (inherited from %s)" , value .Scope )
220
+ }
221
+
222
+ root := treeprint .NewWithRoot (output )
223
+ if schema .Description != "" {
224
+ root .AddBranch (fmt .Sprintf ("%s\n %s\n " , color .HiBlackString ("Description" ), schema .Description ))
225
+ }
226
+ if schema .AllowOverrideSource {
227
+ root .AddBranch (fmt .Sprintf ("%s Users can customize this value!" , color .HiYellowString ("+" )))
228
+ }
229
+ _ , _ = fmt .Fprintln (cmd .OutOrStdout (), " " + strings .Join (strings .Split (root .String (), "\n " ), "\n " ))
230
+ }
231
+ _ , _ = fmt .Fprintf (cmd .OutOrStdout (), " %s\n \n " , color .HiBlackString ("Resources" ))
232
+ for _ , resource := range resources {
233
+ transition := color .HiGreenString ("start" )
234
+ if resource .Transition == database .WorkspaceTransitionStop {
235
+ transition = color .HiRedString ("stop" )
236
+ }
237
+ _ , _ = fmt .Fprintf (cmd .OutOrStdout (), " %s %s on %s\n \n " , color .HiCyanString (resource .Type ), color .HiCyanString (resource .Name ), transition )
238
+ }
239
+ return nil
209
240
}
210
241
211
242
func tarDirectory (directory string ) ([]byte , error ) {
0 commit comments