Skip to content

Commit 8146d00

Browse files
committed
Move templates to examples
1 parent 2cc902f commit 8146d00

File tree

18 files changed

+296
-160
lines changed

18 files changed

+296
-160
lines changed

cli/cliui/job.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package cliui

cli/projectcreate.go

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"path/filepath"
8+
"sort"
79
"time"
810

911
"github.com/briandowns/spinner"
@@ -26,8 +28,7 @@ func projectCreate() *cobra.Command {
2628
provisioner string
2729
)
2830
cmd := &cobra.Command{
29-
Use: "create <name>",
30-
Args: cobra.ExactArgs(1),
31+
Use: "create [name]",
3132
Short: "Create a project from the current directory",
3233
RunE: func(cmd *cobra.Command, args []string) error {
3334
client, err := createClient(cmd)
@@ -39,18 +40,39 @@ func projectCreate() *cobra.Command {
3940
return err
4041
}
4142

42-
projectName := args[0]
43+
var projectName string
44+
if len(args) == 0 {
45+
projectName = filepath.Base(directory)
46+
} else {
47+
projectName = args[0]
48+
}
4349
_, err = client.ProjectByName(cmd.Context(), organization.ID, projectName)
4450
if err == nil {
4551
return xerrors.Errorf("A project already exists named %q!", projectName)
4652
}
4753

54+
start := time.Now()
4855
archive, err := provisionersdk.Tar(directory)
4956
if err != nil {
5057
return err
5158
}
59+
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
60+
spin.Writer = cmd.OutOrStdout()
61+
spin.Suffix = " Uploading current directory..."
62+
err = spin.Color("fgHiGreen")
63+
if err != nil {
64+
return err
65+
}
66+
spin.Start()
67+
defer spin.Stop()
68+
resp, err := client.Upload(cmd.Context(), codersdk.ContentTypeTar, archive)
69+
if err != nil {
70+
return err
71+
}
72+
spin.FinalMSG = fmt.Sprintf("Uploaded %d byte archive! [%dms]", len(archive), time.Now().Sub(start).Milliseconds()) + "\n"
73+
spin.Stop()
5274

53-
job, parameters, err := createValidProjectVersion(cmd, client, organization, database.ProvisionerType(provisioner), archive)
75+
job, parameters, err := createValidProjectVersion(cmd, client, organization, database.ProvisionerType(provisioner), resp.Hash)
5476
if err != nil {
5577
return err
5678
}
@@ -94,33 +116,52 @@ func projectCreate() *cobra.Command {
94116
return cmd
95117
}
96118

97-
func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, organization codersdk.Organization, provisioner database.ProvisionerType, archive []byte, parameters ...codersdk.CreateParameterRequest) (*codersdk.ProjectVersion, []codersdk.CreateParameterRequest, error) {
98-
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
99-
spin.Writer = cmd.OutOrStdout()
100-
spin.Suffix = " Uploading current directory..."
101-
err := spin.Color("fgHiGreen")
102-
if err != nil {
103-
return nil, nil, err
104-
}
105-
spin.Start()
106-
defer spin.Stop()
107-
108-
resp, err := client.Upload(cmd.Context(), codersdk.ContentTypeTar, archive)
109-
if err != nil {
110-
return nil, nil, err
111-
}
112-
119+
func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, organization codersdk.Organization, provisioner database.ProvisionerType, hash string, parameters ...codersdk.CreateParameterRequest) (*codersdk.ProjectVersion, []codersdk.CreateParameterRequest, error) {
113120
before := time.Now()
114121
version, err := client.CreateProjectVersion(cmd.Context(), organization.ID, codersdk.CreateProjectVersionRequest{
115122
StorageMethod: database.ProvisionerStorageMethodFile,
116-
StorageSource: resp.Hash,
123+
StorageSource: hash,
117124
Provisioner: provisioner,
118125
ParameterValues: parameters,
119126
})
120127
if err != nil {
121128
return nil, nil, err
122129
}
130+
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
131+
spin.Writer = cmd.OutOrStdout()
123132
spin.Suffix = " Waiting for the import to complete..."
133+
spin.FinalMSG = "Parsed project..."
134+
spin.Start()
135+
136+
doneChan := make(chan struct{})
137+
go func() {
138+
defer spin.Stop()
139+
ticker := time.NewTicker(time.Second)
140+
for {
141+
select {
142+
case <-doneChan:
143+
return
144+
case <-ticker.C:
145+
}
146+
version, err := client.ProjectVersion(cmd.Context(), version.ID)
147+
if err != nil {
148+
continue
149+
}
150+
switch version.Job.Status {
151+
case codersdk.ProvisionerJobPending:
152+
spin.Suffix = "Pending..."
153+
case codersdk.ProvisionerJobCanceled:
154+
spin.Suffix = "Canceled..."
155+
case codersdk.ProvisionerJobCanceling:
156+
spin.Suffix = "Canceling..."
157+
case codersdk.ProvisionerJobFailed:
158+
spin.FinalMSG = version.Job.Error
159+
case codersdk.ProvisionerJobRunning:
160+
spin.Suffix = "Running..."
161+
}
162+
}
163+
}()
164+
124165
logs, err := client.ProjectVersionLogsAfter(cmd.Context(), version.ID, before)
125166
if err != nil {
126167
return nil, nil, err
@@ -153,6 +194,9 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
153194
for _, parameterValue := range parameterValues {
154195
valuesBySchemaID[parameterValue.SchemaID.String()] = parameterValue
155196
}
197+
sort.Slice(parameterSchemas, func(i, j int) bool {
198+
return parameterSchemas[i].Name < parameterSchemas[j].Name
199+
})
156200
for _, parameterSchema := range parameterSchemas {
157201
_, ok := valuesBySchemaID[parameterSchema.ID.String()]
158202
if ok {
@@ -171,7 +215,7 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
171215
DestinationScheme: parameterSchema.DefaultDestinationScheme,
172216
})
173217
}
174-
return createValidProjectVersion(cmd, client, organization, provisioner, archive, parameters...)
218+
return createValidProjectVersion(cmd, client, organization, provisioner, hash, parameters...)
175219
}
176220

177221
if version.Job.Status != codersdk.ProvisionerJobSucceeded {

cli/projectinit.go

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,39 @@ import (
66
"path/filepath"
77

88
"github.com/coder/coder/cli/cliui"
9-
"github.com/coder/coder/codersdk"
9+
"github.com/coder/coder/examples"
1010
"github.com/coder/coder/provisionersdk"
11-
"github.com/coder/coder/template"
1211
"github.com/spf13/cobra"
1312
)
1413

1514
func projectInit() *cobra.Command {
1615
return &cobra.Command{
1716
Use: "init [directory]",
18-
Short: "Get started with an example project.",
17+
Short: "Get started with a templated project.",
1918
RunE: func(cmd *cobra.Command, args []string) error {
20-
templates, err := template.List()
19+
exampleList, err := examples.List()
2120
if err != nil {
2221
return err
2322
}
24-
templateNames := []string{}
25-
templateByName := map[string]codersdk.Template{}
26-
for _, template := range templates {
27-
templateNames = append(templateNames, template.Name)
28-
templateByName[template.Name] = template
23+
exampleNames := []string{}
24+
exampleByName := map[string]examples.Example{}
25+
for _, example := range exampleList {
26+
exampleNames = append(exampleNames, example.Name)
27+
exampleByName[example.Name] = example
2928
}
3029

31-
fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Templates contain Infrastructure as Code that works with Coder to provision development workspaces. Get started by selecting one:\n"))
32-
30+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Templates contain Infrastructure as Code that works with Coder to provision development workspaces. Get started by selecting one:\n"))
3331
option, err := cliui.Select(cmd, cliui.SelectOptions{
34-
Options: templateNames,
32+
Options: exampleNames,
3533
})
3634
if err != nil {
3735
return err
3836
}
39-
selectedTemplate := templateByName[option]
40-
41-
archive, err := template.Archive(selectedTemplate.ID)
37+
selectedTemplate := exampleByName[option]
38+
archive, err := examples.Archive(selectedTemplate.ID)
4239
if err != nil {
4340
return err
4441
}
45-
4642
workingDir, err := os.Getwd()
4743
if err != nil {
4844
return err
@@ -53,28 +49,23 @@ func projectInit() *cobra.Command {
5349
} else {
5450
directory = filepath.Join(workingDir, selectedTemplate.ID)
5551
}
56-
5752
relPath, err := filepath.Rel(workingDir, directory)
5853
if err != nil {
5954
relPath = directory
6055
} else {
6156
relPath = "./" + relPath
6257
}
6358
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%sExtracting %s to %s...\n", cliui.Styles.Prompt, cliui.Styles.Field.Render(selectedTemplate.ID), cliui.Styles.Keyword.Render(relPath))
64-
6559
err = os.MkdirAll(directory, 0700)
6660
if err != nil {
6761
return err
6862
}
69-
7063
err = provisionersdk.Untar(directory, archive)
7164
if err != nil {
7265
return err
7366
}
74-
75-
fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Inside that directory, get started by running:")
76-
fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("coder projects create"))+"\n")
77-
67+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Inside that directory, get started by running:")
68+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("coder projects create"))+"\n")
7869
return nil
7970
},
8071
}

cli/root.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"os"
66
"strings"
77

8-
"github.com/fatih/color"
8+
"github.com/charmbracelet/lipgloss"
99
"github.com/kirsle/configdir"
1010
"github.com/mattn/go-isatty"
1111
"github.com/spf13/cobra"
@@ -33,32 +33,26 @@ func Root() *cobra.Command {
3333
▄▄██▀▀█▄▄▄ ██ ██ █▀▀█ ▐█▀▀██ ▄█▀▀█ █▀▀
3434
█▌ ▄▌ ▐█ █▌ ▀█▄▄▄█▌ █ █ ▐█ ██ ██▀▀ █
3535
██████▀▄█ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀
36-
` + color.New(color.Underline).Sprint("Self-hosted developer workspaces on your infra") + `
36+
` + lipgloss.NewStyle().Underline(true).Render("Self-hosted developer workspaces on your infra") + `
3737
3838
`,
39-
Example: `
40-
- Create a project for developers to create workspaces
39+
Example: cliui.Styles.Paragraph.Render(`Start Coder in "dev" mode. This dev-mode requires no further setup, and your local `+cliui.Styles.Code.Render("coder")+` CLI will be authenticated to talk to it. This makes it easy to experiment with Coder.`) + `
4140
42-
` + color.New(color.FgHiMagenta).Sprint("$ coder projects create <directory>") + `
41+
` + cliui.Styles.Code.Render("$ coder start --dev") + `
42+
` + cliui.Styles.Paragraph.Render("Get started by creating a project from an example.") + `
4343
44-
- Create a workspace for a specific project
45-
46-
` + color.New(color.FgHiMagenta).Sprint("$ coder workspaces create <project>") + `
47-
48-
- Maintain consistency by updating a workspace
49-
50-
` + color.New(color.FgHiMagenta).Sprint("$ coder workspaces update <workspace>"),
44+
` + cliui.Styles.Code.Render("$ coder projects init"),
5145
}
5246
// Customizes the color of headings to make subcommands
5347
// more visually appealing.
54-
header := color.New(color.FgHiBlack)
48+
header := cliui.Styles.Placeholder
5549
cmd.SetUsageTemplate(strings.NewReplacer(
56-
`Usage:`, header.Sprint("Usage:"),
57-
`Examples:`, header.Sprint("Examples:"),
58-
`Available Commands:`, header.Sprint("Commands:"),
59-
`Global Flags:`, header.Sprint("Global Flags:"),
60-
`Flags:`, header.Sprint("Flags:"),
61-
`Additional help topics:`, header.Sprint("Additional help:"),
50+
`Usage:`, header.Render("Usage:"),
51+
`Examples:`, header.Render("Examples:"),
52+
`Available Commands:`, header.Render("Commands:"),
53+
`Global Flags:`, header.Render("Global Flags:"),
54+
`Flags:`, header.Render("Flags:"),
55+
`Additional help topics:`, header.Render("Additional help:"),
6256
).Replace(cmd.UsageTemplate()))
6357

6458
cmd.AddCommand(

0 commit comments

Comments
 (0)