Skip to content

Commit 0025cb0

Browse files
tomkennedy513a-b
authored andcommitted
Add lifecycle flag to buildpacks and create-buildpack
Signed-off-by: Tom Kennedy <tom.kennedy@broadcom.com>
1 parent 841186f commit 0025cb0

13 files changed

+132
-57
lines changed

actor/v7action/buildpack.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ type Downloader interface {
2121
Download(url string, tmpDirPath string) (string, error)
2222
}
2323

24-
func (actor Actor) GetBuildpacks(labelSelector string) ([]resources.Buildpack, Warnings, error) {
24+
func (actor Actor) GetBuildpacks(labelSelector string, lifecycle string) ([]resources.Buildpack, Warnings, error) {
2525
queries := []ccv3.Query{ccv3.Query{Key: ccv3.OrderBy, Values: []string{ccv3.PositionOrder}}}
2626
if labelSelector != "" {
2727
queries = append(queries, ccv3.Query{Key: ccv3.LabelSelectorFilter, Values: []string{labelSelector}})
2828
}
2929

30+
if lifecycle != "" {
31+
queries = append(queries, ccv3.Query{Key: ccv3.LifecycleFilter, Values: []string{lifecycle}})
32+
}
33+
3034
buildpacks, warnings, err := actor.CloudControllerClient.GetBuildpacks(queries...)
3135

3236
return buildpacks, Warnings(warnings), err

actor/v7action/buildpack_test.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,11 @@ var _ = Describe("Buildpack", func() {
198198
warnings Warnings
199199
executeErr error
200200
labelSelector string
201+
lifecycle string
201202
)
202203

203204
JustBeforeEach(func() {
204-
buildpacks, warnings, executeErr = actor.GetBuildpacks(labelSelector)
205+
buildpacks, warnings, executeErr = actor.GetBuildpacks(labelSelector, lifecycle)
205206
})
206207

207208
It("calls CloudControllerClient.GetBuildpacks()", func() {
@@ -211,6 +212,7 @@ var _ = Describe("Buildpack", func() {
211212
When("a label selector is not provided", func() {
212213
BeforeEach(func() {
213214
labelSelector = ""
215+
lifecycle = ""
214216
})
215217
It("only passes through a OrderBy query to the CloudControllerClient", func() {
216218
positionQuery := ccv3.Query{Key: ccv3.OrderBy, Values: []string{ccv3.PositionOrder}}
@@ -265,6 +267,25 @@ var _ = Describe("Buildpack", func() {
265267
}))
266268
})
267269
})
270+
271+
When("lifecycle flag is provided", func() {
272+
BeforeEach(func() {
273+
ccBuildpacks := []resources.Buildpack{
274+
{Name: "cnb-1", Position: types.NullInt{Value: 1, IsSet: true}, Lifecycle: "cnb"},
275+
{Name: "cnb-2", Position: types.NullInt{Value: 2, IsSet: true}, Lifecycle: "cnb"},
276+
}
277+
fakeCloudControllerClient.GetBuildpacksReturns(
278+
ccBuildpacks,
279+
ccv3.Warnings{},
280+
nil)
281+
lifecycle = "cnb"
282+
})
283+
284+
It("passes the lifecycle as a query", func() {
285+
Expect(executeErr).ToNot(HaveOccurred())
286+
Expect(fakeCloudControllerClient.GetBuildpacksArgsForCall(0)).To(ContainElement(ccv3.Query{Key: ccv3.LifecycleFilter, Values: []string{"cnb"}}))
287+
})
288+
})
268289
})
269290

270291
Describe("CreateBuildpack", func() {

api/cloudcontroller/ccv3/query.go

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const (
1717
GUIDFilter QueryKey = "guids"
1818
// LabelSelectorFilter is a query parameter for listing objects by label
1919
LabelSelectorFilter QueryKey = "label_selector"
20+
// LifecycleFilter is a query parameter for listing buildpacks by lifecycle
21+
LifecycleFilter QueryKey = "lifecycle"
2022
// NameFilter is a query parameter for listing objects by name.
2123
NameFilter QueryKey = "names"
2224
// NoRouteFilter is a query parameter for skipping route creation and unmapping existing routes.

command/v7/actor.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ type Actor interface {
100100
GetApplicationTasks(appName string, sortOrder v7action.SortOrder) ([]resources.Task, v7action.Warnings, error)
101101
GetApplicationsByNamesAndSpace(appNames []string, spaceGUID string) ([]resources.Application, v7action.Warnings, error)
102102
GetBuildpackLabels(buildpackName string, buildpackStack string) (map[string]types.NullString, v7action.Warnings, error)
103-
GetBuildpacks(labelSelector string) ([]resources.Buildpack, v7action.Warnings, error)
103+
GetBuildpacks(labelSelector string, lifecycle string) ([]resources.Buildpack, v7action.Warnings, error)
104104
GetCurrentUser() (configv3.User, error)
105105
GetDefaultDomain(orgGUID string) (resources.Domain, v7action.Warnings, error)
106106
GetDetailedAppSummary(appName string, spaceGUID string, withObfuscatedValues bool) (v7action.DetailedApplicationSummary, v7action.Warnings, error)

command/v7/buildpacks_command.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import (
1010
type BuildpacksCommand struct {
1111
BaseCommand
1212

13-
usage interface{} `usage:"CF_NAME buildpacks [--labels SELECTOR]\n\nEXAMPLES:\n CF_NAME buildpacks\n CF_NAME buildpacks --labels 'environment in (production,staging),tier in (backend)'\n CF_NAME buildpacks --labels 'env=dev,!chargeback-code,tier in (backend,worker)'"`
13+
usage interface{} `usage:"CF_NAME buildpacks [--labels SELECTOR] [--lifecycle buildpack|cnb]\n\nEXAMPLES:\n CF_NAME buildpacks\n CF_NAME buildpacks --labels 'environment in (production,staging),tier in (backend)'\n CF_NAME buildpacks --labels 'env=dev,!chargeback-code,tier in (backend,worker)'\n CF_NAME buildpacks --lifecycle cnb"`
1414
relatedCommands interface{} `related_commands:"create-buildpack, delete-buildpack, rename-buildpack, update-buildpack"`
1515
Labels string `long:"labels" description:"Selector to filter buildpacks by labels"`
16+
Lifecycle string `long:"lifecycle" description:"Filter buildpacks by lifecycle ('buildpack' or 'cnb')"`
1617
}
1718

1819
func (cmd BuildpacksCommand) Execute(args []string) error {
@@ -31,7 +32,7 @@ func (cmd BuildpacksCommand) Execute(args []string) error {
3132
})
3233
cmd.UI.DisplayNewline()
3334

34-
buildpacks, warnings, err := cmd.Actor.GetBuildpacks(cmd.Labels)
35+
buildpacks, warnings, err := cmd.Actor.GetBuildpacks(cmd.Labels, cmd.Lifecycle)
3536
cmd.UI.DisplayWarnings(warnings)
3637
if err != nil {
3738
return err
@@ -48,8 +49,9 @@ func (cmd BuildpacksCommand) Execute(args []string) error {
4849
func (cmd BuildpacksCommand) displayTable(buildpacks []resources.Buildpack) {
4950
if len(buildpacks) > 0 {
5051
var keyValueTable = [][]string{
51-
{"position", "name", "stack", "enabled", "locked", "state", "filename"},
52+
{"position", "name", "stack", "enabled", "locked", "state", "filename", "lifecycle"},
5253
}
54+
5355
for _, buildpack := range buildpacks {
5456
keyValueTable = append(keyValueTable, []string{
5557
strconv.Itoa(buildpack.Position.Value),
@@ -59,6 +61,7 @@ func (cmd BuildpacksCommand) displayTable(buildpacks []resources.Buildpack) {
5961
strconv.FormatBool(buildpack.Locked.Value),
6062
buildpack.State,
6163
buildpack.Filename,
64+
buildpack.Lifecycle,
6265
})
6366
}
6467

command/v7/buildpacks_command_test.go

+42-18
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,22 @@ var _ = Describe("buildpacks Command", func() {
8787
})
8888

8989
It("passes the label selector to the actor", func() {
90-
labelSelector := fakeActor.GetBuildpacksArgsForCall(0)
90+
labelSelector, _ := fakeActor.GetBuildpacksArgsForCall(0)
9191
Expect(labelSelector).To(Equal("some-label-selector"))
9292
})
9393
})
9494

95+
When("the --lifecycle flag is used", func() {
96+
BeforeEach(func() {
97+
cmd.Lifecycle = "cnb"
98+
})
99+
100+
It("passes the lifecycle to the actor", func() {
101+
_, lifecycle := fakeActor.GetBuildpacksArgsForCall(0)
102+
Expect(lifecycle).To(Equal("cnb"))
103+
})
104+
})
105+
95106
When("getting buildpacks fails", func() {
96107
BeforeEach(func() {
97108
fakeActor.GetBuildpacksReturns(nil, v7action.Warnings{"some-warning-1", "some-warning-2"},
@@ -111,23 +122,35 @@ var _ = Describe("buildpacks Command", func() {
111122
BeforeEach(func() {
112123
buildpacks := []resources.Buildpack{
113124
{
114-
Name: "buildpack-1",
115-
Position: types.NullInt{Value: 1, IsSet: true},
116-
Enabled: types.NullBool{Value: true, IsSet: true},
117-
Locked: types.NullBool{Value: false, IsSet: true},
118-
State: constant.BuildpackReady,
119-
Filename: "buildpack-1.file",
120-
Stack: "buildpack-1-stack",
125+
Name: "buildpack-1",
126+
Position: types.NullInt{Value: 1, IsSet: true},
127+
Enabled: types.NullBool{Value: true, IsSet: true},
128+
Locked: types.NullBool{Value: false, IsSet: true},
129+
State: constant.BuildpackReady,
130+
Filename: "buildpack-1.file",
131+
Stack: "buildpack-1-stack",
132+
Lifecycle: "buildpack",
121133
},
122134

123135
{
124-
Name: "buildpack-2",
125-
Position: types.NullInt{Value: 2, IsSet: true},
126-
Enabled: types.NullBool{Value: false, IsSet: true},
127-
Locked: types.NullBool{Value: true, IsSet: true},
128-
State: constant.BuildpackAwaitingUpload,
129-
Filename: "buildpack-2.file",
130-
Stack: "",
136+
Name: "buildpack-2",
137+
Position: types.NullInt{Value: 2, IsSet: true},
138+
Enabled: types.NullBool{Value: false, IsSet: true},
139+
Locked: types.NullBool{Value: true, IsSet: true},
140+
State: constant.BuildpackAwaitingUpload,
141+
Filename: "buildpack-2.file",
142+
Stack: "",
143+
Lifecycle: "buildpack",
144+
},
145+
{
146+
Name: "cnb-1",
147+
Position: types.NullInt{Value: 1, IsSet: true},
148+
Enabled: types.NullBool{Value: true, IsSet: true},
149+
Locked: types.NullBool{Value: false, IsSet: true},
150+
State: constant.BuildpackReady,
151+
Filename: "cnb-1.cnb",
152+
Stack: "cnb-1-stack",
153+
Lifecycle: "cnb",
131154
},
132155
}
133156
fakeActor.GetBuildpacksReturns(buildpacks, v7action.Warnings{"some-warning-1", "some-warning-2"}, nil)
@@ -136,9 +159,10 @@ var _ = Describe("buildpacks Command", func() {
136159
Expect(executeErr).NotTo(HaveOccurred())
137160
Expect(testUI.Err).To(Say("some-warning-1"))
138161
Expect(testUI.Err).To(Say("some-warning-2"))
139-
Expect(testUI.Out).To(Say(`position\s+name\s+stack\s+enabled\s+locked\s+state\s+filename`))
140-
Expect(testUI.Out).To(Say(`1\s+buildpack-1\s+buildpack-1-stack\s+true\s+false\s+READY\s+buildpack-1.file`))
141-
Expect(testUI.Out).To(Say(`2\s+buildpack-2\s+false\s+true\s+AWAITING_UPLOAD\s+buildpack-2.file`))
162+
Expect(testUI.Out).To(Say(`position\s+name\s+stack\s+enabled\s+locked\s+state\s+filename\s+lifecycle`))
163+
Expect(testUI.Out).To(Say(`1\s+buildpack-1\s+buildpack-1-stack\s+true\s+false\s+READY\s+buildpack-1.file\s+buildpack`))
164+
Expect(testUI.Out).To(Say(`2\s+buildpack-2\s+false\s+true\s+AWAITING_UPLOAD\s+buildpack-2.file\s+buildpack`))
165+
Expect(testUI.Out).To(Say(`1\s+cnb-1\s+cnb-1-stack\s+true\s+false\s+READY\s+cnb-1.cnb\s+cnb`))
142166
})
143167
})
144168
When("there are no buildpacks", func() {

command/v7/create_buildpack_command.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ type CreateBuildpackCommand struct {
1818
BaseCommand
1919

2020
RequiredArgs flag.CreateBuildpackArgs `positional-args:"Yes"`
21-
usage interface{} `usage:"CF_NAME create-buildpack BUILDPACK PATH POSITION [--disable]\n\nTIP:\n Path should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest."`
21+
usage interface{} `usage:"CF_NAME create-buildpack BUILDPACK PATH POSITION [--disable]\n\nTIP:\n When using the 'buildpack' lifecycle type, Path should be a zip file, a url to a zip file, or a local directory. When using the 'cnb' lifecycle, Path should be a cnb file or gzipped oci image. Position is a positive integer, sets priority, and is sorted from lowest to highest."`
2222
relatedCommands interface{} `related_commands:"buildpacks, push"`
2323
Disable bool `long:"disable" description:"Disable the buildpack from being used for staging"`
24+
Lifecycle string `long:"lifecycle" description:"Lifecycle that the buildpack will use ('buildpack' or 'cnb')"`
2425

2526
ProgressBar v7action.SimpleProgressBar
2627
}
@@ -59,9 +60,10 @@ func (cmd CreateBuildpackCommand) Execute(args []string) error {
5960
}
6061

6162
createdBuildpack, warnings, err := cmd.Actor.CreateBuildpack(resources.Buildpack{
62-
Name: cmd.RequiredArgs.Buildpack,
63-
Position: types.NullInt{IsSet: true, Value: cmd.RequiredArgs.Position},
64-
Enabled: types.NullBool{IsSet: true, Value: !cmd.Disable},
63+
Name: cmd.RequiredArgs.Buildpack,
64+
Position: types.NullInt{IsSet: true, Value: cmd.RequiredArgs.Position},
65+
Enabled: types.NullBool{IsSet: true, Value: !cmd.Disable},
66+
Lifecycle: cmd.Lifecycle,
6567
})
6668
cmd.UI.DisplayWarnings(warnings)
6769
if err != nil {

command/v7/create_buildpack_command_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ var _ = Describe("create buildpack Command", func() {
9292
Expect(testUI.Out).To(Say(`Creating buildpack %s as the-user\.\.\.`, buildpackName))
9393
})
9494

95+
When("passing in buildpack lifecycle", func() {
96+
BeforeEach(func() {
97+
cmd.Lifecycle = "cnb"
98+
})
99+
100+
It("sets the correct lifecycle in the buildpack resource", func() {
101+
Expect(fakeActor.CreateBuildpackCallCount()).To(Equal(1))
102+
Expect(fakeActor.CreateBuildpackArgsForCall(0).Lifecycle).To(Equal("cnb"))
103+
})
104+
})
105+
95106
When("preparing the buildpack bits fails", func() {
96107
BeforeEach(func() {
97108
fakeActor.PrepareBuildpackBitsReturns("some/invalid/path", errors.New("some-prepare-bp-error"))

command/v7/update_buildpack_command.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type UpdateBuildpackCommand struct {
2727
BaseCommand
2828

2929
RequiredArgs flag.BuildpackName `positional-args:"Yes"`
30-
usage interface{} `usage:"CF_NAME update-buildpack BUILDPACK [-p PATH | -s STACK | --assign-stack NEW_STACK] [-i POSITION] [--rename NEW_NAME] [--enable|--disable] [--lock|--unlock]\n\nTIP:\nPath should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest.\n\nUse '--assign-stack' with caution. Associating a buildpack with a stack that it does not support may result in undefined behavior. Additionally, changing this association once made may require a local copy of the buildpack.\n\n"`
30+
usage interface{} `usage:"CF_NAME update-buildpack BUILDPACK [-p PATH | -s STACK | --assign-stack NEW_STACK] [-i POSITION] [--rename NEW_NAME] [--enable|--disable] [--lock|--unlock]\n\nTIP:\nWhen using the 'buildpack' lifecycle type, Path should be a zip file, a url to a zip file, or a local directory. When using the 'cnb' lifecycle, Path should be a cnb file or gzipped oci image. Position is a positive integer, sets priority, and is sorted from lowest to highest.\n\nUse '--assign-stack' with caution. Associating a buildpack with a stack that it does not support may result in undefined behavior. Additionally, changing this association once made may require a local copy of the buildpack.\n\n"`
3131
relatedCommands interface{} `related_commands:"buildpacks, create-buildpack, delete-buildpack"`
3232
NewStack string `long:"assign-stack" description:"Assign a stack to a buildpack that does not have a stack association"`
3333
Disable bool `long:"disable" description:"Disable the buildpack from being used for staging"`

command/v7/v7fakes/fake_actor.go

+10-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration/v7/global/create_buildpack_command_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var _ = Describe("create buildpack command", func() {
3434
Eventually(session).Should(Say("USAGE:"))
3535
Eventually(session).Should(Say(`cf create-buildpack BUILDPACK PATH POSITION \[--disable\]`))
3636
Eventually(session).Should(Say("TIP:"))
37-
Eventually(session).Should(Say("Path should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest."))
37+
Eventually(session).Should(Say("When using the 'buildpack' lifecycle type, Path should be a zip file, a url to a zip file, or a local directory. When using the 'cnb' lifecycle, Path should be a cnb file or gzipped oci image. Position is a positive integer, sets priority, and is sorted from lowest to highest."))
3838
Eventually(session).Should(Say("OPTIONS:"))
3939
Eventually(session).Should(Say(`--disable\s+Disable the buildpack from being used for staging`))
4040
Eventually(session).Should(Say("SEE ALSO:"))

integration/v7/global/update_buildpack_command_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var _ = Describe("update-buildpack command", func() {
3434
Eventually(session).Should(Say("USAGE:"))
3535
Eventually(session).Should(Say(regexp.QuoteMeta(`cf update-buildpack BUILDPACK [-p PATH | -s STACK | --assign-stack NEW_STACK] [-i POSITION] [--rename NEW_NAME] [--enable|--disable] [--lock|--unlock]`)))
3636
Eventually(session).Should(Say("TIP:"))
37-
Eventually(session).Should(Say("Path should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest.\n\n"))
37+
Eventually(session).Should(Say("When using the 'buildpack' lifecycle type, Path should be a zip file, a url to a zip file, or a local directory. When using the 'cnb' lifecycle, Path should be a cnb file or gzipped oci image. Position is a positive integer, sets priority, and is sorted from lowest to highest.\n\n"))
3838
Eventually(session).Should(Say("Use '--assign-stack' with caution. Associating a buildpack with a stack that it does not support may result in undefined behavior. Additionally, changing this association once made may require a local copy of the buildpack.\n\n"))
3939
Eventually(session).Should(Say("OPTIONS:"))
4040
Eventually(session).Should(Say(`--assign-stack\s+Assign a stack to a buildpack that does not have a stack association`))

0 commit comments

Comments
 (0)