Skip to content
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
6 changes: 3 additions & 3 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ builds:
binary: bin/bk
main: ./cmd/bk
ldflags:
- -s -w -X github.com/buildkite/cli/v3/internal/build.Version={{.Version}}
- -s -w -X github.com/buildkite/cli/v3/internal/version.Version={{.Version}}

- id: linux
goos: [linux]
Expand All @@ -28,15 +28,15 @@ builds:
binary: bin/bk
main: ./cmd/bk
ldflags:
- -s -w -X github.com/buildkite/cli/v3/internal/build.Version={{.Version}}
- -s -w -X github.com/buildkite/cli/v3/internal/version.Version={{.Version}}

- id: windows
goos: [windows]
goarch: ['386', amd64, arm64]
binary: bin/bk
main: ./cmd/bk
ldflags:
- -s -w -X github.com/buildkite/cli/v3/internal/build.Version={{.Version}}
- -s -w -X github.com/buildkite/cli/v3/internal/version.Version={{.Version}}

archives:
- id: macos-archive
Expand Down
4 changes: 2 additions & 2 deletions cmd/bk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"os"

"github.com/buildkite/cli/v3/internal/build"
"github.com/buildkite/cli/v3/internal/version"
"github.com/buildkite/cli/v3/pkg/cmd/factory"
"github.com/buildkite/cli/v3/pkg/cmd/root"
)
Expand All @@ -17,7 +17,7 @@ func main() {

func mainRun() int {
ctx := context.Background()
f := factory.New(build.Version)
f := factory.New(version.Version)

rootCmd, err := root.NewCmdRoot(f)
if err != nil {
Expand Down
7 changes: 5 additions & 2 deletions internal/build/build.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package build

// Version is dynamically set at build time through ldflags
var Version = "DEV"
type Build struct {
Organization string
Pipeline string
BuildNumber string
}
9 changes: 0 additions & 9 deletions internal/build/resolver.go

This file was deleted.

44 changes: 44 additions & 0 deletions internal/build/resolver/resolver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package resolver

import (
"context"
"errors"

"github.com/buildkite/cli/v3/internal/build"
)

// BuildResolverFn is a function for finding a build. It returns an error if an irrecoverable scenario happens and
// should halt execution. Otherwise, if the resolver does not find a build, it should return (nil, nil) to indicate
// this. ie. no error occurred, but no build was found either
type BuildResolverFn func(context.Context) (*build.Build, error)

type AggregateResolver []BuildResolverFn

// Resolve is a BuildResolverFn that wraps up a list of resolvers to loop through and try find a build. The first build
// to be found will be returned. If none are found, it won't return an error to match the expectation of a
// BuildResolverFn
//
// This is safe to call multiple times, the same result will be returned
func (ar AggregateResolver) Resolve(ctx context.Context) (*build.Build, error) {
for _, resolve := range ar {
b, err := resolve(ctx)
if err != nil {
return nil, err
}
if b != nil {
return b, nil
}
}

return nil, nil
}

// NewAggregateResolver creates an AggregateResolver from a list of BuildResolverFn, appending a final resolver for
// capturing the case that no build is found by any resolver
func NewAggregateResolver(resolvers ...BuildResolverFn) AggregateResolver {
return append(resolvers, errorResolver)
}

func errorResolver(context.Context) (*build.Build, error) {
return nil, errors.New("Failed to find a build.")
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package build
package resolver

import (
"context"
"fmt"
"regexp"

"github.com/buildkite/cli/v3/internal/build"
)

func ResolveFromURL(args []string) build.BuildResolverFn {
return func() (*build.Build, error) {
func ResolveFromURL(args []string) BuildResolverFn {
return func(context.Context) (*build.Build, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eg, if this resolver needed to know the pipeline to be able to resolve the build (ie thinking "most recent build on a branch for a pipeline"), we would bind in a PipelineResolverFn here for the function to use. The signature of the build resolver would remain the same and we don't need to expose that dependency to other resolvers that may not need it (like this one)

Copy link
Contributor Author

@jradtilbrook jradtilbrook May 2, 2024

Choose a reason for hiding this comment

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

The API request that is made to determine the "most recent build" would also make use of the context passed in so that it could cancel the request

if len(args) != 1 {
return nil, fmt.Errorf("Incorrect number of arguments, expected 1, got %d", len(args))
}
Expand Down
3 changes: 2 additions & 1 deletion internal/pipeline/resolver/cli.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver

import (
"context"
"fmt"
"net/url"
"strings"
Expand All @@ -10,7 +11,7 @@ import (
)

func ResolveFromPositionalArgument(args []string, index int, conf *config.Config) PipelineResolverFn {
return func() (*pipeline.Pipeline, error) {
return func(context.Context) (*pipeline.Pipeline, error) {
// if args does not have values, skip this resolver
if len(args) < 1 {
return nil, nil
Expand Down
5 changes: 3 additions & 2 deletions internal/pipeline/resolver/cli_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver_test

import (
"context"
"testing"

"github.com/buildkite/cli/v3/internal/config"
Expand Down Expand Up @@ -39,7 +40,7 @@ func TestParsePipelineArg(t *testing.T) {
Organization: "testing",
}
f := resolver.ResolveFromPositionalArgument([]string{testcase.url}, 0, &c)
pipeline, err := f()
pipeline, err := f(context.Background())
if err != nil {
t.Error(err)
}
Expand All @@ -59,7 +60,7 @@ func TestParsePipelineArg(t *testing.T) {
Organization: "testing",
}
f := resolver.ResolveFromPositionalArgument([]string{"https://buildkite.com/"}, 0, &c)
pipeline, err := f()
pipeline, err := f(context.Background())
if err == nil {
t.Error("Should have failed parsing pipeline")
}
Expand Down
4 changes: 3 additions & 1 deletion internal/pipeline/resolver/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package resolver

import (
"context"

"github.com/buildkite/cli/v3/internal/config"
"github.com/buildkite/cli/v3/internal/pipeline"
)

func ResolveFromConfig(c *config.LocalConfig) PipelineResolverFn {
return func() (*pipeline.Pipeline, error) {
return func(context.Context) (*pipeline.Pipeline, error) {

var pipelines []string
var defaultPipeline string
Expand Down
5 changes: 3 additions & 2 deletions internal/pipeline/resolver/config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver

import (
"context"
"testing"

"github.com/buildkite/cli/v3/internal/config"
Expand All @@ -14,7 +15,7 @@ func TestResolvePipelineFromConfig(t *testing.T) {
}

resolve := ResolveFromConfig(&l)
selected, err := resolve()
selected, err := resolve(context.Background())
if err != nil {
t.Errorf("failed to resolve from config")
}
Expand All @@ -33,7 +34,7 @@ func TestResolvePipelineFromConfig(t *testing.T) {
}

resolve := ResolveFromConfig(&l)
selected, err := resolve()
selected, err := resolve(context.Background())
if err != nil {
t.Errorf("failed to resolve from config")
}
Expand Down
3 changes: 2 additions & 1 deletion internal/pipeline/resolver/path.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver

import (
"context"
"strings"

"github.com/buildkite/cli/v3/internal/pipeline"
Expand All @@ -9,7 +10,7 @@ import (
)

func ResolveFromPath(path string, org string, client *buildkite.Client) PipelineResolverFn {
return func() (*pipeline.Pipeline, error) {
return func(context.Context) (*pipeline.Pipeline, error) {
pipelines, err := resolveFromPath(path, org, client)
if err != nil {
return nil, err
Expand Down
11 changes: 7 additions & 4 deletions internal/pipeline/resolver/resolver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver

import (
"context"
"errors"

"github.com/buildkite/cli/v3/internal/pipeline"
Expand All @@ -9,16 +10,18 @@ import (
// PipelineResolverFn is a function for the purpose of finding a pipeline. It returns an error if an irrecoverable
// scenario happens and should halt execution. Otherwise if the resolver does not find a pipeline, it should return
// (nil, nil) to indicate this. ie. no error occurred, but no pipeline was found either.
type PipelineResolverFn func() (*pipeline.Pipeline, error)
type PipelineResolverFn func(context.Context) (*pipeline.Pipeline, error)

type AggregateResolver []PipelineResolverFn

// Resolve is a PipelineResolverFn that wraps up a list of resolvers to loop through to try find a pipeline. The first
// pipeline that is found will be returned, if none are found if won't return an error to match the expectation of a
// PipelineResolveFn
func (pr AggregateResolver) Resolve() (*pipeline.Pipeline, error) {
//
// This is safe to call multiple times. The same result will be returned.
func (pr AggregateResolver) Resolve(ctx context.Context) (*pipeline.Pipeline, error) {
for _, resolve := range pr {
p, err := resolve()
p, err := resolve(ctx)
if err != nil {
return nil, err
}
Expand All @@ -37,6 +40,6 @@ func NewAggregateResolver(resolvers ...PipelineResolverFn) AggregateResolver {
return append(resolvers, errorResolver)
}

func errorResolver() (*pipeline.Pipeline, error) {
func errorResolver(context.Context) (*pipeline.Pipeline, error) {
return nil, errors.New("Failed to resolve a pipeline.")
}
9 changes: 5 additions & 4 deletions internal/pipeline/resolver/resolver_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resolver_test

import (
"context"
"testing"

"github.com/buildkite/cli/v3/internal/pipeline"
Expand All @@ -14,11 +15,11 @@ func TestAggregateResolver(t *testing.T) {
t.Parallel()

agg := resolver.AggregateResolver{
func() (*pipeline.Pipeline, error) { return nil, nil },
func() (*pipeline.Pipeline, error) { return &pipeline.Pipeline{Name: "test"}, nil },
func(context.Context) (*pipeline.Pipeline, error) { return nil, nil },
func(context.Context) (*pipeline.Pipeline, error) { return &pipeline.Pipeline{Name: "test"}, nil },
}

p, err := agg.Resolve()
p, err := agg.Resolve(context.Background())

if p.Name != "test" {
t.Fatalf("Resolve function did not return expected value: %s", p.Name)
Expand All @@ -33,7 +34,7 @@ func TestAggregateResolver(t *testing.T) {

agg := resolver.AggregateResolver{}

p, err := agg.Resolve()
p, err := agg.Resolve(context.Background())

if p != nil && err != nil {
t.Fatal("Resolve did not return nil")
Expand Down
4 changes: 4 additions & 0 deletions internal/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package version

// Version is dynamically set at build time through ldflags
var Version = "DEV"
3 changes: 2 additions & 1 deletion pkg/cmd/build/cancel.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package build

import (
"context"
"fmt"

"github.com/MakeNowJust/heredoc"
Expand Down Expand Up @@ -36,7 +37,7 @@ func NewCmdBuildCancel(f *factory.Factory) *cobra.Command {
)
var pipeline pipeline.Pipeline
r := io.NewPendingCommand(func() tea.Msg {
p, err := resolvers.Resolve()
p, err := resolvers.Resolve(context.Background())
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/build/new.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package build

import (
"context"
"fmt"

"github.com/MakeNowJust/heredoc"
Expand Down Expand Up @@ -39,7 +40,7 @@ func NewCmdBuildNew(f *factory.Factory) *cobra.Command {
)
var pipeline pipeline.Pipeline
r := io.NewPendingCommand(func() tea.Msg {
p, err := resolvers.Resolve()
p, err := resolvers.Resolve(context.Background())
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/build/rebuild.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package build

import (
"context"
"fmt"

"github.com/MakeNowJust/heredoc"
Expand Down Expand Up @@ -36,7 +37,7 @@ func NewCmdBuildRebuild(f *factory.Factory) *cobra.Command {
)
var pipeline pipeline.Pipeline
r := io.NewPendingCommand(func() tea.Msg {
p, err := resolvers.Resolve()
p, err := resolvers.Resolve(context.Background())
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/build/view.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package build

import (
"context"
"fmt"
"time"

Expand Down Expand Up @@ -47,7 +48,7 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command {
var pipeline pipeline.Pipeline

r := io.NewPendingCommand(func() tea.Msg {
p, err := resolvers.Resolve()
p, err := resolvers.Resolve(context.Background())
if err != nil {
return err
}
Expand Down