Skip to content
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

Add job list in build output #273

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
os.Exit(1)
}

if err = os.WriteFile(schemaFile, []byte(schema), 0644); err != nil {
if err = os.WriteFile(schemaFile, []byte(schema), 0o644); err != nil {
fmt.Println(err)
os.Exit(1)
}
Expand Down
6 changes: 4 additions & 2 deletions internal/agent/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import (
"github.com/pkg/browser"
)

var agentListStyle = lipgloss.NewStyle().Padding(1, 2)
var viewPortStyle = agentListStyle.Copy()
var (
agentListStyle = lipgloss.NewStyle().Padding(1, 2)
viewPortStyle = agentListStyle.Copy()
)

type AgentListModel struct {
agentList list.Model
Expand Down
1 change: 0 additions & 1 deletion internal/build/resolver/current_branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func TestResolveBuildFromCurrentBranch(t *testing.T) {
}
r := resolver.ResolveBuildFromCurrentBranch(testRepository(), pipelineResolver, &f)
b, err := r(context.Background())

if err != nil {
t.Fatal(err)
}
Expand Down
1 change: 0 additions & 1 deletion internal/build/resolver/user_builds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ func TestResolveBuildForCurrentUser(t *testing.T) {

r := resolver.ResolveBuildForCurrentUser("main", pipelineResolver, f)
build, err := r(context.Background())

if err != nil {
t.Fatal(err)
}
Expand Down
1 change: 0 additions & 1 deletion internal/build/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ func getBuildStateColor(state string) lipgloss.Color {
}

func renderBuildState(state string, blocked bool) string {

var stateIcon string
stateColor := getBuildStateColor(state)

Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func createIfNotExistsConfigDir() (string, error) {

configDir := filepath.Join(homeDir, ".config")
if _, err := os.Stat(configDir); errors.Is(err, os.ErrNotExist) {
err := os.Mkdir(configDir, 0755)
err := os.Mkdir(configDir, 0o755)
if err != nil {
return "", err
}
Expand Down
87 changes: 87 additions & 0 deletions internal/job/view.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package job

import (
"errors"
"fmt"
"log"
"time"

"github.com/buildkite/go-buildkite/v3/buildkite"
"github.com/charmbracelet/lipgloss"
)

func JobSummary(job *buildkite.Job) string {
jobName := getJobName(*job)
jobTotalTime, err := calculateTotalTime(job.StartedAt, job.FinishedAt)
if err != nil {
log.Fatal("Unable to calculate total job time", err)
}

jobInfo := fmt.Sprintf("%s %s (%s)", renderJobState(*job.State), jobName, lipgloss.NewStyle().Foreground(lipgloss.Color("#5A5A5A")).Render(jobTotalTime.String()))

summary := lipgloss.JoinVertical(lipgloss.Top,
lipgloss.NewStyle().Align(lipgloss.Left).Padding(0, 1).Render(),
lipgloss.NewStyle().Bold(true).Padding(0, 1).Render(jobInfo),
)
return summary
}

func getJobName(job buildkite.Job) string {
var jobName string

switch {
case job.Name != nil:
jobName = *job.Name
case job.Label != nil:
jobName = *job.Label
default:
jobName = *job.Command
}

return jobName
}

func renderJobState(state string) string {
var stateIcon string
stateColor := getJobStateColor(state)

switch state {
case "passed":
stateIcon = "✔"
case "running":
stateIcon = "▶"
case "failed", "failing":
stateIcon = "✖"
case "canceled":
stateIcon = "🚫"
case "canceling":
stateIcon = "🚫(cancelling...)"
default:
stateIcon = "❔"
}

return lipgloss.NewStyle().Foreground(stateColor).Render(stateIcon)
}

func getJobStateColor(state string) lipgloss.Color {
var stateColor lipgloss.Color
switch state {
case "passed":
stateColor = lipgloss.Color("#9dcc3a") // green
case "running":
stateColor = lipgloss.Color("#FF6E00")
case "failed", "failing":
stateColor = lipgloss.Color("#ff0000")
default:
stateColor = lipgloss.Color("#5A5A5A") // grey
}
return stateColor
}

func calculateTotalTime(startedAt, finishedAt *buildkite.Timestamp) (time.Duration, error) {
if startedAt == nil || finishedAt == nil {
return 0, errors.New("both startedAt and finishedAt must be non-nil")
}

return finishedAt.Time.Sub(startedAt.Time), nil
}
1 change: 0 additions & 1 deletion internal/pipeline/resolver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,4 @@ func TestResolvePipelineFromConfig(t *testing.T) {
t.Errorf("pipeline name should resolve temporarily to pipeline1")
}
})

}
1 change: 0 additions & 1 deletion internal/pipeline/resolver/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ func TestResolvePipelinesFromPath(t *testing.T) {
if len(pipelines) != 0 {
t.Errorf("Expected 0 pipeline, got %d", len(pipelines))
}

})

t.Run("one pipeline", func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/agent/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func RunStop(cmd *cobra.Command, args []string, opts *AgentStopOptions) error {
// use a wait group to ensure we exit the program after all agents have finished
var wg sync.WaitGroup
// this semaphore is used to limit how many concurrent API requests can be sent
var sem = semaphore.NewWeighted(opts.limit)
sem := semaphore.NewWeighted(opts.limit)

var agents []agent.StoppableAgent
// this command accepts either input from stdin or positional arguments (not both) in that order
Expand Down
1 change: 0 additions & 1 deletion pkg/cmd/agent/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ func NewCmdAgentView(f *factory.Factory) *cobra.Command {

l := io.NewPendingCommand(func() tea.Msg {
agentData, _, err := f.RestAPIClient.Agents.Get(org, id)

if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion pkg/cmd/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func NewCmdBuild(f *factory.Factory) *cobra.Command {
}

func openBuildInBrowser(openInWeb bool, webUrl string) error {

if openInWeb {
fmt.Printf("Opening %s in your browser\n", webUrl)
err := browser.OpenURL(webUrl)
Expand Down
1 change: 0 additions & 1 deletion pkg/cmd/build/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ func cancelBuild(org string, pipeline string, buildId string, web bool, f *facto
}

return io.PendingOutput(renderResult(fmt.Sprintf("Cancelling build: %s\n", *build.WebURL)))

}, fmt.Sprintf("Cancelling build #%s from pipeline %s", buildId, pipeline))

p := tea.NewProgram(l)
Expand Down
2 changes: 0 additions & 2 deletions pkg/cmd/build/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ func NewCmdBuildNew(f *factory.Factory) *cobra.Command {

func newBuild(org string, pipeline string, f *factory.Factory, message string, commit string, branch string, web bool) error {
l := io.NewPendingCommand(func() tea.Msg {

if len(branch) == 0 {
p, _, err := f.RestAPIClient.Pipelines.Get(org, pipeline)
if err != nil {
Expand All @@ -85,7 +84,6 @@ func newBuild(org string, pipeline string, f *factory.Factory, message string, c

return io.PendingOutput(lipgloss.JoinVertical(lipgloss.Top,
lipgloss.NewStyle().Padding(1, 1).Render(fmt.Sprintf("Build created: %s\n", *build.WebURL))))

}, fmt.Sprintf("Starting new build for %s", pipeline))
p := tea.NewProgram(l)
_, err := p.Run()
Expand Down
1 change: 0 additions & 1 deletion pkg/cmd/build/rebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ func rebuild(org string, pipeline string, buildId string, web bool, f *factory.F
}

return io.PendingOutput(renderResult(fmt.Sprintf("Build created: %s\n", *build.WebURL)))

}, fmt.Sprintf("Rerunning build #%s for pipeline %s", buildId, pipeline))

p := tea.NewProgram(l)
Expand Down
11 changes: 9 additions & 2 deletions pkg/cmd/build/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/buildkite/cli/v3/internal/build"
buildResolver "github.com/buildkite/cli/v3/internal/build/resolver"
"github.com/buildkite/cli/v3/internal/io"
"github.com/buildkite/cli/v3/internal/job"
pipelineResolver "github.com/buildkite/cli/v3/internal/pipeline/resolver"
"github.com/buildkite/cli/v3/pkg/cmd/factory"
"github.com/buildkite/go-buildkite/v3/buildkite"
Expand All @@ -35,8 +36,8 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command {
If the pipeline argument is omitted, it will be resolved using the current directory.
`),
RunE: func(cmd *cobra.Command, args []string) error {
var buildArtifacts = make([]buildkite.Artifact, 0)
var buildAnnotations = make([]buildkite.Annotation, 0)
buildArtifacts := make([]buildkite.Artifact, 0)
buildAnnotations := make([]buildkite.Annotation, 0)

pipelineRes := pipelineResolver.NewAggregateResolver(
pipelineResolver.ResolveFromPositionalArgument(args, 1, f.Config),
Expand Down Expand Up @@ -86,6 +87,12 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command {

// Obtain build summary and return
summary := build.BuildSummary(b)
if len(b.Jobs) > 0 {
summary += lipgloss.NewStyle().Bold(true).Padding(0, 1).Render("\nJobs")
for _, j := range b.Jobs {
summary += job.JobSummary(j)
}
}
if len(buildArtifacts) > 0 {
summary += lipgloss.NewStyle().Bold(true).Padding(0, 1).Render("\nArtifacts")
for _, a := range buildArtifacts {
Expand Down