github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/package_buildpack_test.go (about) 1 package commands_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 8 "github.com/heroku/color" 9 "github.com/pkg/errors" 10 "github.com/sclevine/spec" 11 "github.com/sclevine/spec/report" 12 "github.com/spf13/cobra" 13 14 pubbldpkg "github.com/buildpacks/pack/buildpackage" 15 "github.com/buildpacks/pack/internal/commands" 16 "github.com/buildpacks/pack/internal/commands/fakes" 17 "github.com/buildpacks/pack/internal/config" 18 "github.com/buildpacks/pack/pkg/dist" 19 "github.com/buildpacks/pack/pkg/image" 20 "github.com/buildpacks/pack/pkg/logging" 21 h "github.com/buildpacks/pack/testhelpers" 22 ) 23 24 func TestPackageBuildpackCommand(t *testing.T) { 25 color.Disable(true) 26 defer color.Disable(false) 27 spec.Run(t, "PackageBuildpackCommand", testPackageBuildpackCommand, spec.Parallel(), spec.Report(report.Terminal{})) 28 } 29 30 func testPackageBuildpackCommand(t *testing.T, when spec.G, it spec.S) { 31 when("PackageBuildpack#Execute", func() { 32 when("valid package config", func() { 33 it("prints deprecation warning", func() { 34 var outBuf bytes.Buffer 35 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 36 cmd := packageBuildpackCommand(withLogger(logger)) 37 h.AssertNil(t, cmd.Execute()) 38 h.AssertContains(t, outBuf.String(), "Warning: Command 'pack package-buildpack' has been deprecated, please use 'pack buildpack package' instead") 39 }) 40 41 it("reads package config from the configured path", func() { 42 fakePackageConfigReader := fakes.NewFakePackageConfigReader() 43 expectedPackageConfigPath := "/path/to/some/file" 44 45 packageBuildpackCommand := packageBuildpackCommand( 46 withPackageConfigReader(fakePackageConfigReader), 47 withPackageConfigPath(expectedPackageConfigPath), 48 ) 49 50 err := packageBuildpackCommand.Execute() 51 h.AssertNil(t, err) 52 53 h.AssertEq(t, fakePackageConfigReader.ReadCalledWithArg, expectedPackageConfigPath) 54 }) 55 56 it("creates package with correct image name", func() { 57 fakeBuildpackPackager := &fakes.FakeBuildpackPackager{} 58 59 packageBuildpackCommand := packageBuildpackCommand( 60 withImageName("my-specific-image"), 61 withBuildpackPackager(fakeBuildpackPackager), 62 ) 63 64 err := packageBuildpackCommand.Execute() 65 h.AssertNil(t, err) 66 67 receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions 68 69 h.AssertEq(t, receivedOptions.Name, "my-specific-image") 70 }) 71 72 it("creates package with config returned by the reader", func() { 73 fakeBuildpackPackager := &fakes.FakeBuildpackPackager{} 74 75 myConfig := pubbldpkg.Config{ 76 Buildpack: dist.BuildpackURI{URI: "test"}, 77 } 78 79 packageBuildpackCommand := packageBuildpackCommand( 80 withBuildpackPackager(fakeBuildpackPackager), 81 withPackageConfigReader(fakes.NewFakePackageConfigReader(whereReadReturns(myConfig, nil))), 82 ) 83 84 err := packageBuildpackCommand.Execute() 85 h.AssertNil(t, err) 86 87 receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions 88 89 h.AssertEq(t, receivedOptions.Config, myConfig) 90 }) 91 92 when("pull-policy", func() { 93 var ( 94 outBuf bytes.Buffer 95 cmd *cobra.Command 96 args []string 97 fakeBuildpackPackager *fakes.FakeBuildpackPackager 98 ) 99 100 it.Before(func() { 101 logger := logging.NewLogWithWriters(&outBuf, &outBuf) 102 fakeBuildpackPackager = &fakes.FakeBuildpackPackager{} 103 104 cmd = packageBuildpackCommand(withLogger(logger), withBuildpackPackager(fakeBuildpackPackager)) 105 args = []string{ 106 "some-image-name", 107 "--config", "/path/to/some/file", 108 } 109 }) 110 111 it("pull-policy=never sets policy", func() { 112 args = append(args, "--pull-policy", "never") 113 cmd.SetArgs(args) 114 115 err := cmd.Execute() 116 h.AssertNil(t, err) 117 118 receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions 119 h.AssertEq(t, receivedOptions.PullPolicy, image.PullNever) 120 }) 121 122 it("pull-policy=always sets policy", func() { 123 args = append(args, "--pull-policy", "always") 124 cmd.SetArgs(args) 125 126 err := cmd.Execute() 127 h.AssertNil(t, err) 128 129 receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions 130 h.AssertEq(t, receivedOptions.PullPolicy, image.PullAlways) 131 }) 132 it("takes precedence over a configured pull policy", func() { 133 logger := logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}) 134 configReader := fakes.NewFakePackageConfigReader() 135 buildpackPackager := &fakes.FakeBuildpackPackager{} 136 clientConfig := config.Config{PullPolicy: "if-not-present"} 137 138 command := commands.PackageBuildpack(logger, clientConfig, buildpackPackager, configReader) 139 command.SetArgs([]string{ 140 "some-image-name", 141 "--config", "/path/to/some/file", 142 "--pull-policy", 143 "never", 144 }) 145 146 err := command.Execute() 147 h.AssertNil(t, err) 148 149 receivedOptions := buildpackPackager.CreateCalledWithOptions 150 h.AssertEq(t, receivedOptions.PullPolicy, image.PullNever) 151 }) 152 }) 153 when("configured pull policy", func() { 154 it("uses the configured pull policy", func() { 155 logger := logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}) 156 configReader := fakes.NewFakePackageConfigReader() 157 buildpackPackager := &fakes.FakeBuildpackPackager{} 158 clientConfig := config.Config{PullPolicy: "never"} 159 160 command := commands.PackageBuildpack(logger, clientConfig, buildpackPackager, configReader) 161 command.SetArgs([]string{ 162 "some-image-name", 163 "--config", "/path/to/some/file", 164 }) 165 166 err := command.Execute() 167 h.AssertNil(t, err) 168 169 receivedOptions := buildpackPackager.CreateCalledWithOptions 170 h.AssertEq(t, receivedOptions.PullPolicy, image.PullNever) 171 }) 172 }) 173 }) 174 }) 175 176 when("invalid flags", func() { 177 when("both --publish and --pull-policy never flags are specified", func() { 178 it("errors with a descriptive message", func() { 179 logger := logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}) 180 configReader := fakes.NewFakePackageConfigReader() 181 buildpackPackager := &fakes.FakeBuildpackPackager{} 182 clientConfig := config.Config{} 183 184 command := commands.PackageBuildpack(logger, clientConfig, buildpackPackager, configReader) 185 command.SetArgs([]string{ 186 "some-image-name", 187 "--config", "/path/to/some/file", 188 "--publish", 189 "--pull-policy", 190 "never", 191 }) 192 193 err := command.Execute() 194 h.AssertNotNil(t, err) 195 h.AssertError(t, err, "--publish and --pull-policy never cannot be used together. The --publish flag requires the use of remote images.") 196 }) 197 }) 198 199 it("logs an error and exits when package toml is invalid", func() { 200 outBuf := &bytes.Buffer{} 201 expectedErr := errors.New("it went wrong") 202 203 packageBuildpackCommand := packageBuildpackCommand( 204 withLogger(logging.NewLogWithWriters(outBuf, outBuf)), 205 withPackageConfigReader( 206 fakes.NewFakePackageConfigReader(whereReadReturns(pubbldpkg.Config{}, expectedErr)), 207 ), 208 ) 209 210 err := packageBuildpackCommand.Execute() 211 h.AssertNotNil(t, err) 212 213 h.AssertContains(t, outBuf.String(), fmt.Sprintf("ERROR: reading config: %s", expectedErr)) 214 }) 215 216 when("package-config is specified", func() { 217 it("errors with a descriptive message", func() { 218 outBuf := &bytes.Buffer{} 219 220 config := &packageCommandConfig{ 221 logger: logging.NewLogWithWriters(outBuf, outBuf), 222 packageConfigReader: fakes.NewFakePackageConfigReader(), 223 buildpackPackager: &fakes.FakeBuildpackPackager{}, 224 225 imageName: "some-image-name", 226 configPath: "/path/to/some/file", 227 } 228 229 cmd := commands.PackageBuildpack(config.logger, config.clientConfig, config.buildpackPackager, config.packageConfigReader) 230 cmd.SetArgs([]string{config.imageName, "--package-config", config.configPath}) 231 232 err := cmd.Execute() 233 h.AssertError(t, err, "unknown flag: --package-config") 234 }) 235 }) 236 237 when("no config path is specified", func() { 238 it("creates a default config", func() { 239 config := &packageCommandConfig{ 240 logger: logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}), 241 packageConfigReader: fakes.NewFakePackageConfigReader(), 242 buildpackPackager: &fakes.FakeBuildpackPackager{}, 243 244 imageName: "some-image-name", 245 } 246 247 cmd := commands.PackageBuildpack(config.logger, config.clientConfig, config.buildpackPackager, config.packageConfigReader) 248 cmd.SetArgs([]string{config.imageName}) 249 250 err := cmd.Execute() 251 h.AssertNil(t, err) 252 253 receivedOptions := config.buildpackPackager.CreateCalledWithOptions 254 h.AssertEq(t, receivedOptions.Config.Buildpack.URI, ".") 255 }) 256 }) 257 258 when("--pull-policy unknown-policy", func() { 259 it("fails to run", func() { 260 logger := logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}) 261 configReader := fakes.NewFakePackageConfigReader() 262 buildpackPackager := &fakes.FakeBuildpackPackager{} 263 clientConfig := config.Config{} 264 265 command := commands.PackageBuildpack(logger, clientConfig, buildpackPackager, configReader) 266 command.SetArgs([]string{ 267 "some-image-name", 268 "--config", "/path/to/some/file", 269 "--pull-policy", 270 "unknown-policy", 271 }) 272 273 h.AssertError(t, command.Execute(), "parsing pull policy") 274 }) 275 }) 276 }) 277 } 278 279 func packageBuildpackCommand(ops ...packageCommandOption) *cobra.Command { 280 config := &packageCommandConfig{ 281 logger: logging.NewLogWithWriters(&bytes.Buffer{}, &bytes.Buffer{}), 282 packageConfigReader: fakes.NewFakePackageConfigReader(), 283 buildpackPackager: &fakes.FakeBuildpackPackager{}, 284 clientConfig: config.Config{}, 285 286 imageName: "some-image-name", 287 configPath: "/path/to/some/file", 288 } 289 290 for _, op := range ops { 291 op(config) 292 } 293 294 cmd := commands.PackageBuildpack(config.logger, config.clientConfig, config.buildpackPackager, config.packageConfigReader) 295 cmd.SetArgs([]string{config.imageName, "--config", config.configPath}) 296 297 return cmd 298 }