Skip to content

Commit

Permalink
feat: add list build information command (#366)
Browse files Browse the repository at this point in the history
* chore: update go client to latest

* feat: add list build information command

* chore: update output

* chore: fix merge issue

* chore: mention no commits/work items if none exist

* chore: add some additional examples

* chore: update description for latest flag

* chore: update description for filter flag to make it clearer how we filter
  • Loading branch information
hnrkndrssn authored Jul 11, 2024
1 parent e56c4cc commit 0a17e9f
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 1 deletion.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/AlecAivazis/survey/v2 v2.3.6
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/OctopusDeploy/go-octodiff v1.0.0
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.0
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.1
github.com/bmatcuk/doublestar/v4 v4.4.0
github.com/briandowns/spinner v1.19.0
github.com/google/uuid v1.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ github.com/OctopusDeploy/go-octopusdeploy/v2 v2.45.0 h1:eTNAHSimCL5d0vTawIEB7TZJ
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.45.0/go.mod h1:ggvOXzMnq+w0pLg6C9zdjz6YBaHfO3B3tqmmB7JQdaw=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.0 h1:B91TiQolB939nCCMDJ+EUUnNqDUvvInvC1bEIqrXkBo=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.0/go.mod h1:ggvOXzMnq+w0pLg6C9zdjz6YBaHfO3B3tqmmB7JQdaw=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.1 h1:Z9LH289a46I5y1W9gQpr/h1t8fdNInNy/KJS1I8NCv0=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.46.1/go.mod h1:ggvOXzMnq+w0pLg6C9zdjz6YBaHfO3B3tqmmB7JQdaw=
github.com/bmatcuk/doublestar/v4 v4.4.0 h1:LmAwNwhjEbYtyVLzjcP/XeVw4nhuScHGkF/XWXnvIic=
github.com/bmatcuk/doublestar/v4 v4.4.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/briandowns/spinner v1.19.0 h1:s8aq38H+Qju89yhp89b4iIiMzMm8YN3p6vGpwyh/a8E=
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/buildinformation/build-information.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package buildinformation
import (
"fmt"

cmdList "github.com/OctopusDeploy/cli/pkg/cmd/buildinformation/list"
cmdUpload "github.com/OctopusDeploy/cli/pkg/cmd/buildinformation/upload"
cmdView "github.com/OctopusDeploy/cli/pkg/cmd/buildinformation/view"
"github.com/OctopusDeploy/cli/pkg/constants"
Expand All @@ -24,6 +25,7 @@ func NewCmdBuildInformation(f factory.Factory) *cobra.Command {
}

cmd.AddCommand(cmdView.NewCmdView(f))
cmd.AddCommand(cmdList.NewCmdList(f))
cmd.AddCommand(cmdUpload.NewCmdUpload(f))
return cmd
}
176 changes: 176 additions & 0 deletions pkg/cmd/buildinformation/list/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package list

import (
"fmt"
"strconv"
"strings"

"github.com/MakeNowJust/heredoc/v2"
"github.com/OctopusDeploy/cli/pkg/apiclient"
"github.com/OctopusDeploy/cli/pkg/cmd/buildinformation/shared"
"github.com/OctopusDeploy/cli/pkg/constants"
"github.com/OctopusDeploy/cli/pkg/factory"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/cli/pkg/util/flag"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/buildinformation"
"github.com/spf13/cobra"
)

const (
FlagLatest = "latest"
FlagFilter = "filter"
FlagPackageId = "package-id"
)

type ListFlags struct {
Latest *flag.Flag[bool]
Filter *flag.Flag[string]
PackageId *flag.Flag[string]
}

func NewListFlags() *ListFlags {
return &ListFlags{
Latest: flag.New[bool](FlagLatest, false),
Filter: flag.New[string](FlagFilter, false),
PackageId: flag.New[string](FlagPackageId, false),
}
}

func NewCmdList(f factory.Factory) *cobra.Command {
listFlags := NewListFlags()

cmd := &cobra.Command{
Use: "List",
Short: "List build information",
Long: "List build information in Octopus Deploy",
Example: heredoc.Docf(`
$ %[1]s build-information list
$ %[1]s build-information ls
$ %[1]s build-info list
$ %[1]s build-info ls --package-id ThePackage
$ %[1]s build-info ls --package-id ThePackage --filter 1.2.3
`, constants.ExecutableName),
Aliases: []string{"ls"},
RunE: func(cmd *cobra.Command, args []string) error {
return listRun(cmd, f, listFlags)
},
}

flags := cmd.Flags()
flags.BoolVarP(&listFlags.Latest.Value, listFlags.Latest.Name, "", false, "only return the latest build information according to SemVer")
flags.StringVarP(&listFlags.Filter.Value, listFlags.Filter.Name, "q", "", "filter build information by version that contains the filter")
flags.StringVarP(&listFlags.PackageId.Value, listFlags.PackageId.Name, "p", "", "filter build information by package id")

return cmd
}

func listRun(cmd *cobra.Command, f factory.Factory, listFlags *ListFlags) error {
octopus, err := f.GetSpacedClient(apiclient.NewRequester(cmd))
if err != nil {
return err
}

query := buildinformation.BuildInformationQuery{
Latest: listFlags.Latest.Value,
Filter: listFlags.Filter.Value,
PackageID: listFlags.PackageId.Value,
}

buildInfoResources, err := buildinformation.Get(octopus, f.GetCurrentSpace().ID, query)
if err != nil {
return err
}

allBuildInfo, err := buildInfoResources.GetAllPages(octopus.Sling())
if err != nil {
return err
}

return output.PrintArray(allBuildInfo, cmd, output.Mappers[*buildinformation.BuildInformation]{
Json: func(b *buildinformation.BuildInformation) any {
buildInfo := shared.BuildInfoAsJson{
Id: b.GetID(),
PackageId: b.PackageID,
Version: b.Version,
Branch: b.Branch,
BuildEnvironment: b.BuildEnvironment,
VcsCommitNumber: b.VcsCommitNumber,
VcsType: b.VcsType,
VcsRoot: b.VcsRoot,
}

if len(b.Commits) > 0 {
for _, c := range b.Commits {
buildInfo.Commits = append(buildInfo.Commits, &shared.CommitAsJson{Id: c.ID, Comment: c.Comment})
}
}

if len(b.WorkItems) > 0 {
for _, w := range b.WorkItems {
buildInfo.WorkItems = append(buildInfo.WorkItems, &shared.WorkItemAsJson{Id: w.ID, Source: w.Source, Description: w.Description})
}
}

return buildInfo
},
Table: output.TableDefinition[*buildinformation.BuildInformation]{
Header: []string{
"PACKAGE ID",
"VERSION",
"ENVIRONMENT",
"BUILD NO",
"BRANCH",
"COMMITS",
"WORKITEMS"},
Row: func(b *buildinformation.BuildInformation) []string {
return []string{
output.Bold(b.PackageID),
b.Version,
b.BuildEnvironment,
b.BuildNumber,
b.Branch,
strconv.Itoa(len(b.Commits)),
strconv.Itoa(len(b.WorkItems))}
},
},
Basic: func(b *buildinformation.BuildInformation) string {
var s strings.Builder

s.WriteString(fmt.Sprintf("%s %s %s\n", output.Bold(b.PackageID), b.Version, output.Dimf("(%s)", b.GetID())))

s.WriteString(output.Bold("\nBuild details\n"))
s.WriteString(output.Dim(fmt.Sprintf("Environment: %s\n", b.BuildEnvironment)))
s.WriteString(output.Dim(fmt.Sprintf("Branch: %s\n", b.Branch)))
s.WriteString(output.Dim(fmt.Sprintf("URL: %s\n", output.Blue(b.BuildURL))))

s.WriteString(output.Bold("\nVCS Details\n"))
s.WriteString(output.Dim(fmt.Sprintf("Type: %s\n", b.VcsType)))
s.WriteString(output.Dim(fmt.Sprintf("URL: %s\n", output.Blue(b.VcsRoot))))

s.WriteString(output.Bold("\nCommit details\n"))
s.WriteString(output.Dim(fmt.Sprintf("Hash: %s\n", b.VcsCommitNumber)))
s.WriteString(output.Dim(fmt.Sprintf("URL: %s\n", output.Blue(b.VcsCommitURL))))
if len(b.Commits) > 0 {
for _, commit := range b.Commits {
s.WriteString(fmt.Sprintf("%s %s\n", output.Dim(commit.ID[0:8]), commit.Comment))
}
} else {
s.WriteString("No commits included\n")
}

s.WriteString(output.Bold("\nWork items\n"))
if len(b.WorkItems) > 0 {
if b.IssueTrackerName != "" {
s.WriteString(output.Dim(fmt.Sprintf("Issue tracker: %s\n", b.IssueTrackerName)))
}
for _, workItem := range b.WorkItems {
s.WriteString(fmt.Sprintf("%s %s\n", output.Dim(workItem.ID), workItem.Description))
}
} else {
s.WriteString("No work items included\n")
}

return s.String()
},
})
}

0 comments on commit 0a17e9f

Please sign in to comment.