Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implement basic templates versions CLI #3145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 26, 2022
1 change: 1 addition & 0 deletions cli/templatelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func templateList() *cobra.Command {
)
cmd := &cobra.Command{
Use: "list",
Short: "List all the templates available for the organization",
Aliases: []string{"ls"},
RunE: func(cmd *cobra.Command, args []string) error {
client, err := createClient(cmd)
Expand Down
65 changes: 65 additions & 0 deletions cli/templatelist_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cli_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/coder/coder/cli/clitest"
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/pty/ptytest"
)

func TestTemplateList(t *testing.T) {
t.Parallel()
t.Run("ListTemplates", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user := coderdtest.CreateFirstUser(t, client)
firstVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, firstVersion.ID)
firstTemplate := coderdtest.CreateTemplate(t, client, user.OrganizationID, firstVersion.ID)

secondVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, secondVersion.ID)
secondTemplate := coderdtest.CreateTemplate(t, client, user.OrganizationID, secondVersion.ID)

cmd, root := clitest.New(t, "templates", "list")
clitest.SetupConfig(t, client, root)

pty := ptytest.New(t)
cmd.SetIn(pty.Input())
cmd.SetOut(pty.Output())

errC := make(chan error)
go func() {
errC <- cmd.Execute()
}()

require.NoError(t, <-errC)

pty.ExpectMatch(firstTemplate.Name)
pty.ExpectMatch(secondTemplate.Name)
})
t.Run("NoTemplates", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
coderdtest.CreateFirstUser(t, client)

cmd, root := clitest.New(t, "templates", "list")
clitest.SetupConfig(t, client, root)

pty := ptytest.New(t)
cmd.SetIn(pty.Input())
cmd.SetOut(pty.Output())

errC := make(chan error)
go func() {
errC <- cmd.Execute()
}()

require.NoError(t, <-errC)

pty.ExpectMatch("No templates found in testuser! Create one:")
})
}
81 changes: 77 additions & 4 deletions cli/templateversions.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,88 @@
package cli

import "github.com/spf13/cobra"
import (
"fmt"
"strings"

"github.com/google/uuid"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"golang.org/x/xerrors"

"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
)

func templateVersions() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "versions",
Short: "Manage different versions of the specified template",
Aliases: []string{"version"},
Example: formatExamples(
example{
Description: "List versions of a specific template",
Command: "coder templates versions list my-template",
},
),
Comment on lines +21 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should example be on the list subcommand? Probably ok in both spots?

}
cmd.AddCommand(
templateVersionsList(),
)

return cmd
}

func templateVersionsList() *cobra.Command {
return &cobra.Command{
Use: "list <template>",
Args: cobra.ExactArgs(1),
Short: "List all the versions of the specified template",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
client, err := createClient(cmd)
if err != nil {
return xerrors.Errorf("create client: %w", err)
}
organization, err := currentOrganization(cmd, client)
if err != nil {
return xerrors.Errorf("get current organization: %w", err)
}
template, err := client.TemplateByName(cmd.Context(), organization.ID, args[0])
if err != nil {
return xerrors.Errorf("get template by name: %w", err)
}
req := codersdk.TemplateVersionsByTemplateRequest{
TemplateID: template.ID,
}

versions, err := client.TemplateVersionsByTemplate(cmd.Context(), req)
if err != nil {
return xerrors.Errorf("get template versions by template: %w", err)
}
_, err = fmt.Fprintln(cmd.OutOrStdout(), displayTemplateVersions(template.ActiveVersionID, versions...))
return err
},
}
}

// coder template versions
// displayTemplateVersions will return a table displaying existing
// template versions for the specified template.
func displayTemplateVersions(activeVersionID uuid.UUID, templateVersions ...codersdk.TemplateVersion) string {
tableWriter := cliui.Table()
header := table.Row{
"Name", "Created At", "Created By", "Status", ""}
tableWriter.AppendHeader(header)
for _, templateVersion := range templateVersions {
var activeStatus = ""
if templateVersion.ID == activeVersionID {
activeStatus = cliui.Styles.Code.Render(cliui.Styles.Keyword.Render("Active"))
}
tableWriter.AppendRow(table.Row{
templateVersion.Name,
templateVersion.CreatedAt.Format("03:04:05 PM MST on Jan 2, 2006"),
templateVersion.CreatedByName,
strings.Title(string(templateVersion.Job.Status)),
activeStatus,
})
}
return tableWriter.Render()
}
41 changes: 41 additions & 0 deletions cli/templateversions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cli_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/coder/coder/cli/clitest"
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/pty/ptytest"
)

func TestTemplateVersions(t *testing.T) {
t.Parallel()
t.Run("ListVersions", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)

cmd, root := clitest.New(t, "templates", "versions", "list", template.Name)
clitest.SetupConfig(t, client, root)

pty := ptytest.New(t)
cmd.SetIn(pty.Input())
cmd.SetOut(pty.Output())

errC := make(chan error)
go func() {
errC <- cmd.Execute()
}()

require.NoError(t, <-errC)

pty.ExpectMatch(version.Name)
pty.ExpectMatch(version.CreatedByName)
pty.ExpectMatch("Active")
})
}