├── .github ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── chore.md │ ├── config.yml │ └── feature.md ├── dependabot.yml ├── labeler.yml ├── pull_request_template.md ├── release-notes.yml └── workflows │ ├── actions │ └── release-notes │ │ ├── .gitignore │ │ ├── README.md │ │ ├── action.js │ │ ├── action.yml │ │ ├── dist │ │ └── index.js │ │ ├── local.js │ │ ├── package-lock.json │ │ ├── package.json │ │ └── release-notes.js │ ├── benchmark.yml │ ├── build.yml │ ├── check-latest-release.yml │ ├── codeql-analysis.yml │ ├── compatibility.yml │ ├── delivery-archlinux-git.yml │ ├── delivery-archlinux.yml │ ├── delivery-chocolatey.yml │ ├── delivery-docker.yml │ ├── delivery-homebrew.yml │ ├── delivery-release-dispatch.yml │ ├── delivery-ubuntu.yml │ ├── delivery │ ├── archlinux │ │ ├── README.md │ │ ├── pack-cli-bin │ │ │ └── PKGBUILD │ │ ├── pack-cli-git │ │ │ └── PKGBUILD │ │ ├── publish-package.sh │ │ └── test-install-package.sh │ ├── chocolatey │ │ ├── pack.nuspec │ │ └── tools │ │ │ └── VERIFICATION.txt │ ├── homebrew │ │ └── pack.rb │ └── ubuntu │ │ ├── 1_dependencies.sh │ │ ├── 2_create-ppa.sh │ │ ├── 3_test-ppa.sh │ │ ├── 4_upload-ppa.sh │ │ ├── debian │ │ ├── README │ │ ├── changelog │ │ ├── compat │ │ ├── control │ │ ├── copyright │ │ └── rules │ │ └── deliver.sh │ ├── privileged-pr-process.yml │ ├── release-merge.yml │ └── scripts │ ├── generate-release-event.sh │ ├── generate-workflow_dispatch-event.sh │ └── test-job.sh ├── .gitignore ├── .gitpod.yml ├── CODEOWNERS ├── CONTRIBUTING.md ├── DEVELOPMENT.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── RELEASE.md ├── acceptance ├── acceptance_test.go ├── assertions │ ├── image.go │ ├── lifecycle_output.go │ ├── output.go │ └── test_buildpack_output.go ├── buildpacks │ ├── archive_buildpack.go │ ├── folder_buildpack.go │ ├── manager.go │ ├── package_file_buildpack.go │ └── package_image_buildpack.go ├── config │ ├── asset_manager.go │ ├── github_asset_fetcher.go │ ├── input_configuration_manager.go │ ├── lifecycle_asset.go │ ├── pack_assets.go │ └── run_combination.go ├── invoke │ ├── pack.go │ └── pack_fixtures.go ├── managers │ └── image_manager.go ├── os │ ├── variables.go │ ├── variables_darwin.go │ ├── variables_darwin_arm64.go │ ├── variables_linux.go │ └── variables_windows.go ├── suite_manager.go ├── testconfig │ └── all.json └── testdata │ ├── mock_app.zip │ ├── mock_app │ ├── project.toml │ ├── run │ └── run.bat │ ├── mock_buildpacks │ ├── descriptor-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── internet-capable-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── meta-buildpack-dependency │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── meta-buildpack │ │ ├── buildpack.toml │ │ └── package.toml │ ├── multi-platform-buildpack │ │ ├── buildpack.toml │ │ ├── linux │ │ │ └── amd64 │ │ │ │ └── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ └── windows │ │ │ └── amd64 │ │ │ └── bin │ │ │ ├── build.bat │ │ │ └── detect.bat │ ├── nested-level-1-buildpack │ │ └── buildpack.toml │ ├── nested-level-2-buildpack │ │ └── buildpack.toml │ ├── noop-buildpack-2 │ │ ├── bin │ │ │ ├── build │ │ │ └── detect │ │ └── buildpack.toml │ ├── noop-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── not-in-builder-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── other-stack-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── read-env-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── read-env-extension │ │ ├── bin │ │ │ ├── detect │ │ │ └── generate │ │ └── extension.toml │ ├── read-volume-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── read-write-volume-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── simple-layers-buildpack-different-sha │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ ├── detect.bat │ │ │ └── extra_file.txt │ │ └── buildpack.toml │ ├── simple-layers-buildpack │ │ ├── bin │ │ │ ├── build │ │ │ ├── build.bat │ │ │ ├── detect │ │ │ └── detect.bat │ │ └── buildpack.toml │ ├── simple-layers-extension │ │ ├── bin │ │ │ ├── detect │ │ │ └── generate │ │ └── extension.toml │ └── simple-layers-parent-buildpack │ │ └── buildpack.toml │ ├── mock_stack │ ├── create-stack.sh │ ├── linux │ │ ├── build │ │ │ └── Dockerfile │ │ └── run │ │ │ └── Dockerfile │ └── windows │ │ ├── build │ │ └── Dockerfile │ │ └── run │ │ ├── Dockerfile │ │ └── server.go │ ├── pack_fixtures │ ├── .gitattributes │ ├── builder.toml │ ├── builder_extensions.toml │ ├── builder_multi_platform-no-targets.toml │ ├── builder_multi_platform.toml │ ├── inspect_0.20.0_builder_nested_depth_2_output.txt │ ├── inspect_0.20.0_builder_nested_output.txt │ ├── inspect_0.20.0_builder_nested_output_json.txt │ ├── inspect_0.20.0_builder_nested_output_toml.txt │ ├── inspect_0.20.0_builder_nested_output_yaml.txt │ ├── inspect_0.20.0_builder_output.txt │ ├── inspect_X.Y.Z_builder_output.txt │ ├── inspect_builder_nested_depth_2_output.txt │ ├── inspect_builder_nested_output.txt │ ├── inspect_builder_nested_output_json.txt │ ├── inspect_builder_nested_output_toml.txt │ ├── inspect_builder_nested_output_yaml.txt │ ├── inspect_builder_output.txt │ ├── inspect_buildpack_output.txt │ ├── inspect_image_local_output.json │ ├── inspect_image_local_output.toml │ ├── inspect_image_local_output.yaml │ ├── inspect_image_published_output.json │ ├── inspect_image_published_output.toml │ ├── inspect_image_published_output.yaml │ ├── invalid_builder.toml │ ├── invalid_package.toml │ ├── nested-level-1-buildpack_package.toml │ ├── nested-level-2-buildpack_package.toml │ ├── nested_builder.toml │ ├── package.toml │ ├── package_aggregate.toml │ ├── package_for_build_cmd.toml │ ├── package_multi_platform.toml │ ├── report_output.txt │ ├── simple-layers-buildpack-different-sha_package.toml │ └── simple-layers-buildpack_package.toml │ └── pack_previous_fixtures_overrides │ └── .gitkeep ├── benchmarks └── build_test.go ├── builder ├── buildpack_identifier.go ├── config_reader.go ├── config_reader_test.go └── detection_order.go ├── buildpackage ├── config_reader.go └── config_reader_test.go ├── cmd ├── cmd.go └── docker_init.go ├── codecov.yml ├── go.mod ├── go.sum ├── golangci.yaml ├── internal ├── build │ ├── container_ops.go │ ├── container_ops_test.go │ ├── docker.go │ ├── fakes │ │ ├── cache.go │ │ ├── fake_builder.go │ │ ├── fake_phase.go │ │ ├── fake_phase_factory.go │ │ └── fake_termui.go │ ├── lifecycle_execution.go │ ├── lifecycle_execution_test.go │ ├── lifecycle_executor.go │ ├── mount_paths.go │ ├── phase.go │ ├── phase_config_provider.go │ ├── phase_config_provider_test.go │ ├── phase_factory.go │ ├── phase_test.go │ └── testdata │ │ ├── fake-app.zip │ │ ├── fake-app │ │ ├── fake-app-file │ │ ├── fake-app-symlink │ │ └── file-to-ignore │ │ └── fake-lifecycle │ │ ├── Dockerfile │ │ ├── go.mod │ │ ├── go.sum │ │ └── phase.go ├── builder │ ├── builder.go │ ├── builder_test.go │ ├── descriptor.go │ ├── descriptor_test.go │ ├── detection_order_calculator.go │ ├── detection_order_calculator_test.go │ ├── fakes │ │ ├── fake_detection_calculator.go │ │ ├── fake_inspectable.go │ │ ├── fake_inspectable_fetcher.go │ │ ├── fake_label_manager.go │ │ └── fake_label_manager_factory.go │ ├── image_fetcher_wrapper.go │ ├── inspect.go │ ├── inspect_test.go │ ├── label_manager.go │ ├── label_manager_provider.go │ ├── label_manager_test.go │ ├── lifecycle.go │ ├── lifecycle_test.go │ ├── metadata.go │ ├── testdata │ │ └── lifecycle │ │ │ ├── platform-0.3 │ │ │ ├── lifecycle-v0.0.0-arch │ │ │ │ ├── analyzer │ │ │ │ ├── builder │ │ │ │ ├── creator │ │ │ │ ├── detector │ │ │ │ ├── exporter │ │ │ │ ├── launcher │ │ │ │ └── restorer │ │ │ └── lifecycle.toml │ │ │ └── platform-0.4 │ │ │ ├── lifecycle-v0.0.0-arch │ │ │ ├── analyzer │ │ │ ├── builder │ │ │ ├── creator │ │ │ ├── detector │ │ │ ├── exporter │ │ │ ├── launcher │ │ │ └── restorer │ │ │ └── lifecycle.toml │ ├── testmocks │ │ └── mock_lifecycle.go │ ├── trusted_builder.go │ ├── trusted_builder_test.go │ ├── version.go │ ├── version_test.go │ └── writer │ │ ├── factory.go │ │ ├── factory_test.go │ │ ├── human_readable.go │ │ ├── human_readable_test.go │ │ ├── json.go │ │ ├── json_test.go │ │ ├── shared_builder_test.go │ │ ├── structured_format.go │ │ ├── toml.go │ │ ├── toml_test.go │ │ ├── yaml.go │ │ └── yaml_test.go ├── commands │ ├── add_registry.go │ ├── add_registry_test.go │ ├── build.go │ ├── build_test.go │ ├── builder.go │ ├── builder_create.go │ ├── builder_create_test.go │ ├── builder_inspect.go │ ├── builder_inspect_test.go │ ├── builder_suggest.go │ ├── builder_suggest_test.go │ ├── builder_test.go │ ├── buildpack.go │ ├── buildpack_inspect.go │ ├── buildpack_inspect_test.go │ ├── buildpack_new.go │ ├── buildpack_new_test.go │ ├── buildpack_package.go │ ├── buildpack_package_test.go │ ├── buildpack_pull.go │ ├── buildpack_pull_test.go │ ├── buildpack_register.go │ ├── buildpack_register_test.go │ ├── buildpack_test.go │ ├── buildpack_yank.go │ ├── buildpack_yank_test.go │ ├── commands.go │ ├── completion.go │ ├── completion_test.go │ ├── config.go │ ├── config_default_builder.go │ ├── config_default_builder_test.go │ ├── config_experimental.go │ ├── config_experimental_test.go │ ├── config_lifecycle_image.go │ ├── config_lifecycle_image_test.go │ ├── config_pull_policy.go │ ├── config_pull_policy_test.go │ ├── config_registries.go │ ├── config_registries_default.go │ ├── config_registries_default_test.go │ ├── config_registries_test.go │ ├── config_registry_mirrors.go │ ├── config_registry_mirrors_test.go │ ├── config_run_image_mirrors.go │ ├── config_run_image_mirrors_test.go │ ├── config_test.go │ ├── config_trusted_builder.go │ ├── config_trusted_builder_test.go │ ├── create_builder.go │ ├── create_builder_test.go │ ├── download_sbom.go │ ├── download_sbom_test.go │ ├── extension.go │ ├── extension_inspect.go │ ├── extension_inspect_test.go │ ├── extension_new.go │ ├── extension_package.go │ ├── extension_package_test.go │ ├── extension_pull.go │ ├── extension_register.go │ ├── extension_test.go │ ├── extension_yank.go │ ├── fakes │ │ ├── fake_builder_inspector.go │ │ ├── fake_builder_writer.go │ │ ├── fake_builder_writer_factory.go │ │ ├── fake_buildpack_packager.go │ │ ├── fake_extension_packager.go │ │ ├── fake_inspect_image_writer.go │ │ ├── fake_inspect_image_writer_factory.go │ │ └── fake_package_config_reader.go │ ├── inspect_builder.go │ ├── inspect_builder_test.go │ ├── inspect_buildpack.go │ ├── inspect_buildpack_test.go │ ├── inspect_extension.go │ ├── inspect_image.go │ ├── inspect_image_test.go │ ├── list_registries.go │ ├── list_registries_test.go │ ├── list_trusted_builders.go │ ├── list_trusted_builders_test.go │ ├── manifest.go │ ├── manifest_add.go │ ├── manifest_add_test.go │ ├── manifest_annotate.go │ ├── manifest_annotate_test.go │ ├── manifest_create.go │ ├── manifest_create_test.go │ ├── manifest_inspect.go │ ├── manifest_inspect_test.go │ ├── manifest_push.go │ ├── manifest_push_test.go │ ├── manifest_remove.go │ ├── manifest_remove_test.go │ ├── manifest_rm.go │ ├── manifest_rm_test.go │ ├── manifest_test.go │ ├── package_buildpack.go │ ├── package_buildpack_test.go │ ├── rebase.go │ ├── rebase_test.go │ ├── register_buildpack.go │ ├── register_buildpack_test.go │ ├── remove_registry.go │ ├── remove_registry_test.go │ ├── report.go │ ├── report_test.go │ ├── sbom.go │ ├── set_default_builder.go │ ├── set_default_builder_test.go │ ├── set_default_registry.go │ ├── set_default_registry_test.go │ ├── set_run_image_mirrors.go │ ├── set_run_image_mirrors_test.go │ ├── stack.go │ ├── stack_suggest.go │ ├── stack_suggest_test.go │ ├── stack_test.go │ ├── suggest_builders.go │ ├── suggest_builders_test.go │ ├── testdata │ │ ├── buildpack.toml │ │ ├── inspect_image_output.json │ │ └── project.toml │ ├── testmocks │ │ ├── mock_inspect_image_writer_factory.go │ │ └── mock_pack_client.go │ ├── trust_builder.go │ ├── trust_builder_test.go │ ├── untrust_builder.go │ ├── untrust_builder_test.go │ ├── version.go │ ├── version_test.go │ ├── yank_buildpack.go │ └── yank_buildpack_test.go ├── config │ ├── config.go │ ├── config_helpers.go │ └── config_test.go ├── container │ └── run.go ├── fakes │ ├── fake_buildpack.go │ ├── fake_buildpack_blob.go │ ├── fake_buildpack_tar.go │ ├── fake_extension.go │ ├── fake_extension_blob.go │ ├── fake_extension_tar.go │ ├── fake_image_fetcher.go │ ├── fake_images.go │ ├── fake_lifecycle.go │ └── fake_package.go ├── inspectimage │ ├── bom_display.go │ ├── info_display.go │ └── writer │ │ ├── bom_json.go │ │ ├── bom_json_test.go │ │ ├── bom_yaml.go │ │ ├── bom_yaml_test.go │ │ ├── factory.go │ │ ├── factory_test.go │ │ ├── human_readable.go │ │ ├── human_readable_test.go │ │ ├── json.go │ │ ├── json_test.go │ │ ├── structured_bom_format.go │ │ ├── structured_bom_format_test.go │ │ ├── structured_format.go │ │ ├── structured_format_test.go │ │ ├── toml.go │ │ ├── toml_test.go │ │ ├── yaml.go │ │ └── yaml_test.go ├── layer │ ├── layer.go │ ├── writer_factory.go │ └── writer_factory_test.go ├── name │ ├── name.go │ └── name_test.go ├── paths │ ├── defaults_unix.go │ ├── defaults_windows.go │ ├── paths.go │ └── paths_test.go ├── registry │ ├── buildpack.go │ ├── buildpack_test.go │ ├── git.go │ ├── git_test.go │ ├── github.go │ ├── github_test.go │ ├── index.go │ ├── index_test.go │ ├── registry_cache.go │ └── registry_cache_test.go ├── slices │ ├── slices.go │ └── slices_test.go ├── sshdialer │ ├── posix_test.go │ ├── server_test.go │ ├── ssh_agent_unix.go │ ├── ssh_agent_windows.go │ ├── ssh_dialer.go │ ├── ssh_dialer_test.go │ ├── testdata │ │ ├── etc │ │ │ └── ssh │ │ │ │ ├── ssh_host_ecdsa_key │ │ │ │ ├── ssh_host_ecdsa_key.pub │ │ │ │ ├── ssh_host_ed25519_key │ │ │ │ ├── ssh_host_ed25519_key.pub │ │ │ │ ├── ssh_host_rsa_key │ │ │ │ └── ssh_host_rsa_key.pub │ │ ├── id_dsa │ │ ├── id_dsa.pub │ │ ├── id_ed25519 │ │ ├── id_ed25519.pub │ │ ├── id_rsa │ │ └── id_rsa.pub │ └── windows_test.go ├── stack │ ├── merge.go │ ├── merge_test.go │ ├── mixins.go │ └── mixins_test.go ├── strings │ ├── strings.go │ └── strings_test.go ├── stringset │ ├── stringset.go │ └── stringset_test.go ├── style │ ├── style.go │ └── style_test.go ├── target │ ├── parse.go │ ├── parse_test.go │ ├── platform.go │ └── platform_test.go ├── term │ ├── term.go │ └── term_test.go └── termui │ ├── branch.go │ ├── dashboard.go │ ├── detect.go │ ├── dive.go │ ├── dive_test.go │ ├── fakes │ ├── app.go │ ├── builder.go │ └── docker_stdwriter.go │ ├── logger.go │ ├── termui.go │ ├── termui_test.go │ └── testdata │ ├── fake-layers.tar │ └── generate.sh ├── main.go ├── pkg ├── README.md ├── archive │ ├── archive.go │ ├── archive_test.go │ ├── archive_unix.go │ ├── archive_windows.go │ ├── tar_builder.go │ ├── tar_builder_test.go │ ├── testdata │ │ ├── dir-to-tar-with-hardlink │ │ │ └── original-file │ │ ├── dir-to-tar │ │ │ ├── some-file.txt │ │ │ └── sub-dir │ │ │ │ └── link-file │ │ ├── fat-zip-to-tar.zip │ │ ├── jar-file.jar │ │ └── zip-to-tar.zip │ └── umask_unix.go ├── blob │ ├── blob.go │ ├── blob_test.go │ ├── downloader.go │ ├── downloader_test.go │ └── testdata │ │ ├── blob │ │ └── file.txt │ │ ├── buildpack │ │ └── buildpack.toml │ │ └── lifecycle │ │ ├── analyzer │ │ ├── builder │ │ ├── cacher │ │ ├── detector │ │ ├── exporter │ │ ├── launcher │ │ └── restorer ├── buildpack │ ├── build_module_info.go │ ├── build_module_info_test.go │ ├── builder.go │ ├── builder_test.go │ ├── buildpack.go │ ├── buildpack_tar_writer.go │ ├── buildpack_tar_writer_test.go │ ├── buildpack_test.go │ ├── buildpackage.go │ ├── downloader.go │ ├── downloader_test.go │ ├── locator_type.go │ ├── locator_type_test.go │ ├── managed_collection.go │ ├── managed_collection_test.go │ ├── multi_architecture_helper.go │ ├── multi_architecture_helper_test.go │ ├── oci_layout_package.go │ ├── oci_layout_package_test.go │ ├── package.go │ ├── parse_name.go │ ├── parse_name_test.go │ └── testdata │ │ ├── buildpack-with-hardlink │ │ ├── bin │ │ │ ├── build │ │ │ └── detect │ │ ├── buildpack.toml │ │ └── original-file │ │ ├── buildpack │ │ ├── bin │ │ │ ├── build │ │ │ └── detect │ │ └── buildpack.toml │ │ ├── extension │ │ ├── bin │ │ │ ├── detect │ │ │ └── generate │ │ └── extension.toml │ │ ├── hello-universe-oci.cnb │ │ ├── hello-universe.cnb │ │ ├── package.toml │ │ └── tree-extension.cnb ├── cache │ ├── bind_cache.go │ ├── cache_opts.go │ ├── cache_opts_test.go │ ├── consts.go │ ├── image_cache.go │ ├── image_cache_test.go │ ├── volume_cache.go │ └── volume_cache_test.go ├── client │ ├── build.go │ ├── build_test.go │ ├── client.go │ ├── client_test.go │ ├── common.go │ ├── common_test.go │ ├── create_builder.go │ ├── create_builder_test.go │ ├── docker.go │ ├── docker_context.go │ ├── docker_context_test.go │ ├── download_sbom.go │ ├── download_sbom_test.go │ ├── errors.go │ ├── example_build_test.go │ ├── example_buildpack_downloader_test.go │ ├── example_fetcher_test.go │ ├── input_image_reference.go │ ├── input_image_reference_test.go │ ├── inspect_builder.go │ ├── inspect_builder_test.go │ ├── inspect_buildpack.go │ ├── inspect_buildpack_test.go │ ├── inspect_extension.go │ ├── inspect_extension_test.go │ ├── inspect_image.go │ ├── inspect_image_test.go │ ├── manifest_add.go │ ├── manifest_add_test.go │ ├── manifest_annotate.go │ ├── manifest_annotate_test.go │ ├── manifest_create.go │ ├── manifest_create_test.go │ ├── manifest_inspect.go │ ├── manifest_inspect_test.go │ ├── manifest_push.go │ ├── manifest_push_test.go │ ├── manifest_remove.go │ ├── manifest_remove_test.go │ ├── manifest_rm.go │ ├── manifest_rm_test.go │ ├── new_buildpack.go │ ├── new_buildpack_test.go │ ├── package_buildpack.go │ ├── package_buildpack_test.go │ ├── package_extension.go │ ├── package_extension_test.go │ ├── process_volumes.go │ ├── process_volumes_unix.go │ ├── pull_buildpack.go │ ├── pull_buildpack_test.go │ ├── rebase.go │ ├── rebase_test.go │ ├── register_buildpack.go │ ├── register_buildpack_test.go │ ├── testdata │ │ ├── builder.toml │ │ ├── buildpack-api-0.4 │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ └── buildpack.toml │ │ ├── buildpack-flatten │ │ │ ├── buildpack-1 │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-2 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-3 │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-4 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-5 │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-6 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ └── buildpack-7 │ │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ ├── buildpack-multi-platform │ │ │ ├── README.md │ │ │ ├── buildpack-composite-with-dependencies-on-disk │ │ │ │ ├── buildpack.toml │ │ │ │ └── package.toml │ │ │ ├── buildpack-composite │ │ │ │ ├── buildpack.toml │ │ │ │ └── package.toml │ │ │ ├── buildpack-new-format-with-versions │ │ │ │ └── linux │ │ │ │ │ ├── amd64 │ │ │ │ │ └── v5 │ │ │ │ │ │ ├── ubuntu@18.01 │ │ │ │ │ │ ├── bin │ │ │ │ │ │ │ ├── build │ │ │ │ │ │ │ └── detect │ │ │ │ │ │ └── buildpack.toml │ │ │ │ │ │ └── ubuntu@21.01 │ │ │ │ │ │ ├── bin │ │ │ │ │ │ ├── build │ │ │ │ │ │ └── detect │ │ │ │ │ │ └── buildpack.toml │ │ │ │ │ └── arm │ │ │ │ │ └── v6 │ │ │ │ │ ├── ubuntu@18.01 │ │ │ │ │ ├── bin │ │ │ │ │ │ ├── build │ │ │ │ │ │ └── detect │ │ │ │ │ └── buildpack.toml │ │ │ │ │ └── ubuntu@21.01 │ │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-new-format │ │ │ │ └── linux │ │ │ │ │ ├── amd64 │ │ │ │ │ ├── bin │ │ │ │ │ │ ├── build │ │ │ │ │ │ └── detect │ │ │ │ │ └── buildpack.toml │ │ │ │ │ ├── arm │ │ │ │ │ ├── bin │ │ │ │ │ │ ├── build │ │ │ │ │ │ └── detect │ │ │ │ │ └── buildpack.toml │ │ │ │ │ └── buildpack.toml │ │ │ └── buildpack-old-format │ │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ ├── buildpack-non-deterministic │ │ │ ├── buildpack-1-version-1 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-1-version-2 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ ├── buildpack-2-version-1 │ │ │ │ ├── bin │ │ │ │ │ ├── build │ │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ │ └── buildpack-2-version-2 │ │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ │ └── buildpack.toml │ │ ├── buildpack │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ └── buildpack.toml │ │ ├── buildpack2 │ │ │ ├── bin │ │ │ │ ├── build │ │ │ │ └── detect │ │ │ └── buildpack.toml │ │ ├── docker-context │ │ │ ├── error-cases │ │ │ │ ├── config-does-not-exist │ │ │ │ │ └── README │ │ │ │ ├── current-context-does-not-match │ │ │ │ │ ├── config.json │ │ │ │ │ └── contexts │ │ │ │ │ │ └── meta │ │ │ │ │ │ └── fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e │ │ │ │ │ │ └── meta.json │ │ │ │ ├── docker-endpoint-does-not-exist │ │ │ │ │ ├── config.json │ │ │ │ │ └── contexts │ │ │ │ │ │ └── meta │ │ │ │ │ │ └── fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e │ │ │ │ │ │ └── meta.json │ │ │ │ ├── empty-context │ │ │ │ │ └── config.json │ │ │ │ ├── invalid-config │ │ │ │ │ └── config.json │ │ │ │ └── invalid-metadata │ │ │ │ │ ├── config.json │ │ │ │ │ └── contexts │ │ │ │ │ └── meta │ │ │ │ │ └── fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e │ │ │ │ │ └── meta.json │ │ │ └── happy-cases │ │ │ │ ├── current-context-not-defined │ │ │ │ └── config.json │ │ │ │ ├── custom-context │ │ │ │ ├── config.json │ │ │ │ └── contexts │ │ │ │ │ └── meta │ │ │ │ │ └── fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e │ │ │ │ │ └── meta.json │ │ │ │ ├── default-context │ │ │ │ └── config.json │ │ │ │ └── two-endpoints-context │ │ │ │ ├── config.json │ │ │ │ └── contexts │ │ │ │ └── meta │ │ │ │ └── fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e │ │ │ │ └── meta.json │ │ ├── downloader │ │ │ └── dirA │ │ │ │ └── file.txt │ │ ├── empty-file │ │ ├── extension-api-0.9 │ │ │ ├── bin │ │ │ │ ├── detect │ │ │ │ └── generate │ │ │ └── extension.toml │ │ ├── extension │ │ │ ├── bin │ │ │ │ ├── detect │ │ │ │ └── generate │ │ │ └── extension.toml │ │ ├── jar-file.jar │ │ ├── just-a-file.txt │ │ ├── lifecycle │ │ │ ├── lifecycle.tar │ │ │ ├── platform-0.3 │ │ │ │ ├── lifecycle-v0.0.0-arch │ │ │ │ │ ├── analyzer │ │ │ │ │ ├── builder │ │ │ │ │ ├── creator │ │ │ │ │ ├── detector │ │ │ │ │ ├── exporter │ │ │ │ │ ├── launcher │ │ │ │ │ └── restorer │ │ │ │ └── lifecycle.toml │ │ │ └── platform-0.4 │ │ │ │ ├── lifecycle-v0.0.0-arch │ │ │ │ ├── analyzer │ │ │ │ ├── builder │ │ │ │ ├── creator │ │ │ │ ├── detector │ │ │ │ ├── exporter │ │ │ │ ├── launcher │ │ │ │ └── restorer │ │ │ │ └── lifecycle.toml │ │ ├── non-zip-file │ │ ├── registry │ │ │ ├── 3 │ │ │ │ └── fo │ │ │ │ │ └── example_foo │ │ │ └── ja │ │ │ │ └── va │ │ │ │ └── example_java │ │ ├── some-app │ │ │ └── .gitignore │ │ └── zip-file.zip │ ├── version.go │ ├── yank_buildpack.go │ └── yank_buildpack_test.go ├── dist │ ├── buildmodule.go │ ├── buildmodule_test.go │ ├── buildpack_descriptor.go │ ├── buildpack_descriptor_test.go │ ├── dist.go │ ├── dist_test.go │ ├── distribution.go │ ├── extension_descriptor.go │ ├── extension_descriptor_test.go │ ├── image.go │ ├── image_test.go │ └── layers.go ├── image │ ├── fetcher.go │ ├── fetcher_test.go │ ├── pull_policy.go │ └── pull_policy_test.go ├── index │ ├── index_factory.go │ └── index_factory_test.go ├── logging │ ├── logger_simple.go │ ├── logger_simple_test.go │ ├── logger_writers.go │ ├── logger_writers_test.go │ ├── logging.go │ ├── logging_test.go │ ├── prefix_writer.go │ └── prefix_writer_test.go ├── project │ ├── project.go │ ├── project_test.go │ ├── types │ │ └── types.go │ ├── v01 │ │ └── project.go │ └── v02 │ │ ├── metadata.go │ │ ├── metadata_test.go │ │ └── project.go └── testmocks │ ├── mock_access_checker.go │ ├── mock_blob_downloader.go │ ├── mock_build_module.go │ ├── mock_buildpack_downloader.go │ ├── mock_docker_client.go │ ├── mock_image.go │ ├── mock_image_factory.go │ ├── mock_image_fetcher.go │ ├── mock_index_factory.go │ └── mock_registry_resolver.go ├── project.toml ├── registry └── type.go ├── resources └── pack-build.gif ├── testdata ├── builder.toml ├── buildpack-api-0.4 │ ├── bin │ │ ├── build │ │ └── detect │ └── buildpack.toml ├── buildpack │ ├── bin │ │ ├── build │ │ └── detect │ └── buildpack.toml ├── buildpack2 │ ├── bin │ │ ├── build │ │ └── detect │ └── buildpack.toml ├── downloader │ └── dirA │ │ └── file.txt ├── empty-file ├── jar-file.jar ├── just-a-file.txt ├── lifecycle │ ├── platform-0.3 │ │ ├── lifecycle-v0.0.0-arch │ │ │ ├── analyzer │ │ │ ├── builder │ │ │ ├── creator │ │ │ ├── detector │ │ │ ├── exporter │ │ │ ├── launcher │ │ │ └── restorer │ │ └── lifecycle.toml │ └── platform-0.4 │ │ ├── lifecycle-v0.0.0-arch │ │ ├── analyzer │ │ ├── builder │ │ ├── creator │ │ ├── detector │ │ ├── exporter │ │ ├── launcher │ │ └── restorer │ │ └── lifecycle.toml ├── non-zip-file ├── registry │ ├── 3 │ │ └── fo │ │ │ └── example_foo │ └── ja │ │ └── va │ │ └── example_java ├── some-app │ └── .gitignore └── zip-file.zip ├── testhelpers ├── arg_patterns.go ├── assert_file.go ├── assertions.go ├── comparehelpers │ ├── deep_compare.go │ └── deep_compare_test.go ├── image_index.go ├── registry.go ├── tar_assertions.go ├── tar_verifier.go └── testhelpers.go └── tools ├── go.mod ├── go.sum ├── pedantic_imports └── main.go ├── test-fork.sh └── tools.go /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 3 | about: Bug report 4 | title: '' 5 | labels: status/triage, type/bug 6 | assignees: '' 7 | 8 | --- 9 | ### Summary 10 | 11 | 12 | 13 | --- 14 | 15 | ### Reproduction 16 | 17 | ##### Steps 18 | 19 | 20 | 1. 21 | 2. 22 | 3. 23 | 24 | 25 | ##### Current behavior 26 | 27 | 28 | 29 | ##### Expected behavior 30 | 31 | 32 | 33 | --- 34 | 35 | ### Environment 36 | 37 | ##### pack info 38 | 39 | 40 | ##### docker info 41 | 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/chore.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Chore 3 | about: Suggest a chore that will help contributors and doesn't affect end users. 4 | title: '' 5 | labels: type/chore, status/triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Description 11 | 12 | 13 | ### Proposed solution 14 | 15 | 16 | ### Additional context 17 | 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Questions 3 | url: https://github.com/buildpacks/community/discussions 4 | about: Have a general question? 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest a new feature or an improvement to existing functionality 4 | title: '' 5 | labels: type/enhancement, status/triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Description 11 | 13 | 14 | ### Proposed solution 15 | 17 | 18 | ### Describe alternatives you've considered 19 | 20 | 21 | ### Additional context 22 | - [ ] This feature should be documented somewhere 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Set update schedule for gomod 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | groups: 9 | # Group all minor/patch go dependencies into a single PR. 10 | go-dependencies: 11 | update-types: 12 | - "minor" 13 | - "patch" 14 | labels: 15 | - "dependencies" 16 | - "go" 17 | - "type/chore" 18 | 19 | # Set update schedule for GitHub Actions 20 | - package-ecosystem: "github-actions" 21 | directory: "/" 22 | schedule: 23 | interval: "weekly" 24 | labels: 25 | - "dependencies" 26 | - "github_actions" 27 | - "type/chore" 28 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # Rules defined here: https://github.com/actions/labeler 2 | type/chore: 3 | - '*.md' 4 | - '**/*.yml' 5 | - 'acceptance/**/*' 6 | - '.github/**/*' 7 | - 'go.mod' 8 | - 'go.sum' 9 | 10 | type/enhancement: 11 | - '*.go' 12 | - '**/*.go' 13 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | 4 | ## Output 5 | 6 | 7 | #### Before 8 | 9 | #### After 10 | 11 | ## Documentation 12 | 13 | 14 | 15 | - Should this change be documented? 16 | - [ ] Yes, see #___ 17 | - [ ] No 18 | 19 | ## Related 20 | 21 | 22 | Resolves #___ 23 | -------------------------------------------------------------------------------- /.github/release-notes.yml: -------------------------------------------------------------------------------- 1 | labels: 2 | breaking-change: 3 | title: Breaking Changes 4 | description: Changes that may require a little bit of thought before upgrading. 5 | weight: 8 6 | experimental: 7 | title: Experimental 8 | description: | 9 | _Experimental features that may change in the future. Use them at your discretion._ 10 | 11 | _To enable these features, run `pack config experimental true`, or add `experimental = true` to your `~/.pack/config.toml`._ 12 | weight: 9 13 | type/enhancement: 14 | title: Features 15 | weight: 1 16 | type/bug: 17 | title: Bugs 18 | weight: 2 19 | 20 | sections: 21 | contributors: 22 | title: Contributors 23 | description: | 24 | We'd like to acknowledge that this release wouldn't be as good without the help of the following amazing contributors: -------------------------------------------------------------------------------- /.github/workflows/actions/release-notes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | changelog.md -------------------------------------------------------------------------------- /.github/workflows/actions/release-notes/action.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is the main entrypoint for GitHub Actions (see action.yml) 3 | */ 4 | 5 | const core = require('@actions/core'); 6 | const github = require('@actions/github'); 7 | const releaseNotes = require('./release-notes.js'); 8 | 9 | try { 10 | const defaultConfigFile = "./.github/release-notes.yml"; 11 | 12 | releaseNotes( 13 | github.getOctokit(core.getInput("github-token", {required: true})), 14 | `${github.context.repo.owner}/${github.context.repo.repo}`, 15 | core.getInput('milestone', {required: true}), 16 | core.getInput('configFile') || defaultConfigFile, 17 | ) 18 | .then(contents => { 19 | console.log("GENERATED CHANGELOG\n=========================\n", contents); 20 | core.setOutput("contents", contents) 21 | }) 22 | .catch(error => core.setFailed(error.message)) 23 | } catch (error) { 24 | core.setFailed(error.message); 25 | } -------------------------------------------------------------------------------- /.github/workflows/actions/release-notes/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Release Notes' 2 | description: 'Generate release notes based on pull requests in a milestone.' 3 | inputs: 4 | github-token: 5 | description: GitHub token used to search for pull requests. 6 | required: true 7 | milestone: 8 | description: The milestone used to look for pull requests. 9 | required: true 10 | config-file: 11 | description: Path to the configuration (yaml) file. 12 | required: false 13 | default: "./.github/release-notes.yml" 14 | outputs: 15 | contents: 16 | description: The contents of the release notes. 17 | runs: 18 | using: 'node16' 19 | main: 'dist/index.js' -------------------------------------------------------------------------------- /.github/workflows/actions/release-notes/local.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is the main entry for local development and manual testing. 3 | */ 4 | 5 | const path = require('path'); 6 | const releaseNotes = require(path.resolve('release-notes.js')); 7 | 8 | const {Octokit} = require("@octokit/rest"); 9 | const github = new Octokit({auth: mustGetEnvVar('GITHUB_TOKEN')}); 10 | 11 | releaseNotes( 12 | github, 13 | "buildpacks/pack", 14 | mustGetArg(0, "milestone"), 15 | mustGetArg(1, "config-path") 16 | ) 17 | .then(console.log) 18 | .catch(err => { 19 | console.error(err); 20 | process.exit(1); 21 | }); 22 | 23 | function mustGetArg(position, name) { 24 | let value = process.argv[position + 2]; 25 | if (!value) { 26 | console.error(`'${name}' must be provided as argument ${position}.`); 27 | process.exit(1); 28 | } 29 | return value; 30 | } 31 | 32 | function mustGetEnvVar(envVar) { 33 | let value = process.env[envVar]; 34 | if (!value) { 35 | console.error(`'${envVar}' env var must be set.`); 36 | process.exit(1); 37 | } 38 | return value; 39 | } -------------------------------------------------------------------------------- /.github/workflows/actions/release-notes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "release-notes", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "local": "node local.js", 6 | "build": "ncc build action.js -o dist/" 7 | }, 8 | "dependencies": { 9 | "@actions/core": "^1.10.0", 10 | "@actions/github": "^4.0.0", 11 | "@octokit/rest": "^18.0.0", 12 | "yaml": "^1.10.0" 13 | }, 14 | "devDependencies": { 15 | "@vercel/ncc": "^0.24.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/delivery-release-dispatch.yml: -------------------------------------------------------------------------------- 1 | name: delivery / release-dispatch 2 | 3 | on: 4 | release: 5 | types: 6 | - released 7 | 8 | jobs: 9 | send-release-dispatch: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | repo: ['buildpacks/docs', 'buildpacks/samples', 'buildpacks/pack-orb', 'buildpacks/github-actions'] 14 | steps: 15 | - name: Repository Dispatch 16 | uses: peter-evans/repository-dispatch@v3 17 | with: 18 | token: ${{ secrets.PLATFORM_GITHUB_TOKEN }} 19 | event-type: pack-release 20 | repository: ${{ matrix.repo }} 21 | -------------------------------------------------------------------------------- /.github/workflows/delivery/archlinux/pack-cli-bin/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Michael William Le Nguyen 2 | # Maintainer: Buildpacks Maintainers 3 | pkgname=pack-cli-bin 4 | pkgver={{PACK_VERSION}} 5 | pkgrel=1 6 | pkgdesc="CLI for building apps using Cloud Native Buildpacks" 7 | arch=('x86_64') 8 | url="https://buildpacks.io/" 9 | license=('Apache') 10 | provides=('pack-cli') 11 | conflicts=('pack-cli') 12 | source=("{{BIN_TGZ_URL}}") 13 | sha512sums=("{{BIN_TGZ_SHA}}") 14 | package() { 15 | install -D -m755 "${srcdir}/pack" "${pkgdir}/usr/bin/pack" 16 | } -------------------------------------------------------------------------------- /.github/workflows/delivery/archlinux/pack-cli-git/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Michael William Le Nguyen 2 | # Maintainer: Buildpacks Maintainers 3 | pkgname=pack-cli-git 4 | pkgver={{PACK_VERSION}}+r{{GIT_REVISION}}.g{{GIT_COMMIT}} 5 | pkgrel=1 6 | pkgdesc="CLI for building apps using Cloud Native Buildpacks" 7 | arch=('x86_64') 8 | url="https://buildpacks.io/" 9 | license=('Apache') 10 | makedepends=( 11 | 'git' 12 | 'go-pie' 13 | ) 14 | provides=('pack-cli') 15 | conflicts=('pack-cli') 16 | source=("${pkgname}::git+https://github.com/buildpacks/pack") 17 | sha512sums=("SKIP") 18 | build() { 19 | export GOPATH="${srcdir}/go" 20 | cd "${srcdir}/${pkgname}" 21 | PACK_VERSION={{PACK_VERSION}} make build 22 | } 23 | package() { 24 | export GOPATH="${srcdir}/go" 25 | go clean -modcache 26 | install -D -m755 "${srcdir}/${pkgname}/out/pack" "${pkgdir}/usr/bin/pack" 27 | } -------------------------------------------------------------------------------- /.github/workflows/delivery/archlinux/test-install-package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -u 4 | 5 | # ensure variable is set 6 | : "$PACKAGE_NAME" 7 | : "$GITHUB_WORKSPACE" 8 | 9 | # setup non-root user 10 | useradd -m archie 11 | 12 | # add non-root user to sudoers 13 | pacman -Sy --noconfirm sudo 14 | echo 'archie ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers 15 | 16 | # setup workspace 17 | WORKSPACE=$(mktemp -d -t "$PACKAGE_NAME-XXXXXXXXXX") 18 | cp -R "$GITHUB_WORKSPACE/$PACKAGE_NAME/"* "$WORKSPACE" 19 | chown -R archie "$WORKSPACE" 20 | 21 | # run everything else as non-root user 22 | pushd "$WORKSPACE" > /dev/null 23 | su archie << "EOF" 24 | echo -n '> Debug info:' 25 | ls -al 26 | sha512sum ./* 27 | 28 | echo -n '> Installing AUR packaging deps...' 29 | sudo pacman -Sy --noconfirm git base-devel libffi 30 | 31 | echo -n '> Installing package...' 32 | makepkg -sri --noconfirm 33 | 34 | # print version 35 | echo -n '> Installed pack version: ' 36 | pack --version 37 | EOF 38 | popd > /dev/null 39 | -------------------------------------------------------------------------------- /.github/workflows/delivery/chocolatey/tools/VERIFICATION.txt: -------------------------------------------------------------------------------- 1 | 2 | VERIFICATION 3 | Verification is intended to assist the Chocolatey moderators and community 4 | in verifying that this package's contents are trustworthy. 5 | 6 | This release is published by the Cloud Native Buildpacks project, creators of the Pack CLI. 7 | -------------------------------------------------------------------------------- /.github/workflows/delivery/homebrew/pack.rb: -------------------------------------------------------------------------------- 1 | ### 2 | # This file is autogenerated from https://github.com/buildpacks/pack/tree/main/.github/workflows/delivery/homebrew/ 3 | # Changes should be committed there. 4 | ### 5 | class Pack < Formula 6 | desc "A CLI for building apps using Cloud Native Buildpacks" 7 | homepage "https://github.com/buildpacks/pack" 8 | version "{{PACK_VERSION}}" 9 | version_scheme 1 10 | 11 | if OS.mac? && Hardware::CPU.arm? 12 | url "{{MACOS_ARM64_URL}}" 13 | sha256 "{{MACOS_ARM64_SHA}}" 14 | elsif OS.mac? 15 | url "{{MACOS_URL}}" 16 | sha256 "{{MACOS_SHA}}" 17 | elsif OS.linux? && Hardware::CPU.arm? 18 | url "{{LINUX_ARM64_URL}}" 19 | sha256 "{{LINUX_ARM64_SHA}}" 20 | else 21 | url "{{LINUX_URL}}" 22 | sha256 "{{LINUX_SHA}}" 23 | end 24 | 25 | def install 26 | bin.install "pack" 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/1_dependencies.sh: -------------------------------------------------------------------------------- 1 | function dependencies() { 2 | : "$GO_DEP_PACKAGE_NAME" 3 | 4 | echo "> Installing dev tools..." 5 | apt-get update 6 | apt-get install gnupg debhelper dput dh-make devscripts lintian software-properties-common -y 7 | 8 | echo "> Installing git..." 9 | apt-get install git -y 10 | 11 | echo "> Installing go..." 12 | add-apt-repository ppa:longsleep/golang-backports -y 13 | apt-get update 14 | apt-get install $GO_DEP_PACKAGE_NAME -y 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/3_test-ppa.sh: -------------------------------------------------------------------------------- 1 | function test_ppa { 2 | : "$GITHUB_WORKSPACE" 3 | 4 | echo "> Creating a test directory..." 5 | testdir="$(mktemp -d)" 6 | 7 | echo "> Source Dir: '$GITHUB_WORKSPACE'" 8 | echo "> Test Dir: '$testdir'" 9 | cp -R $GITHUB_WORKSPACE/* $testdir 10 | 11 | pushd $testdir 12 | echo "> Building a debian binary package..." 13 | debuild -b -us -uc 14 | 15 | echo "> Installing binary package..." 16 | dpkg -i ../*.deb 17 | 18 | echo "> Contents installed by the build debain package:" 19 | dpkg -L pack-cli 20 | popd 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/4_upload-ppa.sh: -------------------------------------------------------------------------------- 1 | function upload_ppa { 2 | echo "> Uploading PPA..." 3 | dput "ppa:cncf-buildpacks/pack-cli" ./../*.changes 4 | } -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/README: -------------------------------------------------------------------------------- 1 | The Debian Package {{PACKAGE_NAME}} 2 | ---------------------------- 3 | 4 | CLI for building apps using Cloud Native Buildpacks. 5 | 6 | For extensive documentation see: https://buildpacks.io/docs/tools/pack/cli/pack/ 7 | 8 | Please file issues and bugs at https://github.com/buildpacks/pack/ 9 | 10 | -- {{MAINTAINER_NAME}} <{{MAINTAINER_EMAIL}}> {{DATE_TIME}} -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/changelog: -------------------------------------------------------------------------------- 1 | {{PACKAGE_NAME}} ({{PACK_VERSION}}-0ubuntu1~{{UBUNTU_VERSION}}) {{UBUNTU_VERSION}}; urgency=medium 2 | 3 | * For complete changelog see https://github.com/buildpacks/pack/releases/tag/v{{PACK_VERSION}}. 4 | 5 | -- {{MAINTAINER_NAME}} <{{MAINTAINER_EMAIL}}> {{DATE_TIME}} 6 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/compat: -------------------------------------------------------------------------------- 1 | 9 -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/control: -------------------------------------------------------------------------------- 1 | Source: {{PACKAGE_NAME}} 2 | Section: utils 3 | Priority: optional 4 | Maintainer: {{MAINTAINER_NAME}} <{{MAINTAINER_EMAIL}}> 5 | Build-Depends: debhelper (>=9), git, {{GO_DEP_ENTRY}} 6 | Standards-Version: 3.9.8 7 | Vcs-Git: git@github.com/{{REPO}}.git 8 | Vcs-Browser: https://github.com/{{REPO}} 9 | Homepage: {{HOMEPAGE}} 10 | 11 | Package: {{PACKAGE_NAME}} 12 | Architecture: {{ARCH}} 13 | Description: {{DESCRIPTION}} 14 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: {{PACKAGE_NAME}} 3 | 4 | Files: * 5 | 6 | License: Apache-2.0 7 | 8 | Files: debian/* 9 | Copyright: 2020 {{MAINTAINER_NAME}} <{{MAINTAINER_EMAIL}}> 10 | License: Apache-2.0 11 | 12 | License: Apache-2.0 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at 16 | . 17 | https://www.apache.org/licenses/LICENSE-2.0 18 | . 19 | Unless required by applicable law or agreed to in writing, software 20 | distributed under the License is distributed on an "AS IS" BASIS, 21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | See the License for the specific language governing permissions and 23 | limitations under the License. 24 | . 25 | On Debian systems, the complete text of the Apache version 2.0 license 26 | can be found in "/usr/share/common-licenses/Apache-2.0". 27 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | export DH_VERBOSE = 1 5 | 6 | %: 7 | dh $@ 8 | 9 | override_dh_auto_test: 10 | 11 | override_dh_auto_build: 12 | mkdir -p /tmp/.cache/go-build 13 | GOCACHE=/tmp/.cache/go-build GOFLAGS="-mod=vendor" LDFLAGS="" PACK_VERSION='{{PACK_VERSION}}' PATH="${PATH}:{{GO_DEP_LIB_PATH}}/bin" dh_auto_build -- build 14 | rm -r /tmp/.cache/go-build 15 | -------------------------------------------------------------------------------- /.github/workflows/delivery/ubuntu/deliver.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | 8 | echo "PWD=${PWD}" 9 | echo "SCRIPT_DIR=${SCRIPT_DIR}" 10 | 11 | source "$SCRIPT_DIR/1_dependencies.sh" 12 | source "$SCRIPT_DIR/2_create-ppa.sh" 13 | source "$SCRIPT_DIR/3_test-ppa.sh" 14 | source "$SCRIPT_DIR/4_upload-ppa.sh" 15 | 16 | echo 17 | echo "++++++++++++++++++++++++++++" 18 | echo "> Installing dependencies..." 19 | echo "++++++++++++++++++++++++++++" 20 | echo 21 | dependencies 22 | 23 | echo 24 | echo "++++++++++++++++++++++++++++" 25 | echo "> Creating PPA..." 26 | echo "++++++++++++++++++++++++++++" 27 | echo 28 | create_ppa 29 | 30 | echo 31 | echo "++++++++++++++++++++++++++++" 32 | echo "> Testing PPA..." 33 | echo "++++++++++++++++++++++++++++" 34 | echo 35 | test_ppa 36 | 37 | echo 38 | echo "++++++++++++++++++++++++++++" 39 | echo "> Uploading PPA..." 40 | echo "++++++++++++++++++++++++++++" 41 | echo 42 | upload_ppa 43 | -------------------------------------------------------------------------------- /.github/workflows/release-merge.yml: -------------------------------------------------------------------------------- 1 | # Merges changes to release branches back into main. 2 | name: release-merge 3 | 4 | on: 5 | push: 6 | branches: 7 | - 'release/**' 8 | 9 | jobs: 10 | merge: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Merge 14 | run: | 15 | echo '> Configuring ssh...' 16 | SSH_HOME="${HOME}/.ssh" 17 | mkdir -p "${SSH_HOME}" 18 | chmod 700 "${SSH_HOME}" 19 | 20 | echo '> Starting ssh-agent...' 21 | eval $(ssh-agent) 22 | 23 | echo '> Add Github to known_hosts...' 24 | ssh-keyscan -H github.com >> "${SSH_HOME}/known_hosts" 25 | chmod 644 "${SSH_HOME}/known_hosts" 26 | 27 | echo '> Adding DEPLOY_KEY...' 28 | ssh-add - <<< "${{ secrets.DEPLOY_KEY }}" 29 | 30 | echo '> Attempting merge...' 31 | ls -al 32 | git config --global user.name "github-bot" 33 | git config --global user.email "action@github.com" 34 | git clone git@github.com:${GITHUB_REPOSITORY}.git 35 | cd pack 36 | git checkout main 37 | git merge origin/${GITHUB_REF#refs/heads/} --no-edit 38 | git show -1 39 | git push -------------------------------------------------------------------------------- /.github/workflows/scripts/generate-workflow_dispatch-event.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | usage() { 5 | echo "Usage: " 6 | echo " $0 " 7 | echo 8 | echo " inputs in JSON format" 9 | echo 10 | echo "Examples: " 11 | echo " $0 '{\"tag\": \"v1.2.3\"}'" 12 | echo " $0 '{\"issue_number\": 123}'" 13 | echo 14 | exit 1; 15 | } 16 | 17 | INPUT_JSON="${1}" 18 | if [[ -z "${INPUT_JSON}" ]]; then 19 | echo "Must specify input json" 20 | echo 21 | usage 22 | exit 1 23 | fi 24 | 25 | tmpEventFile=$(mktemp) 26 | cat < "$tmpEventFile" 27 | { 28 | "action": "workflow_dispatch", 29 | "inputs": ${INPUT_JSON} 30 | } 31 | EOF 32 | 33 | echo "$tmpEventFile" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pack/ 2 | /pack 3 | out/ 4 | benchmarks.test 5 | *.out 6 | 7 | # Jetbrains Goland 8 | .idea/ 9 | 10 | # Build outputs 11 | artifacts/ 12 | .DS_Store 13 | 14 | # Travis unencrypted file 15 | .travis/key.pem 16 | 17 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | 2 | tasks: 3 | - name: Setup 4 | before: chmod ugo+w /var/run/docker.sock 5 | init: make build 6 | command: chmod ugo+w /var/run/docker.sock 7 | 8 | github: 9 | prebuilds: 10 | master: true 11 | branches: true 12 | pullRequests: true 13 | pullRequestsFromForks: true 14 | addCheck: true 15 | 16 | vscode: 17 | extensions: 18 | - golang.go 19 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @buildpacks/platform-maintainers @buildpacks/toc 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_image=gcr.io/distroless/static 2 | 3 | FROM golang:1.24 as builder 4 | ARG pack_version 5 | ENV PACK_VERSION=$pack_version 6 | WORKDIR /app 7 | COPY . . 8 | RUN make build 9 | 10 | FROM ${base_image} 11 | COPY --from=builder /app/out/pack /usr/local/bin/pack 12 | ENTRYPOINT [ "/usr/local/bin/pack" ] 13 | -------------------------------------------------------------------------------- /acceptance/config/pack_assets.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance 2 | 3 | package config 4 | 5 | type PackAsset struct { 6 | path string 7 | fixturePaths []string 8 | } 9 | 10 | func (a AssetManager) NewPackAsset(kind ComboValue) PackAsset { 11 | path, fixtures := a.PackPaths(kind) 12 | 13 | return PackAsset{ 14 | path: path, 15 | fixturePaths: fixtures, 16 | } 17 | } 18 | 19 | func (p PackAsset) Path() string { 20 | return p.path 21 | } 22 | 23 | func (p PackAsset) FixturePaths() []string { 24 | return p.fixturePaths 25 | } 26 | -------------------------------------------------------------------------------- /acceptance/os/variables.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance && !windows 2 | 3 | package os 4 | 5 | import "os" 6 | 7 | const PackBinaryName = "pack" 8 | 9 | var InterruptSignal = os.Interrupt 10 | -------------------------------------------------------------------------------- /acceptance/os/variables_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance && darwin && amd64 2 | 3 | package os 4 | 5 | import "regexp" 6 | 7 | var PackBinaryExp = regexp.MustCompile(`pack-v\d+.\d+.\d+-macos\.`) 8 | -------------------------------------------------------------------------------- /acceptance/os/variables_darwin_arm64.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance && darwin && arm64 2 | 3 | package os 4 | 5 | import "regexp" 6 | 7 | var PackBinaryExp = regexp.MustCompile(`pack-v\d+.\d+.\d+-macos-`) 8 | -------------------------------------------------------------------------------- /acceptance/os/variables_linux.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance && linux 2 | 3 | package os 4 | 5 | import "regexp" 6 | 7 | var PackBinaryExp = regexp.MustCompile(`pack-v\d+.\d+.\d+-linux\.`) 8 | -------------------------------------------------------------------------------- /acceptance/os/variables_windows.go: -------------------------------------------------------------------------------- 1 | //go:build acceptance && windows 2 | 3 | package os 4 | 5 | import ( 6 | "os" 7 | "regexp" 8 | ) 9 | 10 | const PackBinaryName = "pack.exe" 11 | 12 | var ( 13 | PackBinaryExp = regexp.MustCompile(`pack-v\d+.\d+.\d+-windows`) 14 | InterruptSignal = os.Kill 15 | ) 16 | -------------------------------------------------------------------------------- /acceptance/testconfig/all.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"pack": "current", "pack_create_builder": "current", "lifecycle": "current"}, 3 | {"pack": "current", "pack_create_builder": "current", "lifecycle": "previous"}, 4 | {"pack": "current", "pack_create_builder": "previous", "lifecycle": "previous"}, 5 | {"pack": "previous", "pack_create_builder": "current", "lifecycle": "current"}, 6 | {"pack": "previous", "pack_create_builder": "current", "lifecycle": "previous"} 7 | ] -------------------------------------------------------------------------------- /acceptance/testdata/mock_app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/acceptance/testdata/mock_app.zip -------------------------------------------------------------------------------- /acceptance/testdata/mock_app/project.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | version = "1.0.2" 3 | source-url = "https://github.com/buildpacks/pack" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_app/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | port="${1-8080}" 6 | 7 | echo "listening on port $port" 8 | 9 | resp=$(echo "HTTP/1.1 200 OK\n" && cat "$PWD"/*-deps/*-dep /contents*.txt) 10 | while true; do 11 | nc -l -p "$port" -c "echo \"$resp\"" 12 | done 13 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_app/run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set port=8080 4 | if [%1] neq [] set port=%1 5 | 6 | C:\util\server.exe -p %port% -g "%cd%\*-deps\*-dep, c:\contents*.txt" 7 | 8 | 9 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/descriptor-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Descriptor Buildpack" 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | 9 | ls -laR 10 | 11 | echo "---> Done" 12 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/descriptor-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: Descriptor Buildpack 4 | 5 | dir /s 6 | 7 | echo ---- Done 8 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/descriptor-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Detect: Descriptor Buildpack" 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | 9 | echo "---> Done" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/descriptor-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Detect: Descriptor Buildpack 4 | 5 | echo ---- Done 6 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/descriptor-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "descriptor/bp" 5 | version = "descriptor-bp-version" 6 | name = "Descriptor Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/internet-capable-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Internet Capable Buildpack" 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | 9 | 10 | if netcat -z -w 1 google.com 80; then 11 | echo "RESULT: Connected to the internet" 12 | else 13 | echo "RESULT: Disconnected from the internet" 14 | fi 15 | 16 | echo "---> Done" 17 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/internet-capable-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: Internet capable buildpack 4 | 5 | ping -n 1 google.com 6 | 7 | if %ERRORLEVEL% equ 0 ( 8 | echo RESULT: Connected to the internet 9 | ) else ( 10 | echo RESULT: Disconnected from the internet 11 | ) 12 | 13 | echo ---- Done 14 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/internet-capable-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Internet capable buildpack" 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | 9 | 10 | if netcat -z -w 1 google.com 80; then 11 | echo "RESULT: Connected to the internet" 12 | else 13 | echo "RESULT: Disconnected from the internet" 14 | fi 15 | 16 | echo "---> Done" 17 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/internet-capable-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Detect: Internet capable buildpack 4 | 5 | ping -n 1 google.com 6 | 7 | if %ERRORLEVEL% equ 0 ( 8 | echo RESULT: Connected to the internet 9 | ) else ( 10 | echo RESULT: Disconnected from the internet 11 | ) 12 | 13 | echo ---- Done 14 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/internet-capable-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "internet/bp" 5 | version = "internet-bp-version" 6 | name = "Internet Capable Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack-dependency/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Local Meta-Buildpack Dependency" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack-dependency/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: Local Meta-Buildpack Dependency 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack-dependency/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack-dependency/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack-dependency/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "local/meta-bp-dep" 5 | version = "local-meta-bp-version" 6 | name = "Local Meta-Buildpack Dependency" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "local/meta-bp" 5 | version = "local-meta-bp-version" 6 | name = "Local Meta-Buildpack" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "local/meta-bp-dep" 11 | version = "local-meta-bp-version" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/meta-buildpack/package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "." 3 | 4 | [[dependencies]] 5 | uri = "../meta-buildpack-dependency" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/multi-platform-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "simple/layers" 5 | version = "simple-layers-version" 6 | name = "Simple Layers Buildpack" 7 | 8 | [[targets]] 9 | os = "linux" 10 | arch = "amd64" 11 | 12 | [[targets]] 13 | os = "linux" 14 | arch = "arm64" 15 | 16 | [[targets]] 17 | os = "windows" 18 | arch = "amd64" 19 | 20 | [[stacks]] 21 | id = "*" 22 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/multi-platform-buildpack/linux/amd64/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: NOOP Buildpack" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/multi-platform-buildpack/linux/amd64/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/multi-platform-buildpack/windows/amd64/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: NOOP Buildpack 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/multi-platform-buildpack/windows/amd64/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/nested-level-1-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "simple/nested-level-1" 5 | version = "nested-l1-version" 6 | name = "Nested Level One Buildpack" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "simple/nested-level-2" 11 | version = "nested-l2-version" 12 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/nested-level-2-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "simple/nested-level-2" 5 | version = "nested-l2-version" 6 | name = "Nested Level Two Buildpack" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "simple/layers" 11 | version = "simple-layers-version" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack-2/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: NOOP Buildpack (later version)" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack-2/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack-2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "noop.buildpack" 5 | version = "noop.buildpack.later-version" 6 | name = "NOOP Buildpack" 7 | homepage = "http://geocities.com/cool-bp" 8 | 9 | [[stacks]] 10 | id = "pack.test.stack" 11 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: NOOP Buildpack" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: NOOP Buildpack 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/noop-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "noop.buildpack" 5 | version = "noop.buildpack.version" 6 | name = "NOOP Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/not-in-builder-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Local Buildpack" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/not-in-builder-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: Local Buildpack 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/not-in-builder-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/not-in-builder-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/not-in-builder-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "local/bp" 5 | version = "local-bp-version" 6 | name = "Local Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/other-stack-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Other Stack Buildpack" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/other-stack-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo ---- Build: Other Stack Buildpack 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/other-stack-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/other-stack-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/other-stack-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "other/stack/bp" 5 | version = "other-stack-version" 6 | name = "Other Stack Buildpack" 7 | 8 | [[stacks]] 9 | id = "other.stack" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Build: Read Env Buildpack" 4 | 5 | set -o errexit 6 | set -o nounset 7 | set -o pipefail 8 | 9 | launch_dir=$1 10 | platform_dir=$2 11 | 12 | ## makes a launch layer 13 | if [[ -f "$platform_dir/env/ENV1_CONTENTS" ]]; then 14 | echo "making env1 layer" 15 | mkdir "$launch_dir/env1-launch-layer" 16 | contents=$(cat "$platform_dir/env/ENV1_CONTENTS") 17 | echo "$contents" > "$launch_dir/env1-launch-layer/env1-launch-dep" 18 | ln -snf "$launch_dir/env1-launch-layer" env1-launch-deps 19 | echo "[types]" > "$launch_dir/env1-launch-layer.toml" 20 | echo "launch = true" >> "$launch_dir/env1-launch-layer.toml" 21 | fi 22 | 23 | ## makes a launch layer 24 | if [[ -f "$platform_dir/env/ENV2_CONTENTS" ]]; then 25 | echo "making env2 layer" 26 | mkdir "$launch_dir/env2-launch-layer" 27 | contents=$(cat "$platform_dir/env/ENV2_CONTENTS") 28 | echo "$contents" > "$launch_dir/env2-launch-layer/env2-launch-dep" 29 | ln -snf "$launch_dir/env2-launch-layer" env2-launch-deps 30 | echo "[types]" > "$launch_dir/env2-launch-layer.toml" 31 | echo "launch = true" >> "$launch_dir/env2-launch-layer.toml" 32 | fi 33 | 34 | echo "---> Done" 35 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal EnableDelayedExpansion 3 | 4 | set launch_dir=%1 5 | set platform_dir=%2 6 | 7 | :: makes a launch layer 8 | if exist %platform_dir%\env\ENV1_CONTENTS ( 9 | echo making env1 layer 10 | mkdir %launch_dir%\env1-launch-layer 11 | set /p contents=<%platform_dir%\env\ENV1_CONTENTS 12 | echo !contents!> %launch_dir%\env1-launch-layer\env1-launch-dep 13 | mklink /j env1-launch-deps %launch_dir%\env1-launch-layer 14 | echo [types] > %launch_dir%\env1-launch-layer.toml 15 | echo launch = true >> %launch_dir%\env1-launch-layer.toml 16 | ) 17 | 18 | :: makes a launch layer 19 | if exist %platform_dir%\env\ENV2_CONTENTS ( 20 | echo making env2 layer 21 | mkdir %launch_dir%\env2-launch-layer 22 | set /p contents=<%platform_dir%\env\ENV2_CONTENTS 23 | echo !contents!> %launch_dir%\env2-launch-layer\env2-launch-dep 24 | mklink /j env2-launch-deps %launch_dir%\env2-launch-layer 25 | echo [types] > %launch_dir%\env2-launch-layer.toml 26 | echo launch = true >> %launch_dir%\env2-launch-layer.toml 27 | ) 28 | 29 | echo --- Done 30 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> DETECT: Printenv buildpack" 4 | 5 | set -o errexit 6 | set -o pipefail 7 | 8 | platform_dir=$1 9 | 10 | if [[ ! -f $platform_dir/env/DETECT_ENV_BUILDPACK ]]; then 11 | exit 1 12 | fi -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo DETECT: Printenv buildpack 4 | 5 | set platform_dir=%1 6 | 7 | if not exist %platform_dir%\env\DETECT_ENV_BUILDPACK ( 8 | exit 1 9 | ) 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "read/env" 5 | version = "read-env-version" 6 | name = "Read Env Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-extension/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Detect: Read Env Extension" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-env-extension/bin/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Generate: Read Env Extension" 4 | 5 | # 1. Get args 6 | output_dir=$CNB_OUTPUT_DIR 7 | 8 | # 2. Generate build.Dockerfile 9 | cat >> "${output_dir}/build.Dockerfile" <>"${output_dir}/run.Dockerfile" < /from-ext.txt 27 | 28 | ARG user_id 29 | USER \${user_id} 30 | EOL 31 | fi 32 | 33 | if [[ -z "$EXT_RUN_SWITCH" ]]; then 34 | echo "Skipping run image switch, not requested..." 35 | else 36 | echo "Generating run.Dockerfile for run image switch..." 37 | cat >>"${output_dir}/run.Dockerfile" < Build: Volume Buildpack" 6 | 7 | set -o errexit 8 | set -o nounset 9 | set -o pipefail 10 | 11 | echo "Build: Reading file '${TEST_FILE_PATH}': $(< "${TEST_FILE_PATH}")" 12 | 13 | echo "---> Done" 14 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-volume-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo --- Build: Volume Buildpack 4 | 5 | set /p content=<%TEST_FILE_PATH% 6 | echo Build: Reading file '%TEST_FILE_PATH%': %content% 7 | 8 | echo --- Done 9 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-volume-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TEST_FILE_PATH=${TEST_FILE_PATH:?"env var must be set"} 4 | 5 | echo "---> Detect: Volume Buildpack" 6 | 7 | set -o errexit 8 | set -o nounset 9 | set -o pipefail 10 | 11 | echo "Detect: Reading file '${TEST_FILE_PATH}': $(< "${TEST_FILE_PATH}")" 12 | 13 | echo "---> Done" 14 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-volume-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo --- Detect: Volume Buildpack 4 | 5 | set /p content=<%TEST_FILE_PATH% 6 | echo Detect: Reading file '%TEST_FILE_PATH%': %content% 7 | 8 | echo --- Done 9 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-volume-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "volume/bp" 5 | version = "volume-bp-version" 6 | name = "Volume Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-write-volume-buildpack/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TEST_FILE_PATH=${BUILD_TEST_FILE_PATH:?"env var must be set"} 4 | 5 | echo "---> Build: Read/Write Volume Buildpack" 6 | 7 | set -o errexit 8 | set -o nounset 9 | set -o pipefail 10 | 11 | echo "Build: Writing file '${TEST_FILE_PATH}': $(echo "some-content" > "${TEST_FILE_PATH}" && echo "written" || echo "failed")" 12 | echo "Build: Reading file '${TEST_FILE_PATH}': $(< "${TEST_FILE_PATH}")" 13 | 14 | echo "---> Done" 15 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-write-volume-buildpack/bin/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set TEST_FILE_PATH=%BUILD_TEST_FILE_PATH% 4 | 5 | echo --- Build: Read/Write Volume Buildpack 6 | 7 | echo some-content> %TEST_FILE_PATH% 8 | if exist %TEST_FILE_PATH% ( 9 | echo Build: Writing file '%TEST_FILE_PATH%': written 10 | ) else ( 11 | echo Build: Writing file '%TEST_FILE_PATH%': failed 12 | ) 13 | 14 | set /p content=<%TEST_FILE_PATH% 15 | echo Build: Reading file '%TEST_FILE_PATH%': %content% 16 | 17 | echo --- Done 18 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-write-volume-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TEST_FILE_PATH=${DETECT_TEST_FILE_PATH:?"env var must be set"} 4 | 5 | echo "---> Detect: Read/Write Volume Buildpack" 6 | 7 | set -o errexit 8 | set -o nounset 9 | set -o pipefail 10 | 11 | echo "Detect: Writing file '${TEST_FILE_PATH}': $(echo "some-content" > "${TEST_FILE_PATH}" && echo "written" || echo "failed")" 12 | echo "Detect: Reading file '${TEST_FILE_PATH}': $(< "${TEST_FILE_PATH}")" 13 | 14 | echo "---> Done" 15 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-write-volume-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set TEST_FILE_PATH=%DETECT_TEST_FILE_PATH% 4 | 5 | echo --- Detect: Read/Write Volume Buildpack 6 | 7 | echo some-content> %TEST_FILE_PATH% 8 | if exist %TEST_FILE_PATH% ( 9 | echo Detect: Writing file '%TEST_FILE_PATH%': written 10 | ) else ( 11 | echo Detect: Writing file '%TEST_FILE_PATH%': failed 12 | ) 13 | 14 | set /p content=<%TEST_FILE_PATH% 15 | echo Detect: Reading file '%TEST_FILE_PATH%': %content% 16 | 17 | echo --- Done 18 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/read-write-volume-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "rw-volume/bp" 5 | version = "rw-volume-bp-version" 6 | name = "Read/Write Volume Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack-different-sha/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack-different-sha/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack-different-sha/bin/extra_file.txt: -------------------------------------------------------------------------------- 1 | Just some extra content to change the sha256 of this buildpack :) -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack-different-sha/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "simple/layers" 5 | version = "simple-layers-version" 6 | name = "Simple Layers Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## always detect 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack/bin/detect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: always detect 3 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "simple/layers" 5 | version = "simple-layers-version" 6 | name = "Simple Layers Buildpack" 7 | 8 | [[stacks]] 9 | id = "pack.test.stack" 10 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-extension/bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Detect: Simple Layers Extension" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-extension/bin/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---> Generate: Simple Layers Extension" 4 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-extension/extension.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [extension] 4 | id = "simple/layers" 5 | version = "simple-layers-version" 6 | name = "Simple Layers Extension" 7 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_buildpacks/simple-layers-parent-buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.7" 2 | 3 | [buildpack] 4 | id = "simple/layers/parent" 5 | version = "simple-layers-parent-version" 6 | name = "Simple Layers Parent Buildpack" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "simple/layers" 11 | version = "simple-layers-version" -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/create-stack.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | dir="$(cd $(dirname $0) && pwd)" 4 | os=$(docker info --format '{{json .}}' | jq -r .OSType) 5 | 6 | docker build --tag pack-test/build "$dir"/$os/build 7 | docker build --tag pack-test/run "$dir"/$os/run 8 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/linux/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | 3 | ENV CNB_USER_ID=2222 4 | ENV CNB_GROUP_ID=3333 5 | 6 | RUN \ 7 | groupadd pack --gid 3333 && \ 8 | useradd --uid 2222 --gid 3333 -m -s /bin/bash pack 9 | 10 | RUN apt-get update && apt-get -yq install netcat 11 | LABEL io.buildpacks.stack.id=pack.test.stack 12 | LABEL io.buildpacks.stack.mixins="[\"mixinA\", \"build:mixinTwo\", \"netcat\", \"mixin3\"]" 13 | 14 | USER pack 15 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/linux/run/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | 3 | ENV CNB_USER_ID=2222 4 | ENV CNB_GROUP_ID=3333 5 | 6 | RUN \ 7 | groupadd pack --gid 3333 && \ 8 | useradd --uid 2222 --gid 3333 -m -s /bin/bash pack 9 | 10 | RUN apt-get update && apt-get -yq install netcat 11 | LABEL io.buildpacks.stack.id=pack.test.stack 12 | LABEL io.buildpacks.stack.mixins="[\"mixinA\", \"netcat\", \"mixin3\"]" 13 | 14 | USER pack 15 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/windows/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/windows/nanoserver:1809 2 | 3 | # non-zero sets all user-owned directories to BUILTIN\Users 4 | ENV CNB_USER_ID=1 5 | ENV CNB_GROUP_ID=1 6 | 7 | USER ContainerAdministrator 8 | 9 | RUN net users /ADD pack /passwordreq:no /expires:never 10 | 11 | LABEL io.buildpacks.stack.id=pack.test.stack 12 | LABEL io.buildpacks.stack.mixins="[\"mixinA\", \"build:mixinTwo\", \"netcat\", \"mixin3\"]" 13 | 14 | USER pack 15 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/windows/run/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.17-nanoserver-1809 AS gobuild 2 | 3 | # bake in a simple server util 4 | COPY server.go /util/server.go 5 | WORKDIR /util 6 | RUN go build server.go 7 | 8 | FROM mcr.microsoft.com/windows/nanoserver:1809 9 | 10 | COPY --from=gobuild /util/server.exe /util/server.exe 11 | 12 | # non-zero sets all user-owned directories to BUILTIN\Users 13 | ENV CNB_USER_ID=1 14 | ENV CNB_GROUP_ID=1 15 | 16 | USER ContainerAdministrator 17 | 18 | RUN net users /ADD pack /passwordreq:no /expires:never 19 | 20 | LABEL io.buildpacks.stack.id=pack.test.stack 21 | LABEL io.buildpacks.stack.mixins="[\"mixinA\", \"netcat\", \"mixin3\"]" 22 | 23 | USER pack 24 | 25 | # launcher requires a non-empty PATH to workaround https://github.com/buildpacks/pack/issues/800 26 | ENV PATH c:\\Windows\\system32;C:\\Windows 27 | -------------------------------------------------------------------------------- /acceptance/testdata/mock_stack/windows/run/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | -p="8080": port to expose 3 | -g: file globs to read (comma-separated) 4 | */ 5 | package main 6 | 7 | import ( 8 | "flag" 9 | "log" 10 | "net/http" 11 | "os" 12 | "path/filepath" 13 | "strings" 14 | ) 15 | 16 | func main() { 17 | port := flag.String("p", "8080", "port to expose") 18 | glob := flag.String("g", "", "file globs to read") 19 | flag.Parse() 20 | 21 | var resp []string 22 | 23 | globs := strings.Split(*glob, ",") 24 | for _, glob := range globs { 25 | paths, err := filepath.Glob(strings.TrimSpace(glob)) 26 | if err != nil { 27 | panic(err.Error()) 28 | } 29 | 30 | for _, path := range paths { 31 | contents, err := os.ReadFile(filepath.Clean(path)) 32 | if err != nil { 33 | panic(err.Error()) 34 | } 35 | 36 | resp = append(resp, string(contents)) 37 | } 38 | } 39 | 40 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 41 | w.Write([]byte(strings.Join(resp, "\n"))) 42 | }) 43 | 44 | log.Printf("Serving %s on HTTP port: %s\n", *glob, *port) 45 | log.Fatal(http.ListenAndServe(":"+*port, nil)) 46 | } 47 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/.gitattributes: -------------------------------------------------------------------------------- 1 | *.txt text eol=lf 2 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/builder.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | id = "read/env" 3 | version = "read-env-version" 4 | uri = "read-env-buildpack.tgz" 5 | 6 | [[buildpacks]] 7 | # intentionally missing id/version as they are optional 8 | uri = "noop-buildpack.tgz" 9 | 10 | [[buildpacks]] 11 | # noop-buildpack-2 has the same id but a different version compared to noop-buildpack 12 | uri = "noop-buildpack-2.tgz" 13 | 14 | {{- if .package_image_name}} 15 | [[buildpacks]] 16 | image = "{{.package_image_name}}" 17 | {{- end}} 18 | 19 | [[order]] 20 | {{- if .package_id}} 21 | [[order.group]] 22 | id = "{{.package_id}}" 23 | # intentionlly missing version to test support 24 | {{- end}} 25 | 26 | [[order.group]] 27 | id = "read/env" 28 | version = "read-env-version" 29 | optional = true 30 | 31 | [stack] 32 | id = "pack.test.stack" 33 | build-image = "pack-test/build" 34 | run-image = "pack-test/run" 35 | run-image-mirrors = ["{{.run_image_mirror}}"] 36 | 37 | [lifecycle] 38 | {{- if .lifecycle_uri}} 39 | uri = "{{.lifecycle_uri}}" 40 | {{- end}} 41 | {{- if .lifecycle_version}} 42 | version = "{{.lifecycle_version}}" 43 | {{- end}} 44 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/builder_multi_platform-no-targets.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | id = "simple/layers" 3 | version = "simple-layers-version" 4 | uri = "{{ .BuildpackURI }}" 5 | 6 | [[order]] 7 | [[order.group]] 8 | id = "simple/layers" 9 | version = "simple-layers-version" 10 | 11 | [build] 12 | image = "{{ .BuildImage }}" 13 | 14 | [run] 15 | [[run.images]] 16 | image = "{{ .RunImage }}" 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/builder_multi_platform.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | id = "simple/layers" 3 | version = "simple-layers-version" 4 | uri = "{{ .BuildpackURI }}" 5 | 6 | [[order]] 7 | [[order.group]] 8 | id = "simple/layers" 9 | version = "simple-layers-version" 10 | 11 | # Targets the buildpack will work with 12 | [[targets]] 13 | os = "linux" 14 | arch = "amd64" 15 | 16 | [[targets]] 17 | os = "windows" 18 | arch = "amd64" 19 | 20 | [build] 21 | image = "{{ .BuildImage }}" 22 | 23 | [run] 24 | [[run.images]] 25 | image = "{{ .RunImage }}" 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_X.Y.Z_builder_output.txt: -------------------------------------------------------------------------------- 1 | Files like these represent the expected output of calling `pack inspect-builder` on a builder created with pack vX.Y.Z -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_buildpack_output.txt: -------------------------------------------------------------------------------- 1 | Inspecting buildpack: '{{ .buildpack_name }}' 2 | 3 | {{ .buildpack_source }}: 4 | 5 | Stacks: 6 | ID: pack.test.stack 7 | Mixins: 8 | (none) 9 | 10 | Buildpacks: 11 | ID NAME VERSION HOMEPAGE 12 | simple/layers Simple Layers Buildpack simple-layers-version - 13 | simple/layers/parent Simple Layers Parent Buildpack simple-layers-parent-version - 14 | 15 | Detection Order: 16 | └ Group #1: 17 | └ simple/layers/parent@simple-layers-parent-version 18 | └ Group #1: 19 | └ simple/layers@simple-layers-version 20 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_image_local_output.toml: -------------------------------------------------------------------------------- 1 | image_name = "{{.image_name}}" 2 | 3 | [local_info] 4 | stack = "pack.test.stack" 5 | rebasable = {{.rebasable}} 6 | 7 | [local_info.base_image] 8 | top_layer = "{{.base_image_top_layer}}" 9 | reference = "{{.base_image_id}}" 10 | 11 | [[local_info.run_images]] 12 | name = "{{.run_image_local_mirror}}" 13 | user_configured = true 14 | 15 | [[local_info.run_images]] 16 | name = "pack-test/run" 17 | 18 | [[local_info.run_images]] 19 | name = "{{.run_image_mirror}}" 20 | 21 | [[local_info.buildpacks]] 22 | id = "simple/layers" 23 | version = "simple-layers-version" 24 | 25 | [[local_info.processes]] 26 | type = "web" 27 | shell = "bash" 28 | command = "{{ ( StringsEscapeBackslash .web_command ) }}" 29 | default = true 30 | args = [ "8080" ] 31 | working-dir = "{{ ( StringsEscapeBackslash .image_workdir ) }}" 32 | 33 | [[local_info.processes]] 34 | type = "hello" 35 | shell = "" 36 | command = "{{.hello_command}}" 37 | default = false 38 | args = [ {{ ( StringsJoin (StringsDoubleQuote .hello_args) ",") }} ] 39 | working-dir = "{{ ( StringsEscapeBackslash .image_workdir ) }}" 40 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_image_local_output.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | image_name: "{{.image_name}}" 3 | remote_info: 4 | local_info: 5 | stack: pack.test.stack 6 | rebasable: {{.rebasable}} 7 | base_image: 8 | top_layer: "{{.base_image_top_layer}}" 9 | reference: "{{.base_image_id}}" 10 | run_images: 11 | - name: "{{.run_image_local_mirror}}" 12 | user_configured: true 13 | - name: pack-test/run 14 | - name: "{{.run_image_mirror}}" 15 | buildpacks: 16 | - id: simple/layers 17 | version: simple-layers-version 18 | extensions: [] 19 | processes: 20 | - type: web 21 | shell: bash 22 | command: "{{ ( StringsEscapeBackslash .web_command ) }}" 23 | default: true 24 | args: 25 | - '8080' 26 | working-dir: "{{ ( StringsEscapeBackslash .image_workdir ) }}" 27 | - type: hello 28 | shell: '' 29 | command: "{{.hello_command}}" 30 | default: false 31 | args: [ {{ ( StringsJoin (StringsDoubleQuote .hello_args) ",") }} ] 32 | working-dir: "{{ ( StringsEscapeBackslash .image_workdir ) }}" 33 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_image_published_output.toml: -------------------------------------------------------------------------------- 1 | image_name = "{{.image_name}}" 2 | 3 | [remote_info] 4 | stack = "pack.test.stack" 5 | rebasable = {{.rebasable}} 6 | 7 | [remote_info.base_image] 8 | top_layer = "{{.base_image_top_layer}}" 9 | reference = "{{.base_image_ref}}" 10 | 11 | [[remote_info.run_images]] 12 | name = "pack-test/run" 13 | 14 | [[remote_info.run_images]] 15 | name = "{{.run_image_mirror}}" 16 | 17 | [[remote_info.buildpacks]] 18 | id = "simple/layers" 19 | version = "simple-layers-version" 20 | 21 | [[remote_info.processes]] 22 | type = "web" 23 | shell = "bash" 24 | command = "{{( StringsEscapeBackslash .web_command )}}" 25 | default = true 26 | args = [ "8080" ] 27 | working-dir = "{{ ( StringsEscapeBackslash .image_workdir ) }}" 28 | 29 | [[remote_info.processes]] 30 | type = "hello" 31 | shell = "" 32 | command = "{{.hello_command}}" 33 | default = false 34 | args = [ {{ ( StringsJoin (StringsDoubleQuote .hello_args) "," ) }} ] 35 | working-dir = "{{ ( StringsEscapeBackslash .image_workdir ) }}" 36 | 37 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/inspect_image_published_output.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | image_name: "{{.image_name}}" 3 | local_info: null 4 | remote_info: 5 | stack: pack.test.stack 6 | rebasable: {{.rebasable}} 7 | base_image: 8 | top_layer: "{{.base_image_top_layer}}" 9 | reference: "{{.base_image_ref}}" 10 | run_images: 11 | - name: pack-test/run 12 | - name: "{{.run_image_mirror}}" 13 | buildpacks: 14 | - id: simple/layers 15 | version: simple-layers-version 16 | extensions: [] 17 | processes: 18 | - type: web 19 | shell: bash 20 | command: "{{( StringsEscapeBackslash .web_command )}}" 21 | default: true 22 | args: 23 | - '8080' 24 | working-dir: "{{ ( StringsEscapeBackslash .image_workdir ) }}" 25 | - type: hello 26 | shell: '' 27 | command: "{{.hello_command}}" 28 | default: false 29 | args: [ {{ ( StringsJoin (StringsDoubleQuote .hello_args) "," ) }} ] 30 | working-dir: "{{ ( StringsEscapeBackslash .image_workdir ) }}" 31 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/invalid_builder.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | url = "read-env-buildpack.tgz" 3 | 4 | [stack] 5 | id = "pack.test.stack" 6 | build-image = "pack-test/build" 7 | run-image = "pack-test/run" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/invalid_package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/nested-level-1-buildpack_package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "nested-level-1-buildpack.tgz" 3 | 4 | [[dependencies]] 5 | image = "{{.simple_layers_buildpack}}" 6 | 7 | [[dependencies]] 8 | image = "{{.nested_level_2_buildpack}}" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/nested-level-2-buildpack_package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "nested-level-2-buildpack.tgz" 3 | 4 | [[dependencies]] 5 | image = "{{.simple_layers_buildpack}}" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "simple-layers-buildpack.tgz" 3 | 4 | [platform] 5 | os = "{{ .OS }}" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/package_aggregate.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "{{ .BuildpackURI }}" 3 | 4 | [[dependencies]] 5 | image = "{{ .PackageName }}" 6 | 7 | [platform] 8 | os = "{{ .OS }}" 9 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/package_for_build_cmd.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "simple-layers-parent-buildpack" 3 | 4 | [[dependencies]] 5 | uri = "simple-layers-buildpack" 6 | 7 | [platform] 8 | os = "{{ .OS }}" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/package_multi_platform.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "{{ .BuildpackURI }}" 3 | 4 | [[dependencies]] 5 | uri = "{{ .PackageName }}" 6 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/report_output.txt: -------------------------------------------------------------------------------- 1 | Pack: 2 | Version: {{ .Version }} 3 | OS/Arch: {{ .OS }}/{{ .Arch }} 4 | 5 | Default Lifecycle Version: 0.20.8 6 | 7 | Supported Platform APIs: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13 8 | 9 | Config: 10 | default-builder-image = "{{ .DefaultBuilder }}" 11 | experimental = true 12 | layout-repo-dir = "{{ .LayoutRepoDir }}" 13 | -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/simple-layers-buildpack-different-sha_package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "simple-layers-buildpack-different-sha.tgz" -------------------------------------------------------------------------------- /acceptance/testdata/pack_fixtures/simple-layers-buildpack_package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "simple-layers-buildpack.tgz" -------------------------------------------------------------------------------- /acceptance/testdata/pack_previous_fixtures_overrides/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/acceptance/testdata/pack_previous_fixtures_overrides/.gitkeep -------------------------------------------------------------------------------- /builder/buildpack_identifier.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | type BpIdentifier interface { 4 | Id() string 5 | } 6 | -------------------------------------------------------------------------------- /builder/detection_order.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | import ( 4 | "github.com/buildpacks/pack/pkg/dist" 5 | ) 6 | 7 | type DetectionOrderEntry struct { 8 | dist.ModuleRef `yaml:",inline"` 9 | Cyclical bool `json:"cyclic,omitempty" yaml:"cyclic,omitempty" toml:"cyclic,omitempty"` 10 | GroupDetectionOrder DetectionOrder `json:"buildpacks,omitempty" yaml:"buildpacks,omitempty" toml:"buildpacks,omitempty"` 11 | } 12 | 13 | type DetectionOrder []DetectionOrderEntry 14 | 15 | const ( 16 | OrderDetectionMaxDepth = -1 17 | OrderDetectionNone = 0 18 | ) 19 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | notify: 3 | after_n_builds: 4 4 | 5 | coverage: 6 | round: up 7 | status: 8 | project: 9 | default: 10 | threshold: 1% 11 | patch: 12 | default: 13 | threshold: 10% 14 | 15 | comment: 16 | layout: "reach,diff,flags" 17 | require_changes: yes 18 | after_n_builds: 4 -------------------------------------------------------------------------------- /golangci.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | linters: 3 | default: none 4 | enable: 5 | - bodyclose 6 | - dogsled 7 | - gocritic 8 | - govet 9 | - ineffassign 10 | - misspell 11 | - nakedret 12 | - revive 13 | - rowserrcheck 14 | - staticcheck 15 | - unconvert 16 | - unused 17 | - whitespace 18 | settings: 19 | revive: 20 | rules: 21 | - name: error-strings 22 | disabled: true 23 | exclusions: 24 | generated: lax 25 | presets: 26 | - comments 27 | - common-false-positives 28 | - legacy 29 | - std-error-handling 30 | paths: 31 | - third_party$ 32 | - builtin$ 33 | - examples$ 34 | formatters: 35 | enable: 36 | - goimports 37 | settings: 38 | goimports: 39 | local-prefixes: 40 | - github.com/buildpacks/pack 41 | exclusions: 42 | generated: lax 43 | paths: 44 | - third_party$ 45 | - builtin$ 46 | - examples$ 47 | issues: 48 | default: info 49 | rules: 50 | - linters: 51 | - staticcheck: info -------------------------------------------------------------------------------- /internal/build/fakes/cache.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/buildpacks/pack/pkg/cache" 7 | ) 8 | 9 | type FakeCache struct { 10 | ReturnForType cache.Type 11 | ReturnForClear error 12 | ReturnForName string 13 | 14 | TypeCallCount int 15 | ClearCallCount int 16 | NameCallCount int 17 | } 18 | 19 | func NewFakeCache() *FakeCache { 20 | return &FakeCache{} 21 | } 22 | 23 | func (f *FakeCache) Type() cache.Type { 24 | f.TypeCallCount++ 25 | return f.ReturnForType 26 | } 27 | 28 | func (f *FakeCache) Clear(ctx context.Context) error { 29 | f.ClearCallCount++ 30 | return f.ReturnForClear 31 | } 32 | func (f *FakeCache) Name() string { 33 | f.NameCallCount++ 34 | return f.ReturnForName 35 | } 36 | -------------------------------------------------------------------------------- /internal/build/fakes/fake_phase.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import "context" 4 | 5 | type FakePhase struct { 6 | CleanupCallCount int 7 | RunCallCount int 8 | } 9 | 10 | func (p *FakePhase) Cleanup() error { 11 | p.CleanupCallCount++ 12 | 13 | return nil 14 | } 15 | 16 | func (p *FakePhase) Run(ctx context.Context) error { 17 | p.RunCallCount++ 18 | 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /internal/build/fakes/fake_phase_factory.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import "github.com/buildpacks/pack/internal/build" 4 | 5 | type FakePhaseFactory struct { 6 | NewCallCount int 7 | ReturnForNew build.RunnerCleaner 8 | NewCalledWithProvider []*build.PhaseConfigProvider 9 | } 10 | 11 | func NewFakePhaseFactory(ops ...func(*FakePhaseFactory)) *FakePhaseFactory { 12 | fakePhaseFactory := &FakePhaseFactory{ 13 | ReturnForNew: &FakePhase{}, 14 | } 15 | 16 | for _, op := range ops { 17 | op(fakePhaseFactory) 18 | } 19 | 20 | return fakePhaseFactory 21 | } 22 | 23 | func WhichReturnsForNew(phase build.RunnerCleaner) func(*FakePhaseFactory) { 24 | return func(factory *FakePhaseFactory) { 25 | factory.ReturnForNew = phase 26 | } 27 | } 28 | 29 | func (f *FakePhaseFactory) New(phaseConfigProvider *build.PhaseConfigProvider) build.RunnerCleaner { 30 | f.NewCallCount++ 31 | f.NewCalledWithProvider = append(f.NewCalledWithProvider, phaseConfigProvider) 32 | 33 | return f.ReturnForNew 34 | } 35 | -------------------------------------------------------------------------------- /internal/build/testdata/fake-app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/internal/build/testdata/fake-app.zip -------------------------------------------------------------------------------- /internal/build/testdata/fake-app/fake-app-file: -------------------------------------------------------------------------------- 1 | fake-app-contents -------------------------------------------------------------------------------- /internal/build/testdata/fake-app/fake-app-symlink: -------------------------------------------------------------------------------- 1 | fake-app-file -------------------------------------------------------------------------------- /internal/build/testdata/fake-app/file-to-ignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/internal/build/testdata/fake-app/file-to-ignore -------------------------------------------------------------------------------- /internal/build/testdata/fake-lifecycle/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang 2 | 3 | RUN mkdir /lifecycle 4 | WORKDIR /go/src/step 5 | COPY . . 6 | RUN GO111MODULE=on go build -o /cnb/lifecycle/phase ./phase.go 7 | 8 | ENV CNB_USER_ID 111 9 | ENV CNB_GROUP_ID 222 10 | 11 | LABEL io.buildpacks.stack.id="test.stack" 12 | LABEL io.buildpacks.builder.metadata="{\"buildpacks\":[{\"id\":\"just/buildpack.id\",\"version\":\"1.2.3\"}],\"lifecycle\":{\"version\":\"0.5.0\",\"api\":{\"buildpack\":\"0.2\",\"platform\":\"0.1\"}}}" -------------------------------------------------------------------------------- /internal/build/testdata/fake-lifecycle/go.mod: -------------------------------------------------------------------------------- 1 | module step 2 | 3 | require ( 4 | github.com/buildpacks/lifecycle v0.5.1-0.20191212164213-3b2b120be460 5 | github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 6 | github.com/google/go-containerregistry v0.0.0-20191018211754-b77a90c667af 7 | ) 8 | 9 | go 1.17 10 | -------------------------------------------------------------------------------- /internal/builder/fakes/fake_detection_calculator.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/builder" 5 | "github.com/buildpacks/pack/pkg/dist" 6 | ) 7 | 8 | type FakeDetectionCalculator struct { 9 | ReturnForOrder builder.DetectionOrder 10 | 11 | ErrorForOrder error 12 | 13 | ReceivedTopOrder dist.Order 14 | ReceivedLayers dist.ModuleLayers 15 | ReceivedDepth int 16 | } 17 | 18 | func (c *FakeDetectionCalculator) Order( 19 | topOrder dist.Order, 20 | layers dist.ModuleLayers, 21 | depth int, 22 | ) (builder.DetectionOrder, error) { 23 | c.ReceivedTopOrder = topOrder 24 | c.ReceivedLayers = layers 25 | c.ReceivedDepth = depth 26 | 27 | return c.ReturnForOrder, c.ErrorForOrder 28 | } 29 | -------------------------------------------------------------------------------- /internal/builder/fakes/fake_inspectable.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | type FakeInspectable struct { 4 | ReturnForLabel string 5 | 6 | ErrorForLabel error 7 | 8 | ReceivedName string 9 | } 10 | 11 | func (f *FakeInspectable) Label(name string) (string, error) { 12 | f.ReceivedName = name 13 | 14 | return f.ReturnForLabel, f.ErrorForLabel 15 | } 16 | -------------------------------------------------------------------------------- /internal/builder/fakes/fake_inspectable_fetcher.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/buildpacks/pack/internal/builder" 7 | "github.com/buildpacks/pack/pkg/image" 8 | ) 9 | 10 | type FakeInspectableFetcher struct { 11 | InspectableToReturn *FakeInspectable 12 | ErrorToReturn error 13 | 14 | CallCount int 15 | 16 | ReceivedName string 17 | ReceivedDaemon bool 18 | ReceivedPullPolicy image.PullPolicy 19 | } 20 | 21 | func (f *FakeInspectableFetcher) Fetch(ctx context.Context, name string, options image.FetchOptions) (builder.Inspectable, error) { 22 | f.CallCount++ 23 | 24 | f.ReceivedName = name 25 | f.ReceivedDaemon = options.Daemon 26 | f.ReceivedPullPolicy = options.PullPolicy 27 | 28 | return f.InspectableToReturn, f.ErrorToReturn 29 | } 30 | -------------------------------------------------------------------------------- /internal/builder/fakes/fake_label_manager_factory.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import "github.com/buildpacks/pack/internal/builder" 4 | 5 | type FakeLabelManagerFactory struct { 6 | BuilderLabelManagerToReturn builder.LabelInspector 7 | 8 | ReceivedInspectable builder.Inspectable 9 | } 10 | 11 | func NewFakeLabelManagerFactory(builderLabelManagerToReturn builder.LabelInspector) *FakeLabelManagerFactory { 12 | return &FakeLabelManagerFactory{ 13 | BuilderLabelManagerToReturn: builderLabelManagerToReturn, 14 | } 15 | } 16 | 17 | func (f *FakeLabelManagerFactory) BuilderLabelManager(inspectable builder.Inspectable) builder.LabelInspector { 18 | f.ReceivedInspectable = inspectable 19 | 20 | return f.BuilderLabelManagerToReturn 21 | } 22 | -------------------------------------------------------------------------------- /internal/builder/label_manager_provider.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | type LabelManagerProvider struct{} 4 | 5 | func NewLabelManagerProvider() *LabelManagerProvider { 6 | return &LabelManagerProvider{} 7 | } 8 | 9 | func (p *LabelManagerProvider) BuilderLabelManager(inspectable Inspectable) LabelInspector { 10 | return NewLabelManager(inspectable) 11 | } 12 | -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.3/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [api] 5 | buildpack = "0.2" 6 | platform = "0.3" -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /internal/builder/testdata/lifecycle/platform-0.4/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [apis] 5 | [apis.buildpack] 6 | deprecated = [] 7 | supported = ["0.2", "0.3", "0.4", "0.9"] 8 | 9 | [apis.platform] 10 | deprecated = ["0.2"] 11 | supported = ["0.3", "0.4"] -------------------------------------------------------------------------------- /internal/builder/writer/json.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | ) 7 | 8 | type JSON struct { 9 | StructuredFormat 10 | } 11 | 12 | func NewJSON() BuilderWriter { 13 | return &JSON{ 14 | StructuredFormat: StructuredFormat{ 15 | MarshalFunc: func(i interface{}) ([]byte, error) { 16 | buf, err := json.Marshal(i) 17 | if err != nil { 18 | return []byte{}, err 19 | } 20 | formattedBuf := bytes.NewBuffer(nil) 21 | err = json.Indent(formattedBuf, buf, "", " ") 22 | return formattedBuf.Bytes(), err 23 | }, 24 | }, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /internal/builder/writer/toml.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | 6 | "github.com/pelletier/go-toml" 7 | ) 8 | 9 | type TOML struct { 10 | StructuredFormat 11 | } 12 | 13 | func NewTOML() BuilderWriter { 14 | return &TOML{ 15 | StructuredFormat: StructuredFormat{ 16 | MarshalFunc: func(v interface{}) ([]byte, error) { 17 | buf := bytes.NewBuffer(nil) 18 | err := toml.NewEncoder(buf).Order(toml.OrderPreserve).PromoteAnonymous(false).Encode(v) 19 | if err != nil { 20 | return []byte{}, err 21 | } 22 | return buf.Bytes(), nil 23 | }, 24 | }, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /internal/builder/writer/yaml.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | 6 | "gopkg.in/yaml.v3" 7 | ) 8 | 9 | type YAML struct { 10 | StructuredFormat 11 | } 12 | 13 | func NewYAML() BuilderWriter { 14 | return &YAML{ 15 | StructuredFormat: StructuredFormat{ 16 | MarshalFunc: func(v interface{}) ([]byte, error) { 17 | buf := bytes.NewBuffer(nil) 18 | if err := yaml.NewEncoder(buf).Encode(v); err != nil { 19 | return []byte{}, err 20 | } 21 | return buf.Bytes(), nil 22 | }, 23 | }, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/commands/builder.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | builderwriter "github.com/buildpacks/pack/internal/builder/writer" 7 | "github.com/buildpacks/pack/internal/config" 8 | "github.com/buildpacks/pack/pkg/logging" 9 | ) 10 | 11 | func NewBuilderCommand(logger logging.Logger, cfg config.Config, client PackClient) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "builder", 14 | Aliases: []string{"builders"}, 15 | Short: "Interact with builders", 16 | RunE: nil, 17 | } 18 | 19 | cmd.AddCommand(BuilderCreate(logger, cfg, client)) 20 | cmd.AddCommand(BuilderInspect(logger, cfg, client, builderwriter.NewFactory())) 21 | cmd.AddCommand(BuilderSuggest(logger, client)) 22 | AddHelpFlag(cmd, "builder") 23 | return cmd 24 | } 25 | -------------------------------------------------------------------------------- /internal/commands/builder_suggest.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | func BuilderSuggest(logger logging.Logger, inspector BuilderInspector) *cobra.Command { 10 | cmd := &cobra.Command{ 11 | Use: "suggest", 12 | Args: cobra.NoArgs, 13 | Short: "List the recommended builders", 14 | Example: "pack builder suggest", 15 | Run: func(cmd *cobra.Command, s []string) { 16 | suggestBuilders(logger, inspector) 17 | }, 18 | } 19 | 20 | AddHelpFlag(cmd, "suggest") 21 | return cmd 22 | } 23 | -------------------------------------------------------------------------------- /internal/commands/buildpack.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | func NewBuildpackCommand(logger logging.Logger, cfg config.Config, client PackClient, packageConfigReader PackageConfigReader) *cobra.Command { 11 | cmd := &cobra.Command{ 12 | Use: "buildpack", 13 | Aliases: []string{"buildpacks"}, 14 | Short: "Interact with buildpacks", 15 | RunE: nil, 16 | } 17 | 18 | cmd.AddCommand(BuildpackInspect(logger, cfg, client)) 19 | cmd.AddCommand(BuildpackPackage(logger, cfg, client, packageConfigReader)) 20 | cmd.AddCommand(BuildpackNew(logger, client)) 21 | cmd.AddCommand(BuildpackPull(logger, cfg, client)) 22 | cmd.AddCommand(BuildpackRegister(logger, cfg, client)) 23 | cmd.AddCommand(BuildpackYank(logger, cfg, client)) 24 | 25 | AddHelpFlag(cmd, "buildpack") 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/extension.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | func NewExtensionCommand(logger logging.Logger, cfg config.Config, client PackClient, packageConfigReader PackageConfigReader) *cobra.Command { 11 | cmd := &cobra.Command{ 12 | Use: "extension", 13 | Aliases: []string{"extensions"}, 14 | Short: "Interact with extensions", 15 | RunE: nil, 16 | } 17 | 18 | cmd.AddCommand(ExtensionInspect(logger, cfg, client)) 19 | // client and packageConfigReader to be passed later on 20 | cmd.AddCommand(ExtensionPackage(logger, cfg, client, packageConfigReader)) 21 | // client to be passed later on 22 | cmd.AddCommand(ExtensionNew(logger)) 23 | cmd.AddCommand(ExtensionPull(logger, cfg, client)) 24 | cmd.AddCommand(ExtensionRegister(logger, cfg, client)) 25 | cmd.AddCommand(ExtensionYank(logger, cfg, client)) 26 | 27 | AddHelpFlag(cmd, "extension") 28 | return cmd 29 | } 30 | -------------------------------------------------------------------------------- /internal/commands/extension_new.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | // ExtensionNewFlags define flags provided to the ExtensionNew command 10 | type ExtensionNewFlags struct { 11 | API string 12 | Path string 13 | Stacks []string 14 | Version string 15 | } 16 | 17 | // extensioncreator type to be added here and argument also to be added in the function 18 | 19 | // ExtensionNew generates the scaffolding of an extension 20 | func ExtensionNew(logger logging.Logger) *cobra.Command { 21 | cmd := &cobra.Command{ 22 | Use: "new ", 23 | Short: "Creates basic scaffolding of an extension", 24 | Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), 25 | Example: "pack extension new ", 26 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 27 | // logic will go here 28 | return nil 29 | }), 30 | } 31 | 32 | // flags will go here 33 | 34 | AddHelpFlag(cmd, "new") 35 | return cmd 36 | } 37 | -------------------------------------------------------------------------------- /internal/commands/extension_pull.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // ExtensionPullFlags consist of flags applicable to the `extension pull` command 11 | type ExtensionPullFlags struct { 12 | // ExtensionRegistry is the name of the extension registry to use to search for 13 | ExtensionRegistry string 14 | } 15 | 16 | // ExtensionPull pulls an extension and stores it locally 17 | func ExtensionPull(logger logging.Logger, cfg config.Config, pack PackClient) *cobra.Command { 18 | cmd := &cobra.Command{ 19 | Use: "pull ", 20 | Args: cobra.ExactArgs(1), 21 | Short: "Pull an extension from a registry and store it locally", 22 | Example: "pack extension pull ", 23 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 24 | // logic will be added here 25 | return nil 26 | }), 27 | } 28 | // flags will be added here 29 | AddHelpFlag(cmd, "pull") 30 | return cmd 31 | } 32 | -------------------------------------------------------------------------------- /internal/commands/extension_register.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | type ExtensionRegisterFlags struct { 11 | ExtensionRegistry string 12 | } 13 | 14 | func ExtensionRegister(logger logging.Logger, cfg config.Config, pack PackClient) *cobra.Command { 15 | cmd := &cobra.Command{ 16 | Use: "register ", 17 | Args: cobra.ExactArgs(1), 18 | Short: "Register an extension to a registry", 19 | Example: "pack extension register ", 20 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 21 | // logic will be added here 22 | return nil 23 | }), 24 | } 25 | // flags will be added here 26 | AddHelpFlag(cmd, "register") 27 | return cmd 28 | } 29 | -------------------------------------------------------------------------------- /internal/commands/extension_yank.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | type ExtensionYankFlags struct { 11 | ExtensionRegistry string 12 | Undo bool 13 | } 14 | 15 | func ExtensionYank(logger logging.Logger, cfg config.Config, pack PackClient) *cobra.Command { 16 | cmd := &cobra.Command{ 17 | Use: "yank ", 18 | Args: cobra.ExactArgs(1), 19 | Short: "Yank an extension from a registry", 20 | Example: "pack yank ", 21 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 22 | // logic will be added here 23 | return nil 24 | }), 25 | } 26 | // flags will be added here 27 | AddHelpFlag(cmd, "yank") 28 | 29 | return cmd 30 | } 31 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_builder_inspector.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/pkg/client" 5 | ) 6 | 7 | type FakeBuilderInspector struct { 8 | InfoForLocal *client.BuilderInfo 9 | InfoForRemote *client.BuilderInfo 10 | ErrorForLocal error 11 | ErrorForRemote error 12 | 13 | ReceivedForLocalName string 14 | ReceivedForRemoteName string 15 | CalculatedConfigForLocal client.BuilderInspectionConfig 16 | CalculatedConfigForRemote client.BuilderInspectionConfig 17 | } 18 | 19 | func (i *FakeBuilderInspector) InspectBuilder( 20 | name string, 21 | daemon bool, 22 | modifiers ...client.BuilderInspectionModifier, 23 | ) (*client.BuilderInfo, error) { 24 | if daemon { 25 | i.CalculatedConfigForLocal = client.BuilderInspectionConfig{} 26 | for _, mod := range modifiers { 27 | mod(&i.CalculatedConfigForLocal) 28 | } 29 | i.ReceivedForLocalName = name 30 | return i.InfoForLocal, i.ErrorForLocal 31 | } 32 | 33 | i.CalculatedConfigForRemote = client.BuilderInspectionConfig{} 34 | for _, mod := range modifiers { 35 | mod(&i.CalculatedConfigForRemote) 36 | } 37 | i.ReceivedForRemoteName = name 38 | return i.InfoForRemote, i.ErrorForRemote 39 | } 40 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_builder_writer_factory.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/internal/builder/writer" 5 | ) 6 | 7 | type FakeBuilderWriterFactory struct { 8 | ReturnForWriter writer.BuilderWriter 9 | ErrorForWriter error 10 | 11 | ReceivedForKind string 12 | } 13 | 14 | func (f *FakeBuilderWriterFactory) Writer(kind string) (writer.BuilderWriter, error) { 15 | f.ReceivedForKind = kind 16 | 17 | return f.ReturnForWriter, f.ErrorForWriter 18 | } 19 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_buildpack_packager.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/buildpacks/pack/pkg/client" 7 | ) 8 | 9 | type FakeBuildpackPackager struct { 10 | CreateCalledWithOptions client.PackageBuildpackOptions 11 | } 12 | 13 | func (c *FakeBuildpackPackager) PackageBuildpack(ctx context.Context, opts client.PackageBuildpackOptions) error { 14 | c.CreateCalledWithOptions = opts 15 | 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_extension_packager.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/buildpacks/pack/pkg/client" 7 | ) 8 | 9 | func (c *FakeBuildpackPackager) PackageExtension(ctx context.Context, opts client.PackageBuildpackOptions) error { 10 | c.CreateCalledWithOptions = opts 11 | 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_inspect_image_writer.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/internal/inspectimage" 5 | "github.com/buildpacks/pack/pkg/client" 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | type FakeInspectImageWriter struct { 10 | PrintForLocal string 11 | PrintForRemote string 12 | ErrorForPrint error 13 | 14 | ReceivedInfoForLocal *client.ImageInfo 15 | ReceivedInfoForRemote *client.ImageInfo 16 | RecievedGeneralInfo inspectimage.GeneralInfo 17 | ReceivedErrorForLocal error 18 | ReceivedErrorForRemote error 19 | } 20 | 21 | func (w *FakeInspectImageWriter) Print( 22 | logger logging.Logger, 23 | sharedInfo inspectimage.GeneralInfo, 24 | local, remote *client.ImageInfo, 25 | localErr, remoteErr error, 26 | ) error { 27 | w.ReceivedInfoForLocal = local 28 | w.ReceivedInfoForRemote = remote 29 | w.ReceivedErrorForLocal = localErr 30 | w.ReceivedErrorForRemote = remoteErr 31 | w.RecievedGeneralInfo = sharedInfo 32 | 33 | logger.Infof("\nLOCAL:\n%s\n", w.PrintForLocal) 34 | logger.Infof("\nREMOTE:\n%s\n", w.PrintForRemote) 35 | 36 | return w.ErrorForPrint 37 | } 38 | -------------------------------------------------------------------------------- /internal/commands/fakes/fake_inspect_image_writer_factory.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/internal/inspectimage/writer" 5 | ) 6 | 7 | type FakeInspectImageWriterFactory struct { 8 | ReturnForWriter writer.InspectImageWriter 9 | ErrorForWriter error 10 | 11 | ReceivedForKind string 12 | ReceivedForBOM bool 13 | } 14 | 15 | func (f *FakeInspectImageWriterFactory) Writer(kind string, bom bool) (writer.InspectImageWriter, error) { 16 | f.ReceivedForKind = kind 17 | f.ReceivedForBOM = bom 18 | 19 | return f.ReturnForWriter, f.ErrorForWriter 20 | } 21 | -------------------------------------------------------------------------------- /internal/commands/list_registries.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // Deprecated: Use config registries list instead 11 | func ListBuildpackRegistries(logger logging.Logger, cfg config.Config) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "list-registries", 14 | Args: cobra.NoArgs, 15 | Hidden: true, 16 | Short: "List buildpack registries", 17 | Example: "pack list-registries", 18 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 19 | deprecationWarning(logger, "list-registries", "config registries list") 20 | listRegistries(args, logger, cfg) 21 | 22 | return nil 23 | }), 24 | } 25 | 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/list_trusted_builders.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // Deprecated: Use `config trusted-builders list` instead 11 | func ListTrustedBuilders(logger logging.Logger, cfg config.Config) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "list-trusted-builders", 14 | Short: "List Trusted Builders", 15 | Long: "List Trusted Builders.\n\nShow the builders that are either trusted by default or have been explicitly trusted locally using `trusted-builder add`", 16 | Example: "pack list-trusted-builders", 17 | Hidden: true, 18 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 19 | deprecationWarning(logger, "list-trusted-builders", "config trusted-builders list") 20 | listTrustedBuilders(args, logger, cfg) 21 | return nil 22 | }), 23 | } 24 | 25 | AddHelpFlag(cmd, "list-trusted-builders") 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/manifest_add.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/client" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // ManifestAdd adds a new image to a manifest list (image index). 11 | func ManifestAdd(logger logging.Logger, pack PackClient) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "add [OPTIONS] [flags]", 14 | Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs), 15 | Short: "Add an image to a manifest list.", 16 | Example: `pack manifest add my-image-index my-image:some-arch`, 17 | RunE: logError(logger, func(cmd *cobra.Command, args []string) (err error) { 18 | return pack.AddManifest(cmd.Context(), client.ManifestAddOptions{ 19 | IndexRepoName: args[0], 20 | RepoName: args[1], 21 | }) 22 | }), 23 | } 24 | 25 | AddHelpFlag(cmd, "add") 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/manifest_inspect.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/spf13/cobra" 7 | 8 | "github.com/buildpacks/pack/pkg/logging" 9 | ) 10 | 11 | // ManifestInspect shows the manifest information stored locally 12 | func ManifestInspect(logger logging.Logger, pack PackClient) *cobra.Command { 13 | cmd := &cobra.Command{ 14 | Use: "inspect ", 15 | Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), 16 | Short: "Display information about a manifest list.", 17 | Example: `pack manifest inspect my-image-index`, 18 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 19 | if args[0] == "" { 20 | return errors.New("'' is required") 21 | } 22 | return pack.InspectManifest(args[0]) 23 | }), 24 | } 25 | 26 | AddHelpFlag(cmd, "inspect") 27 | return cmd 28 | } 29 | -------------------------------------------------------------------------------- /internal/commands/manifest_remove.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | // ManifestDelete deletes one or more manifest lists from local storage 10 | func ManifestDelete(logger logging.Logger, pack PackClient) *cobra.Command { 11 | cmd := &cobra.Command{ 12 | Use: "remove [manifest-list] [manifest-list...]", 13 | Args: cobra.MatchAll(cobra.MinimumNArgs(1), cobra.OnlyValidArgs), 14 | Short: "Remove one or more manifest lists from local storage", 15 | Example: `pack manifest remove my-image-index`, 16 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 17 | if err := pack.DeleteManifest(args); err != nil { 18 | return err 19 | } 20 | return nil 21 | }), 22 | } 23 | 24 | AddHelpFlag(cmd, "remove") 25 | return cmd 26 | } 27 | -------------------------------------------------------------------------------- /internal/commands/manifest_rm.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | // ManifestRemove will remove the specified image manifest if it is already referenced in the index 10 | func ManifestRemove(logger logging.Logger, pack PackClient) *cobra.Command { 11 | cmd := &cobra.Command{ 12 | Use: "rm [manifest-list] [manifest] [manifest...] [flags]", 13 | Args: cobra.MatchAll(cobra.MinimumNArgs(2), cobra.OnlyValidArgs), 14 | Short: "Remove an image manifest from a manifest list.", 15 | Example: `pack manifest rm my-image-index my-image@sha256:`, 16 | Long: `'manifest rm' will remove the specified image manifest if it is already referenced in the index. 17 | Users must pass the digest of the image in order to delete it from the index. 18 | To discard __all__ the images in an index and the index itself, use 'manifest delete'.`, 19 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 20 | if err := pack.RemoveManifest(args[0], args[1:]); err != nil { 21 | return err 22 | } 23 | return nil 24 | }), 25 | } 26 | 27 | AddHelpFlag(cmd, "rm") 28 | return cmd 29 | } 30 | -------------------------------------------------------------------------------- /internal/commands/remove_registry.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // Deprecated: Use config registries remove instead 11 | func RemoveRegistry(logger logging.Logger, cfg config.Config, cfgPath string) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "remove-registry ", 14 | Args: cobra.ExactArgs(1), 15 | Hidden: true, 16 | Short: "Remove registry", 17 | Example: "pack remove-registry myregistry", 18 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 19 | deprecationWarning(logger, "remove-registry", "config registries remove") 20 | return removeRegistry(args, logger, cfg, cfgPath) 21 | }), 22 | } 23 | 24 | AddHelpFlag(cmd, "remove-registry") 25 | return cmd 26 | } 27 | -------------------------------------------------------------------------------- /internal/commands/sbom.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | func NewSBOMCommand(logger logging.Logger, cfg config.Config, client PackClient) *cobra.Command { 11 | cmd := &cobra.Command{ 12 | Use: "sbom", 13 | Short: "Interact with SBoM", 14 | RunE: nil, 15 | } 16 | 17 | cmd.AddCommand(DownloadSBOM(logger, client)) 18 | AddHelpFlag(cmd, "sbom") 19 | return cmd 20 | } 21 | -------------------------------------------------------------------------------- /internal/commands/stack.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/pkg/logging" 7 | ) 8 | 9 | func NewStackCommand(logger logging.Logger) *cobra.Command { 10 | command := cobra.Command{ 11 | Use: "stack", 12 | Short: "(deprecated) Interact with stacks", 13 | Long: "(Deprecated)\nStacks are deprecated in favor of using BuildImages and RunImages directly, but will continue to be supported throughout all of 2023 and '24 if not longer. Please see our docs for more details- https://buildpacks.io/docs/concepts/components/stack", 14 | RunE: nil, 15 | } 16 | 17 | command.AddCommand(stackSuggest(logger)) 18 | return &command 19 | } 20 | -------------------------------------------------------------------------------- /internal/commands/testdata/buildpack.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/internal/commands/testdata/buildpack.toml -------------------------------------------------------------------------------- /internal/commands/testdata/inspect_image_output.json: -------------------------------------------------------------------------------- 1 | {"remote":[{"name":"name-1","version":"version-1","metadata":{"RemoteData":{"String":"aString","Bool":true,"Int":123,"Nested":{"String":"anotherString"}}},"buildpack":{"id":"test.bp.one.remote","version":"1.0.0"}}],"local":[{"name":"name-1","version":"version-1","metadata":{"LocalData":{"String":"","Bool":false,"Int":456,"Nested":{"String":""}}},"buildpack":{"id":"test.bp.one.remote","version":"1.0.0"}}]} -------------------------------------------------------------------------------- /internal/commands/testdata/project.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "Sample" 3 | 4 | [[build.buildpacks]] 5 | id = "example/lua" 6 | version = "1.0" 7 | 8 | [[build.env]] 9 | name = "KEY1" 10 | value = "VALUE1" 11 | -------------------------------------------------------------------------------- /internal/commands/trust_builder.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // Deprecated: Use `config trusted-builders add` instead 11 | func TrustBuilder(logger logging.Logger, cfg config.Config, cfgPath string) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "trust-builder ", 14 | Args: cobra.ExactArgs(1), 15 | Short: "Trust builder", 16 | Long: "Trust builder.\n\nWhen building with this builder, all lifecycle phases will be run in a single container using the builder image.", 17 | Example: "pack trust-builder cnbs/sample-stack-run:bionic", 18 | Hidden: true, 19 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 20 | deprecationWarning(logger, "trust-builder", "config trusted-builders add") 21 | return addTrustedBuilder(args, logger, cfg, cfgPath) 22 | }), 23 | } 24 | 25 | AddHelpFlag(cmd, "trust-builder") 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/untrust_builder.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/buildpacks/pack/internal/config" 7 | "github.com/buildpacks/pack/pkg/logging" 8 | ) 9 | 10 | // Deprecated: Use `config trusted-builders remove` instead 11 | func UntrustBuilder(logger logging.Logger, cfg config.Config, cfgPath string) *cobra.Command { 12 | cmd := &cobra.Command{ 13 | Use: "untrust-builder ", 14 | Args: cobra.ExactArgs(1), 15 | Short: "Stop trusting builder", 16 | Hidden: true, 17 | Long: "Stop trusting builder.\n\nWhen building with this builder, all lifecycle phases will be no longer be run in a single container using the builder image.", 18 | Example: "pack untrust-builder cnbs/sample-stack-run:bionic", 19 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 20 | deprecationWarning(logger, "untrust-builder", "config trusted-builders remove") 21 | return removeTrustedBuilder(args, logger, cfg, cfgPath) 22 | }), 23 | } 24 | 25 | AddHelpFlag(cmd, "untrust-builder") 26 | return cmd 27 | } 28 | -------------------------------------------------------------------------------- /internal/commands/version.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/spf13/cobra" 7 | 8 | "github.com/buildpacks/pack/pkg/logging" 9 | ) 10 | 11 | // Version shows the current pack version 12 | func Version(logger logging.Logger, version string) *cobra.Command { 13 | cmd := &cobra.Command{ 14 | Use: "version", 15 | Args: cobra.NoArgs, 16 | Short: "Show current 'pack' version", 17 | Example: "pack version", 18 | RunE: logError(logger, func(cmd *cobra.Command, args []string) error { 19 | logger.Info(strings.TrimSpace(version)) 20 | return nil 21 | }), 22 | } 23 | AddHelpFlag(cmd, "version") 24 | return cmd 25 | } 26 | -------------------------------------------------------------------------------- /internal/commands/version_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/sclevine/spec" 8 | "github.com/sclevine/spec/report" 9 | "github.com/spf13/cobra" 10 | 11 | "github.com/buildpacks/pack/internal/commands" 12 | "github.com/buildpacks/pack/pkg/logging" 13 | h "github.com/buildpacks/pack/testhelpers" 14 | ) 15 | 16 | func TestVersionCommand(t *testing.T) { 17 | spec.Run(t, "Commands", testVersionCommand, spec.Parallel(), spec.Report(report.Terminal{})) 18 | } 19 | 20 | func testVersionCommand(t *testing.T, when spec.G, it spec.S) { 21 | var ( 22 | command *cobra.Command 23 | outBuf bytes.Buffer 24 | testVersion = "1.3.4" 25 | ) 26 | 27 | it.Before(func() { 28 | command = commands.Version(logging.NewLogWithWriters(&outBuf, &outBuf), testVersion) 29 | }) 30 | 31 | when("#Version", func() { 32 | it("returns version", func() { 33 | command.SetArgs([]string{}) 34 | h.AssertNil(t, command.Execute()) 35 | h.AssertEq(t, outBuf.String(), testVersion+"\n") 36 | }) 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /internal/config/config_helpers.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/BurntSushi/toml" 8 | 9 | "github.com/buildpacks/pack/internal/style" 10 | ) 11 | 12 | func FormatUndecodedKeys(undecodedKeys []toml.Key) string { 13 | unusedKeys := map[string]interface{}{} 14 | for _, key := range undecodedKeys { 15 | keyName := key.String() 16 | 17 | parent := strings.Split(keyName, ".")[0] 18 | 19 | if _, ok := unusedKeys[parent]; !ok { 20 | unusedKeys[keyName] = nil 21 | } 22 | } 23 | 24 | var errorKeys []string 25 | for errorKey := range unusedKeys { 26 | errorKeys = append(errorKeys, style.Symbol(errorKey)) 27 | } 28 | 29 | pluralizedElement := "element" 30 | if len(errorKeys) > 1 { 31 | pluralizedElement += "s" 32 | } 33 | elements := strings.Join(errorKeys, ", ") 34 | 35 | return fmt.Sprintf("unknown configuration %s %s", pluralizedElement, elements) 36 | } 37 | -------------------------------------------------------------------------------- /internal/fakes/fake_buildpack_tar.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "testing" 7 | 8 | "github.com/buildpacks/pack/pkg/dist" 9 | h "github.com/buildpacks/pack/testhelpers" 10 | ) 11 | 12 | func CreateBuildpackTar(t *testing.T, tmpDir string, descriptor dist.BuildpackDescriptor) string { 13 | buildpack, err := NewFakeBuildpackBlob(&descriptor, 0777) 14 | h.AssertNil(t, err) 15 | 16 | tempFile, err := os.CreateTemp(tmpDir, "bp-*.tar") 17 | h.AssertNil(t, err) 18 | defer tempFile.Close() 19 | 20 | reader, err := buildpack.Open() 21 | h.AssertNil(t, err) 22 | 23 | _, err = io.Copy(tempFile, reader) 24 | h.AssertNil(t, err) 25 | 26 | return tempFile.Name() 27 | } 28 | -------------------------------------------------------------------------------- /internal/fakes/fake_extension_blob.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "time" 7 | 8 | "github.com/BurntSushi/toml" 9 | 10 | "github.com/buildpacks/pack/pkg/archive" 11 | "github.com/buildpacks/pack/pkg/blob" 12 | "github.com/buildpacks/pack/pkg/buildpack" 13 | ) 14 | 15 | type fakeExtensionBlob struct { 16 | descriptor buildpack.Descriptor 17 | chmod int64 18 | } 19 | 20 | func NewFakeExtensionBlob(descriptor buildpack.Descriptor, chmod int64) (blob.Blob, error) { 21 | return &fakeExtensionBlob{ 22 | descriptor: descriptor, 23 | chmod: chmod, 24 | }, nil 25 | } 26 | 27 | func (b *fakeExtensionBlob) Open() (reader io.ReadCloser, err error) { 28 | buf := &bytes.Buffer{} 29 | if err = toml.NewEncoder(buf).Encode(b.descriptor); err != nil { 30 | return nil, err 31 | } 32 | 33 | tarBuilder := archive.TarBuilder{} 34 | tarBuilder.AddFile("extension.toml", b.chmod, time.Now(), buf.Bytes()) 35 | tarBuilder.AddDir("bin", b.chmod, time.Now()) 36 | tarBuilder.AddFile("bin/build", b.chmod, time.Now(), []byte("build-contents")) 37 | tarBuilder.AddFile("bin/detect", b.chmod, time.Now(), []byte("detect-contents")) 38 | 39 | return tarBuilder.Reader(archive.DefaultTarWriterFactory()), err 40 | } 41 | -------------------------------------------------------------------------------- /internal/fakes/fake_extension_tar.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "testing" 7 | 8 | "github.com/buildpacks/pack/pkg/dist" 9 | h "github.com/buildpacks/pack/testhelpers" 10 | ) 11 | 12 | func CreateExtensionTar(t *testing.T, tmpDir string, descriptor dist.ExtensionDescriptor) string { 13 | extension, err := NewFakeExtensionBlob(&descriptor, 0777) 14 | h.AssertNil(t, err) 15 | 16 | tempFile, err := os.CreateTemp(tmpDir, "ex-*.tar") 17 | h.AssertNil(t, err) 18 | defer tempFile.Close() 19 | 20 | reader, err := extension.Open() 21 | h.AssertNil(t, err) 22 | 23 | _, err = io.Copy(tempFile, reader) 24 | h.AssertNil(t, err) 25 | 26 | return tempFile.Name() 27 | } 28 | -------------------------------------------------------------------------------- /internal/fakes/fake_lifecycle.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/buildpacks/pack/internal/build" 7 | ) 8 | 9 | type FakeLifecycle struct { 10 | Opts build.LifecycleOptions 11 | } 12 | 13 | func (f *FakeLifecycle) Execute(ctx context.Context, opts build.LifecycleOptions) error { 14 | f.Opts = opts 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/bom_json.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | ) 7 | 8 | type JSONBOM struct { 9 | StructuredBOMFormat 10 | } 11 | 12 | func NewJSONBOM() *JSONBOM { 13 | return &JSONBOM{ 14 | StructuredBOMFormat: StructuredBOMFormat{ 15 | MarshalFunc: func(i interface{}) ([]byte, error) { 16 | buf := bytes.NewBuffer(nil) 17 | if err := json.NewEncoder(buf).Encode(i); err != nil { 18 | return []byte{}, err 19 | } 20 | 21 | formattedBuf := bytes.NewBuffer(nil) 22 | if err := json.Indent(formattedBuf, buf.Bytes(), "", " "); err != nil { 23 | return []byte{}, err 24 | } 25 | return formattedBuf.Bytes(), nil 26 | }, 27 | }, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/bom_yaml.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | 6 | "gopkg.in/yaml.v3" 7 | ) 8 | 9 | type YAMLBOM struct { 10 | StructuredBOMFormat 11 | } 12 | 13 | func NewYAMLBOM() *YAMLBOM { 14 | return &YAMLBOM{ 15 | StructuredBOMFormat: StructuredBOMFormat{ 16 | MarshalFunc: func(i interface{}) ([]byte, error) { 17 | buf := bytes.NewBuffer(nil) 18 | if err := yaml.NewEncoder(buf).Encode(i); err != nil { 19 | return []byte{}, err 20 | } 21 | return buf.Bytes(), nil 22 | }, 23 | }, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/factory.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/buildpacks/pack/internal/inspectimage" 7 | "github.com/buildpacks/pack/pkg/client" 8 | 9 | "github.com/buildpacks/pack/pkg/logging" 10 | 11 | "github.com/buildpacks/pack/internal/style" 12 | ) 13 | 14 | type Factory struct{} 15 | 16 | type InspectImageWriter interface { 17 | Print( 18 | logger logging.Logger, 19 | sharedInfo inspectimage.GeneralInfo, 20 | local, remote *client.ImageInfo, 21 | localErr, remoteErr error, 22 | ) error 23 | } 24 | 25 | func NewFactory() *Factory { 26 | return &Factory{} 27 | } 28 | 29 | func (f *Factory) Writer(kind string, bom bool) (InspectImageWriter, error) { 30 | if bom { 31 | switch kind { 32 | case "human-readable", "json": 33 | return NewJSONBOM(), nil 34 | case "yaml": 35 | return NewYAMLBOM(), nil 36 | } 37 | } else { 38 | switch kind { 39 | case "human-readable": 40 | return NewHumanReadable(), nil 41 | case "json": 42 | return NewJSON(), nil 43 | case "yaml": 44 | return NewYAML(), nil 45 | case "toml": 46 | return NewTOML(), nil 47 | } 48 | } 49 | 50 | return nil, fmt.Errorf("output format %s is not supported", style.Symbol(kind)) 51 | } 52 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/json.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | ) 7 | 8 | type JSON struct { 9 | StructuredFormat 10 | } 11 | 12 | func NewJSON() *JSON { 13 | return &JSON{ 14 | StructuredFormat: StructuredFormat{ 15 | MarshalFunc: func(i interface{}) ([]byte, error) { 16 | buf := bytes.NewBuffer(nil) 17 | if err := json.NewEncoder(buf).Encode(i); err != nil { 18 | return []byte{}, err 19 | } 20 | 21 | formattedBuf := bytes.NewBuffer(nil) 22 | if err := json.Indent(formattedBuf, buf.Bytes(), "", " "); err != nil { 23 | return []byte{}, err 24 | } 25 | return formattedBuf.Bytes(), nil 26 | }, 27 | }, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/toml.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | 6 | "github.com/pelletier/go-toml" 7 | ) 8 | 9 | type TOML struct { 10 | StructuredFormat 11 | } 12 | 13 | func NewTOML() *TOML { 14 | return &TOML{ 15 | StructuredFormat: StructuredFormat{ 16 | MarshalFunc: func(i interface{}) ([]byte, error) { 17 | buf := bytes.NewBuffer(nil) 18 | if err := toml.NewEncoder(buf).Encode(i); err != nil { 19 | return []byte{}, err 20 | } 21 | return buf.Bytes(), nil 22 | }, 23 | }, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/inspectimage/writer/yaml.go: -------------------------------------------------------------------------------- 1 | package writer 2 | 3 | import ( 4 | "bytes" 5 | 6 | "gopkg.in/yaml.v3" 7 | ) 8 | 9 | type YAML struct { 10 | StructuredFormat 11 | } 12 | 13 | func NewYAML() *YAML { 14 | return &YAML{ 15 | StructuredFormat: StructuredFormat{ 16 | MarshalFunc: func(i interface{}) ([]byte, error) { 17 | buf := bytes.NewBuffer(nil) 18 | if err := yaml.NewEncoder(buf).Encode(i); err != nil { 19 | return []byte{}, err 20 | } 21 | return buf.Bytes(), nil 22 | }, 23 | }, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/layer/layer.go: -------------------------------------------------------------------------------- 1 | package layer 2 | 3 | import ( 4 | "github.com/buildpacks/pack/pkg/archive" 5 | ) 6 | 7 | func CreateSingleFileTar(tarFile, path, txt string, twf archive.TarWriterFactory) error { 8 | tarBuilder := archive.TarBuilder{} 9 | tarBuilder.AddFile(path, 0644, archive.NormalizedDateTime, []byte(txt)) 10 | return tarBuilder.WriteToPath(tarFile, twf) 11 | } 12 | -------------------------------------------------------------------------------- /internal/layer/writer_factory.go: -------------------------------------------------------------------------------- 1 | package layer 2 | 3 | import ( 4 | "archive/tar" 5 | "fmt" 6 | "io" 7 | 8 | ilayer "github.com/buildpacks/imgutil/layer" 9 | 10 | "github.com/buildpacks/pack/pkg/archive" 11 | ) 12 | 13 | type WriterFactory struct { 14 | os string 15 | } 16 | 17 | func NewWriterFactory(imageOS string) (*WriterFactory, error) { 18 | if imageOS != "linux" && imageOS != "windows" { 19 | return nil, fmt.Errorf("provided image OS '%s' must be either 'linux' or 'windows'", imageOS) 20 | } 21 | 22 | return &WriterFactory{os: imageOS}, nil 23 | } 24 | 25 | func (f *WriterFactory) NewWriter(fileWriter io.Writer) archive.TarWriter { 26 | if f.os == "windows" { 27 | return ilayer.NewWindowsWriter(fileWriter) 28 | } 29 | 30 | // Linux images use tar.Writer 31 | return tar.NewWriter(fileWriter) 32 | } 33 | -------------------------------------------------------------------------------- /internal/paths/defaults_unix.go: -------------------------------------------------------------------------------- 1 | //go:build unix 2 | 3 | package paths 4 | 5 | const ( 6 | RootDir = `/` 7 | ) 8 | -------------------------------------------------------------------------------- /internal/paths/defaults_windows.go: -------------------------------------------------------------------------------- 1 | package paths 2 | 3 | const ( 4 | RootDir = `c:\` 5 | ) 6 | -------------------------------------------------------------------------------- /internal/registry/git.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "bytes" 5 | "text/template" 6 | 7 | "github.com/pkg/errors" 8 | ) 9 | 10 | // GitCommit commits a Buildpack to a registry Cache. 11 | func GitCommit(b Buildpack, username string, registryCache Cache) error { 12 | if err := registryCache.Initialize(); err != nil { 13 | return err 14 | } 15 | 16 | commitTemplate, err := template.New("buildpack").Parse(GitCommitTemplate) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | var commit bytes.Buffer 22 | if err := commitTemplate.Execute(&commit, b); err != nil { 23 | return errors.Wrap(err, "creating template") 24 | } 25 | 26 | if err := registryCache.Commit(b, username, commit.String()); err != nil { 27 | return err 28 | } 29 | 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /internal/slices/slices.go: -------------------------------------------------------------------------------- 1 | package slices 2 | 3 | func MapString(vs []string, f func(string) string) []string { 4 | vsm := make([]string, len(vs)) 5 | for i, v := range vs { 6 | vsm[i] = f(v) 7 | } 8 | return vsm 9 | } 10 | -------------------------------------------------------------------------------- /internal/slices/slices_test.go: -------------------------------------------------------------------------------- 1 | package slices_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/sclevine/spec" 7 | 8 | "github.com/buildpacks/pack/internal/slices" 9 | h "github.com/buildpacks/pack/testhelpers" 10 | ) 11 | 12 | func TestMapString(t *testing.T) { 13 | spec.Run(t, "Slices", func(t *testing.T, when spec.G, it spec.S) { 14 | var ( 15 | assert = h.NewAssertionManager(t) 16 | ) 17 | 18 | when("#MapString", func() { 19 | it("maps each value", func() { 20 | input := []string{"hello", "1", "2", "world"} 21 | expected := []string{"hello.", "1.", "2.", "world."} 22 | fn := func(v string) string { 23 | return v + "." 24 | } 25 | 26 | output := slices.MapString(input, fn) 27 | assert.Equal(output, expected) 28 | }) 29 | }) 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /internal/sshdialer/posix_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package sshdialer_test 4 | 5 | import ( 6 | "errors" 7 | "net" 8 | "os" 9 | ) 10 | 11 | func fixupPrivateKeyMod(path string) { 12 | err := os.Chmod(path, 0400) 13 | if err != nil { 14 | panic(err) 15 | } 16 | } 17 | 18 | func listen(addr string) (net.Listener, error) { 19 | return net.Listen("unix", addr) 20 | } 21 | 22 | func isErrClosed(err error) bool { 23 | return errors.Is(err, net.ErrClosed) 24 | } 25 | -------------------------------------------------------------------------------- /internal/sshdialer/ssh_agent_unix.go: -------------------------------------------------------------------------------- 1 | //go:build unix 2 | 3 | package sshdialer 4 | 5 | import "net" 6 | 7 | func dialSSHAgent(addr string) (net.Conn, error) { 8 | return net.Dial("unix", addr) 9 | } 10 | -------------------------------------------------------------------------------- /internal/sshdialer/ssh_agent_windows.go: -------------------------------------------------------------------------------- 1 | package sshdialer 2 | 3 | import ( 4 | "net" 5 | "strings" 6 | 7 | "github.com/Microsoft/go-winio" 8 | ) 9 | 10 | func dialSSHAgent(addr string) (net.Conn, error) { 11 | if strings.Contains(addr, "\\pipe\\") { 12 | return winio.DialPipe(addr, nil) 13 | } 14 | return net.Dial("unix", addr) 15 | } 16 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/etc/ssh/ssh_host_ecdsa_key: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS 3 | 1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQRDB1fPXY58fSwaqyoj5lCfLtQ/NcIs 4 | grKTA11vypVy9MUCWtdAQIXczmtRMTFCVozk3lwt9M4iKc79nCkkkfyrAAAAsPgat2v4Gr 5 | drAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEMHV89djnx9LBqr 6 | KiPmUJ8u1D81wiyCspMDXW/KlXL0xQJa10BAhdzOa1ExMUJWjOTeXC30ziIpzv2cKSSR/K 7 | sAAAAhAIcs2smJGAEKOvzL8Rfz5b1IpQqB8GzxycT3/53XOzaSAAAAEG12YXNla0BiZWxs 8 | YXRyaXgBAgMEBQYH 9 | -----END OPENSSH PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/etc/ssh/ssh_host_ecdsa_key.pub: -------------------------------------------------------------------------------- 1 | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEMHV89djnx9LBqrKiPmUJ8u1D81wiyCspMDXW/KlXL0xQJa10BAhdzOa1ExMUJWjOTeXC30ziIpzv2cKSSR/Ks= mvasek@bellatrix 2 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/etc/ssh/ssh_host_ed25519_key: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACAhhd7wuRBaf9R7Q/HQi7lEWoukb/HrYDg394NpeOgsbAAAAJjz02VI89Nl 4 | SAAAAAtzc2gtZWQyNTUxOQAAACAhhd7wuRBaf9R7Q/HQi7lEWoukb/HrYDg394NpeOgsbA 5 | AAAEC9lvHqAASWXcZSm/Rih3V78uMejs+6sc6SOVhaogLwHyGF3vC5EFp/1HtD8dCLuURa 6 | i6Rv8etgODf3g2l46CxsAAAAEG12YXNla0BiZWxsYXRyaXgBAgMEBQ== 7 | -----END OPENSSH PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/etc/ssh/ssh_host_ed25519_key.pub: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGF3vC5EFp/1HtD8dCLuURai6Rv8etgODf3g2l46Cxs mvasek@bellatrix 2 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/etc/ssh/ssh_host_rsa_key.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVUeZF20fM6EJkKZytgl0X1WN09Ndz0eJ30HN7GTRB+cboLXmA7JtuZflhXGBWIfOuulqh0sMJgFa7j6XYM94bmBohrxrVYCGC8RBF8mHT0lxWRVZ3P0DtSaC1vqTd3RDCVhpmstLVJkZiD6KjGiV5vMCz/52bXJ+RJFc1/d8+6HK5s7oAgEwF1ycjPdzC7c1m/qjcuyEVjKbsNpcD8t0fCYxl7YlqSypJtp9trGpnqQiO9ZR46sjpH/e4tYzUFMyKv2KefyJGtzGcC1JUb5DleC9qQ+5kNe/PI8/rqQ5ydPXHwMMdzLg8PRLLO0MiMdZen9cHCoOpZBuGJQFo6N7Jgnqqj1kmesahqKnkDxOUq1oMVLppfWhsfFh635K8DmwqNr9zHfc0uHQVF9ddmaSeAS+uY/2gZf8B6AxNvMT63aQoNTzQzJ7UubFY397xG52JvjWFVNnRTw9lweaAA4xyYZ8DiJWZZz68Rzmhh5jRZKT/NAoFNg2VCw3Dr47upPc= mvasek@bellatrix 2 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/id_dsa: -------------------------------------------------------------------------------- 1 | somegarbage 2 | somerugish -------------------------------------------------------------------------------- /internal/sshdialer/testdata/id_dsa.pub: -------------------------------------------------------------------------------- 1 | somegarbage 2 | somerugish -------------------------------------------------------------------------------- /internal/sshdialer/testdata/id_ed25519: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACCVbPGj8U+Zjq5NEgyP2996RFk+lIrXNMYLqLLikeJRJQAAAJjDwa3Yw8Gt 4 | 2AAAAAtzc2gtZWQyNTUxOQAAACCVbPGj8U+Zjq5NEgyP2996RFk+lIrXNMYLqLLikeJRJQ 5 | AAAEDti7Y7pPMfJq3Cwztd3ZiM1orRTIibsTH2Y/NQPPFiHpVs8aPxT5mOrk0SDI/b33pE 6 | WT6Uitc0xguosuKR4lElAAAAFHRlc3R1c2VyQGV4YW1wbGUuY29tAQ== 7 | -----END OPENSSH PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/id_ed25519.pub: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJVs8aPxT5mOrk0SDI/b33pEWT6Uitc0xguosuKR4lEl testuser@example.com 2 | -------------------------------------------------------------------------------- /internal/sshdialer/testdata/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDe2RqNezOI3cRJq+PQYlcASjYRaJgFd/AjAYtB+u8C7C8OkuelIaiYavjUn1+Sx3VOkqSVwA7J7zUzUPcx/83BjCffvHtXLAmYfxojd9Z7Bh05kV1Ayx7Pn8xEbEkZpffLGrIy98Vs2MYUU7K7JhLOInkEfD1qolV5IpoIKazkulJEpsdTalrSn53IO0Afa+aayZIG+Fc4RiTHUqk6YcLZQnAcUAoa6WCC31cIOhbllv83hVwjx9b5ZgX509o/WrBsR2cnL7qemBDJmq4RkL6RVcM0lyaGyMn+PfYCXbx4pn3bxdw7An3BS3/O/hTEFLh2tCJc55u7xbKJX265RpKMt/BdU8+VLuA8assVBkNhDwlLI+jvmC8fzqE7H/PLWO2XgTkMpDybEy2n4+8nRElnj4RB2J+vagiJPZFrr5SWQHMUD8fHAYvWo0AHPLly+NgkEu2ZRoAV3gRwZm4C8u9tXMNf4UNVcyxpgaylZwxnaiLNjwx6UChcA0TAAGPygJ3UJ8D/Gakj3iekOd7Zcl7oE9dzByjIolVaPqXChAjfB8wWSiJ2LZRhVklLwHm+wKLEpIBhzai4OnF6k4NTyo1wxlfHb90rbyfn6/arUTJX7cU1NFd7cUw0lh+fL/Q15nJZsd5oCNt3yCTS9fpo9rPPPjCkL+XqUzVVOgbRK5Iknw== testuser@example.com 2 | -------------------------------------------------------------------------------- /internal/sshdialer/windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package sshdialer_test 4 | 5 | import ( 6 | "errors" 7 | "net" 8 | "os/user" 9 | "strings" 10 | 11 | "github.com/Microsoft/go-winio" 12 | "github.com/hectane/go-acl" 13 | ) 14 | 15 | func fixupPrivateKeyMod(path string) { 16 | usr, err := user.Current() 17 | if err != nil { 18 | panic(err) 19 | } 20 | mode := uint32(0400) 21 | err = acl.Apply(path, 22 | true, 23 | false, 24 | acl.GrantName(((mode&0700)<<23)|((mode&0200)<<9), usr.Username)) 25 | 26 | // See https://github.com/hectane/go-acl/issues/1 27 | if err != nil && err.Error() != "The operation completed successfully." { 28 | panic(err) 29 | } 30 | } 31 | 32 | func listen(addr string) (net.Listener, error) { 33 | if strings.Contains(addr, "\\pipe\\") { 34 | return winio.ListenPipe(addr, nil) 35 | } 36 | return net.Listen("unix", addr) 37 | } 38 | 39 | func isErrClosed(err error) bool { 40 | return errors.Is(err, net.ErrClosed) || errors.Is(err, winio.ErrPipeListenerClosed) || errors.Is(err, winio.ErrFileClosed) 41 | } 42 | -------------------------------------------------------------------------------- /internal/strings/strings.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | "golang.org/x/text/cases" 5 | "golang.org/x/text/language" 6 | ) 7 | 8 | func ValueOrDefault(str, def string) string { 9 | if str == "" { 10 | return def 11 | } 12 | 13 | return str 14 | } 15 | 16 | func Title(lower string) string { 17 | return cases.Title(language.English).String(lower) 18 | } 19 | -------------------------------------------------------------------------------- /internal/strings/strings_test.go: -------------------------------------------------------------------------------- 1 | package strings_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/buildpacks/pack/internal/strings" 7 | 8 | "github.com/sclevine/spec" 9 | 10 | h "github.com/buildpacks/pack/testhelpers" 11 | ) 12 | 13 | func TestValueOrDefault(t *testing.T) { 14 | spec.Run(t, "Strings", func(t *testing.T, when spec.G, it spec.S) { 15 | var ( 16 | assert = h.NewAssertionManager(t) 17 | ) 18 | 19 | when("#ValueOrDefault", func() { 20 | it("returns value when value is non-empty", func() { 21 | output := strings.ValueOrDefault("some-value", "-") 22 | assert.Equal(output, "some-value") 23 | }) 24 | 25 | it("returns default when value is empty", func() { 26 | output := strings.ValueOrDefault("", "-") 27 | assert.Equal(output, "-") 28 | }) 29 | }) 30 | 31 | when("#Title", func() { 32 | it("returns the provided string with title casing", func() { 33 | output := strings.Title("to title case") 34 | assert.Equal(output, "To Title Case") 35 | }) 36 | }) 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /internal/target/platform_test.go: -------------------------------------------------------------------------------- 1 | package target_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/heroku/color" 7 | "github.com/sclevine/spec" 8 | "github.com/sclevine/spec/report" 9 | 10 | "github.com/buildpacks/pack/internal/target" 11 | h "github.com/buildpacks/pack/testhelpers" 12 | ) 13 | 14 | func TestPlatforms(t *testing.T) { 15 | color.Disable(true) 16 | defer color.Disable(false) 17 | spec.Run(t, "TestPlatforms", testPlatforms, spec.Parallel(), spec.Report(report.Terminal{})) 18 | } 19 | 20 | func testPlatforms(t *testing.T, when spec.G, it spec.S) { 21 | it.Before(func() { 22 | var err error 23 | h.AssertNil(t, err) 24 | }) 25 | when("target#SupportsPlatform", func() { 26 | it("should return false when target not supported", func() { 27 | b := target.SupportsPlatform("os", "arm", "v6") 28 | h.AssertFalse(t, b) 29 | }) 30 | it("should parse targets as expected", func() { 31 | b := target.SupportsPlatform("linux", "arm", "v6") 32 | h.AssertTrue(t, b) 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /internal/term/term.go: -------------------------------------------------------------------------------- 1 | package term 2 | 3 | import ( 4 | "io" 5 | 6 | "golang.org/x/term" 7 | ) 8 | 9 | // InvalidFileDescriptor based on https://golang.org/src/os/file_unix.go?s=2183:2210#L57 10 | const InvalidFileDescriptor = ^(uintptr(0)) 11 | 12 | // IsTerminal returns whether a writer is a terminal 13 | func IsTerminal(w io.Writer) (uintptr, bool) { 14 | if f, ok := w.(hasDescriptor); ok { 15 | termFd := f.Fd() 16 | isTerm := term.IsTerminal(int(termFd)) 17 | return termFd, isTerm 18 | } 19 | 20 | return InvalidFileDescriptor, false 21 | } 22 | 23 | type hasDescriptor interface { 24 | Fd() uintptr 25 | } 26 | -------------------------------------------------------------------------------- /internal/term/term_test.go: -------------------------------------------------------------------------------- 1 | package term_test 2 | 3 | import ( 4 | "bytes" 5 | "os" 6 | "testing" 7 | 8 | "github.com/sclevine/spec" 9 | "github.com/sclevine/spec/report" 10 | 11 | "github.com/buildpacks/pack/internal/term" 12 | h "github.com/buildpacks/pack/testhelpers" 13 | ) 14 | 15 | func TestTerm(t *testing.T) { 16 | spec.Run(t, "Term", testTerm, spec.Parallel(), spec.Report(report.Terminal{})) 17 | } 18 | 19 | func testTerm(t *testing.T, when spec.G, it spec.S) { 20 | when("#IsTerminal", func() { 21 | it("returns false for a pipe", func() { 22 | r, _, _ := os.Pipe() 23 | fd, isTerm := term.IsTerminal(r) 24 | h.AssertFalse(t, isTerm) 25 | h.AssertNotEq(t, fd, term.InvalidFileDescriptor) // The mock writer is a pipe, and therefore has a file descriptor 26 | }) 27 | 28 | it("returns InvalidFileDescriptor if passed a normal Writer", func() { 29 | fd, isTerm := term.IsTerminal(&bytes.Buffer{}) 30 | h.AssertFalse(t, isTerm) 31 | h.AssertEq(t, fd, term.InvalidFileDescriptor) 32 | }) 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /internal/termui/branch.go: -------------------------------------------------------------------------------- 1 | package termui 2 | 3 | type Symbol int 4 | 5 | func (s Symbol) String() string { 6 | switch s { 7 | case NoBranchSymbol: 8 | return " " 9 | case BranchSymbol: 10 | return "│ " 11 | case MiddleBranchSymbol: 12 | return "├── " 13 | case LastBranchSymbol: 14 | return "└── " 15 | default: 16 | return "" 17 | } 18 | } 19 | 20 | const ( 21 | NoBranchSymbol Symbol = iota 22 | BranchSymbol 23 | MiddleBranchSymbol 24 | LastBranchSymbol 25 | ) 26 | 27 | type Branches []Symbol 28 | 29 | func (b Branches) Add(s Symbol) Branches { 30 | bCopy := make(Branches, len(b)) 31 | copy(bCopy, b) 32 | return append(bCopy, s) 33 | } 34 | 35 | func (b Branches) String() string { 36 | var s string 37 | for _, branch := range b[:len(b)-1] { 38 | s += branch.String() 39 | } 40 | return s 41 | } 42 | -------------------------------------------------------------------------------- /internal/termui/fakes/app.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/rivo/tview" 5 | ) 6 | 7 | type App struct { 8 | SetRootCallCount int 9 | DrawCallCount int 10 | 11 | doneChan chan bool 12 | } 13 | 14 | func NewApp() *App { 15 | return &App{ 16 | doneChan: make(chan bool, 1), 17 | } 18 | } 19 | 20 | func (a *App) SetRoot(root tview.Primitive, fullscreen bool) *tview.Application { 21 | a.SetRootCallCount++ 22 | return nil 23 | } 24 | 25 | func (a *App) Draw() *tview.Application { 26 | a.DrawCallCount++ 27 | return nil 28 | } 29 | 30 | func (a *App) QueueUpdateDraw(f func()) *tview.Application { 31 | f() 32 | a.DrawCallCount++ 33 | return nil 34 | } 35 | 36 | func (a *App) Run() error { 37 | <-a.doneChan 38 | return nil 39 | } 40 | 41 | func (a *App) StopRunning() { 42 | a.doneChan <- true 43 | } 44 | 45 | func (a *App) ResetDrawCount() { 46 | a.DrawCallCount = 0 47 | } 48 | -------------------------------------------------------------------------------- /internal/termui/fakes/builder.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "github.com/buildpacks/pack/internal/builder" 5 | "github.com/buildpacks/pack/pkg/dist" 6 | ) 7 | 8 | type Builder struct { 9 | baseImageName string 10 | buildpacks []dist.ModuleInfo 11 | lifecycleDescriptor builder.LifecycleDescriptor 12 | stack builder.StackMetadata 13 | } 14 | 15 | func NewBuilder(baseImageName string, buildpacks []dist.ModuleInfo, lifecycleDescriptor builder.LifecycleDescriptor, stack builder.StackMetadata) *Builder { 16 | return &Builder{ 17 | baseImageName: baseImageName, 18 | buildpacks: buildpacks, 19 | lifecycleDescriptor: lifecycleDescriptor, 20 | stack: stack, 21 | } 22 | } 23 | 24 | func (b *Builder) BaseImageName() string { 25 | return b.baseImageName 26 | } 27 | 28 | func (b *Builder) Buildpacks() []dist.ModuleInfo { 29 | return b.buildpacks 30 | } 31 | 32 | func (b *Builder) LifecycleDescriptor() builder.LifecycleDescriptor { 33 | return b.lifecycleDescriptor 34 | } 35 | 36 | func (b *Builder) Stack() builder.StackMetadata { 37 | return b.stack 38 | } 39 | -------------------------------------------------------------------------------- /internal/termui/fakes/docker_stdwriter.go: -------------------------------------------------------------------------------- 1 | package fakes 2 | 3 | import ( 4 | "io" 5 | "time" 6 | 7 | "github.com/docker/docker/pkg/stdcopy" 8 | ) 9 | 10 | type DockerStdWriter struct { 11 | wOut io.Writer 12 | wErr io.Writer 13 | } 14 | 15 | func NewDockerStdWriter(w io.Writer) *DockerStdWriter { 16 | return &DockerStdWriter{ 17 | wOut: stdcopy.NewStdWriter(w, stdcopy.Stdout), 18 | wErr: stdcopy.NewStdWriter(w, stdcopy.Stderr), 19 | } 20 | } 21 | 22 | func (w *DockerStdWriter) WriteStdoutln(contents string) { 23 | w.write(contents+"\n", stdcopy.Stdout) 24 | } 25 | 26 | func (w *DockerStdWriter) WriteStderrln(contents string) { 27 | w.write(contents+"\n", stdcopy.Stderr) 28 | } 29 | 30 | func (w *DockerStdWriter) write(contents string, t stdcopy.StdType) { 31 | switch t { 32 | case stdcopy.Stdout: 33 | w.wOut.Write([]byte(contents)) 34 | case stdcopy.Stderr: 35 | w.wErr.Write([]byte(contents)) 36 | } 37 | 38 | // guard against race conditions 39 | time.Sleep(time.Millisecond) 40 | } 41 | -------------------------------------------------------------------------------- /internal/termui/logger.go: -------------------------------------------------------------------------------- 1 | package termui 2 | 3 | import "io" 4 | 5 | func (s *Termui) Debug(msg string) { 6 | // not implemented 7 | } 8 | 9 | func (s *Termui) Debugf(fmt string, v ...interface{}) { 10 | // not implemented 11 | } 12 | 13 | func (s *Termui) Info(msg string) { 14 | s.textChan <- msg 15 | } 16 | 17 | func (s *Termui) Infof(fmt string, v ...interface{}) { 18 | // not implemented 19 | } 20 | 21 | func (s *Termui) Warn(msg string) { 22 | // not implemented 23 | } 24 | 25 | func (s *Termui) Warnf(fmt string, v ...interface{}) { 26 | // not implemented 27 | } 28 | 29 | func (s *Termui) Error(msg string) { 30 | // not implemented 31 | } 32 | 33 | func (s *Termui) Errorf(fmt string, v ...interface{}) { 34 | // not implemented 35 | } 36 | 37 | func (s *Termui) Writer() io.Writer { 38 | // not implemented 39 | return nil 40 | } 41 | 42 | func (s *Termui) IsVerbose() bool { 43 | // not implemented 44 | return false 45 | } 46 | -------------------------------------------------------------------------------- /internal/termui/testdata/generate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | dir=$(cd $(dirname $0) && pwd) 4 | mkdir -p $dir/layers/some_buildpack-1 5 | mkdir -p $dir/layers/some_buildpack-2/some-dir 6 | mkdir -p $dir/layers/sbom/launch 7 | 8 | echo -n "some-content-1" > $dir/layers/some_buildpack-1/some-file-1.txt 9 | echo -n "some-content-2" > $dir/layers/some_buildpack-2/some-dir/some-file-2.txt 10 | echo -n '{"content": "some-sbom-content"}' > $dir/layers/sbom/launch/sbom.cdx.json 11 | 12 | tar cvf $dir/fake-layers.tar layers 13 | rm -rf $dir/layers -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/heroku/color" 7 | 8 | "github.com/buildpacks/pack/cmd" 9 | "github.com/buildpacks/pack/pkg/client" 10 | 11 | "github.com/buildpacks/pack/internal/commands" 12 | "github.com/buildpacks/pack/pkg/logging" 13 | ) 14 | 15 | func main() { 16 | // create logger with defaults 17 | logger := logging.NewLogWithWriters(color.Stdout(), color.Stderr()) 18 | 19 | rootCmd, err := cmd.NewPackCommand(logger) 20 | if err != nil { 21 | logger.Error(err.Error()) 22 | os.Exit(1) 23 | } 24 | 25 | ctx := commands.CreateCancellableContext() 26 | if err := rootCmd.ExecuteContext(ctx); err != nil { 27 | if _, isSoftError := err.(client.SoftError); isSoftError { 28 | os.Exit(2) 29 | } 30 | os.Exit(1) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pkg/README.md: -------------------------------------------------------------------------------- 1 | `pkg/` is a collection of utility packages that are used by the Pack CLI, without being specific to its internals. Some 2 | packages may get moved to `imgutil` when a project wide common API is developed, but this is a first landing spot allowing 3 | us to share code with the community. 4 | -------------------------------------------------------------------------------- /pkg/archive/archive_unix.go: -------------------------------------------------------------------------------- 1 | //go:build unix 2 | 3 | package archive 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | ) 9 | 10 | // hasHardlinks check if the given files has a hard-link associated with it 11 | func hasHardlinks(fi os.FileInfo, path string) (bool, error) { 12 | return fi.Sys().(*syscall.Stat_t).Nlink > 1, nil 13 | } 14 | 15 | // getInodeFromStat returns the inode (index node) value associated with the given file 16 | func getInodeFromStat(stat interface{}, path string) (inode uint64, err error) { 17 | s, ok := stat.(*syscall.Stat_t) 18 | if ok { 19 | inode = s.Ino 20 | } 21 | return 22 | } 23 | -------------------------------------------------------------------------------- /pkg/archive/testdata/dir-to-tar-with-hardlink/original-file: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /pkg/archive/testdata/dir-to-tar/some-file.txt: -------------------------------------------------------------------------------- 1 | some-content -------------------------------------------------------------------------------- /pkg/archive/testdata/dir-to-tar/sub-dir/link-file: -------------------------------------------------------------------------------- 1 | ../some-file.txt -------------------------------------------------------------------------------- /pkg/archive/testdata/fat-zip-to-tar.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/archive/testdata/fat-zip-to-tar.zip -------------------------------------------------------------------------------- /pkg/archive/testdata/jar-file.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/archive/testdata/jar-file.jar -------------------------------------------------------------------------------- /pkg/archive/testdata/zip-to-tar.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/archive/testdata/zip-to-tar.zip -------------------------------------------------------------------------------- /pkg/archive/umask_unix.go: -------------------------------------------------------------------------------- 1 | //go:build unix 2 | 3 | package archive 4 | 5 | import ( 6 | "io/fs" 7 | "syscall" 8 | ) 9 | 10 | func init() { 11 | Umask = fs.FileMode(syscall.Umask(0)) 12 | syscall.Umask(int(Umask)) 13 | } 14 | -------------------------------------------------------------------------------- /pkg/blob/testdata/blob/file.txt: -------------------------------------------------------------------------------- 1 | contents -------------------------------------------------------------------------------- /pkg/blob/testdata/buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | id = "bp.one" 3 | version = "bp.one.version" 4 | homepage = "http://one.buildpack" 5 | 6 | # technically, this is invalid as a buildpack cannot have both an order and stacks 7 | # however, we're just testing that all the correct fields are parsed 8 | [[order]] 9 | [[order.group]] 10 | id = "bp.nested" 11 | version = "bp.nested.version" 12 | 13 | [[stacks]] 14 | id = "some.stack.id" 15 | 16 | [[stacks]] 17 | id = "other.stack.id" 18 | -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/cacher: -------------------------------------------------------------------------------- 1 | cacher -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /pkg/blob/testdata/lifecycle/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /pkg/buildpack/buildpackage.go: -------------------------------------------------------------------------------- 1 | package buildpack 2 | 3 | import ( 4 | "github.com/buildpacks/pack/pkg/dist" 5 | ) 6 | 7 | // TODO: Move to dist 8 | const MetadataLabel = "io.buildpacks.buildpackage.metadata" 9 | 10 | type Metadata struct { 11 | dist.ModuleInfo 12 | Stacks []dist.Stack `toml:"stacks" json:"stacks"` 13 | } 14 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack-with-hardlink/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack-with-hardlink/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/buildpack-with-hardlink/bin/detect -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack-with-hardlink/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack-with-hardlink/original-file: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/buildpack/bin/detect -------------------------------------------------------------------------------- /pkg/buildpack/testdata/buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/extension/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/extension/bin/detect -------------------------------------------------------------------------------- /pkg/buildpack/testdata/extension/bin/generate: -------------------------------------------------------------------------------- 1 | generate-contents -------------------------------------------------------------------------------- /pkg/buildpack/testdata/extension/extension.toml: -------------------------------------------------------------------------------- 1 | api = "0.9" 2 | 3 | [extension] 4 | id = "ext.one" 5 | version = "1.2.3" 6 | homepage = "http://one.extension" 7 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/hello-universe-oci.cnb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/hello-universe-oci.cnb -------------------------------------------------------------------------------- /pkg/buildpack/testdata/hello-universe.cnb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/hello-universe.cnb -------------------------------------------------------------------------------- /pkg/buildpack/testdata/package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "https://example.com/bp/a.tgz" 3 | 4 | [[dependencies]] 5 | uri = "https://example.com/bp/b.tgz" 6 | 7 | [[dependencies]] 8 | uri = "bp/c" 9 | 10 | [[dependencies]] 11 | image = "registry.example.com/bp/d" 12 | -------------------------------------------------------------------------------- /pkg/buildpack/testdata/tree-extension.cnb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/buildpack/testdata/tree-extension.cnb -------------------------------------------------------------------------------- /pkg/cache/bind_cache.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "context" 5 | "os" 6 | ) 7 | 8 | type BindCache struct { 9 | docker DockerClient 10 | bind string 11 | } 12 | 13 | func NewBindCache(cacheType CacheInfo, dockerClient DockerClient) *BindCache { 14 | return &BindCache{ 15 | bind: cacheType.Source, 16 | docker: dockerClient, 17 | } 18 | } 19 | 20 | func (c *BindCache) Name() string { 21 | return c.bind 22 | } 23 | 24 | func (c *BindCache) Clear(ctx context.Context) error { 25 | err := os.RemoveAll(c.bind) 26 | if err != nil { 27 | return err 28 | } 29 | return nil 30 | } 31 | 32 | func (c *BindCache) Type() Type { 33 | return Bind 34 | } 35 | -------------------------------------------------------------------------------- /pkg/cache/consts.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | const ( 4 | Image Type = iota 5 | Volume 6 | Bind 7 | ) 8 | 9 | type Type int 10 | -------------------------------------------------------------------------------- /pkg/cache/image_cache.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/docker/docker/api/types/image" 7 | "github.com/docker/docker/client" 8 | "github.com/google/go-containerregistry/pkg/name" 9 | ) 10 | 11 | type ImageCache struct { 12 | docker DockerClient 13 | image string 14 | } 15 | 16 | type DockerClient interface { 17 | ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error) 18 | VolumeRemove(ctx context.Context, volumeID string, force bool) error 19 | } 20 | 21 | func NewImageCache(imageRef name.Reference, dockerClient DockerClient) *ImageCache { 22 | return &ImageCache{ 23 | image: imageRef.Name(), 24 | docker: dockerClient, 25 | } 26 | } 27 | 28 | func (c *ImageCache) Name() string { 29 | return c.image 30 | } 31 | 32 | func (c *ImageCache) Clear(ctx context.Context) error { 33 | _, err := c.docker.ImageRemove(ctx, c.Name(), image.RemoveOptions{ 34 | Force: true, 35 | }) 36 | if err != nil && !client.IsErrNotFound(err) { 37 | return err 38 | } 39 | return nil 40 | } 41 | 42 | func (c *ImageCache) Type() Type { 43 | return Image 44 | } 45 | -------------------------------------------------------------------------------- /pkg/client/errors.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | // ExperimentError denotes that an experimental feature was trying to be used without experimental features enabled. 4 | type ExperimentError struct { 5 | msg string 6 | } 7 | 8 | func NewExperimentError(msg string) ExperimentError { 9 | return ExperimentError{msg} 10 | } 11 | 12 | func (ee ExperimentError) Error() string { 13 | return ee.msg 14 | } 15 | 16 | // SoftError is an error that is not intended to be displayed. 17 | type SoftError struct{} 18 | 19 | func NewSoftError() SoftError { 20 | return SoftError{} 21 | } 22 | 23 | func (se SoftError) Error() string { 24 | return "" 25 | } 26 | -------------------------------------------------------------------------------- /pkg/client/example_build_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows && example 2 | 3 | package client_test 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "path/filepath" 9 | 10 | "github.com/buildpacks/pack/pkg/client" 11 | ) 12 | 13 | // This example shows the basic usage of the package: Create a client, 14 | // call a configuration object, call the client's Build function. 15 | func Example_build() { 16 | // create a context object 17 | context := context.Background() 18 | 19 | // initialize a pack client 20 | pack, err := client.NewClient() 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | // replace this with the location of a sample application 26 | // For a list of prepared samples see the 'apps' folder at 27 | // https://github.com/buildpacks/samples. 28 | appPath := filepath.Join("testdata", "some-app") 29 | 30 | // initialize our options 31 | buildOpts := client.BuildOptions{ 32 | Image: "pack-lib-test-image:0.0.1", 33 | Builder: "cnbs/sample-builder:bionic", 34 | AppPath: appPath, 35 | TrustBuilder: func(string) bool { return true }, 36 | } 37 | 38 | // build an image 39 | err = pack.Build(context, buildOpts) 40 | if err != nil { 41 | panic(err) 42 | } 43 | 44 | fmt.Println("build completed") 45 | // Output: build completed 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/manifest_add.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/buildpacks/pack/internal/style" 8 | ) 9 | 10 | type ManifestAddOptions struct { 11 | // Image index we want to update 12 | IndexRepoName string 13 | 14 | // Name of image we wish to add into the image index 15 | RepoName string 16 | } 17 | 18 | // AddManifest implements commands.PackClient. 19 | func (c *Client) AddManifest(ctx context.Context, opts ManifestAddOptions) (err error) { 20 | idx, err := c.indexFactory.LoadIndex(opts.IndexRepoName) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | if err = c.addManifestToIndex(ctx, opts.RepoName, idx); err != nil { 26 | return err 27 | } 28 | 29 | if err = idx.SaveDir(); err != nil { 30 | return fmt.Errorf("failed to save manifest list %s to local storage: %w", style.Symbol(opts.RepoName), err) 31 | } 32 | 33 | c.logger.Infof("Successfully added image %s to index", style.Symbol(opts.RepoName)) 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /pkg/client/manifest_inspect.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/buildpacks/imgutil" 7 | ) 8 | 9 | // InspectManifest implements commands.PackClient. 10 | func (c *Client) InspectManifest(indexRepoName string) error { 11 | var ( 12 | index imgutil.ImageIndex 13 | indexStr string 14 | err error 15 | ) 16 | 17 | index, err = c.indexFactory.FindIndex(indexRepoName) 18 | if err != nil { 19 | return err 20 | } 21 | 22 | if indexStr, err = index.Inspect(); err != nil { 23 | return fmt.Errorf("failed to inspect manifest list '%s': %w", indexRepoName, err) 24 | } 25 | 26 | c.logger.Info(indexStr) 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /pkg/client/manifest_remove.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "errors" 4 | 5 | // DeleteManifest implements commands.PackClient. 6 | func (c *Client) DeleteManifest(names []string) error { 7 | var allErrors error 8 | for _, name := range names { 9 | imgIndex, err := c.indexFactory.LoadIndex(name) 10 | if err != nil { 11 | allErrors = errors.Join(allErrors, err) 12 | continue 13 | } 14 | 15 | if err := imgIndex.DeleteDir(); err != nil { 16 | allErrors = errors.Join(allErrors, err) 17 | } 18 | } 19 | 20 | if allErrors == nil { 21 | c.logger.Info("Successfully deleted manifest list(s) from local storage") 22 | } 23 | return allErrors 24 | } 25 | -------------------------------------------------------------------------------- /pkg/client/manifest_rm.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | gccrName "github.com/google/go-containerregistry/pkg/name" 8 | ) 9 | 10 | // RemoveManifest implements commands.PackClient. 11 | func (c *Client) RemoveManifest(name string, images []string) error { 12 | var allErrors error 13 | 14 | imgIndex, err := c.indexFactory.LoadIndex(name) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | for _, image := range images { 20 | ref, err := gccrName.NewDigest(image, gccrName.WeakValidation, gccrName.Insecure) 21 | if err != nil { 22 | allErrors = errors.Join(allErrors, fmt.Errorf("invalid instance '%s': %w", image, err)) 23 | } 24 | 25 | if err = imgIndex.RemoveManifest(ref); err != nil { 26 | allErrors = errors.Join(allErrors, err) 27 | } 28 | 29 | if err = imgIndex.SaveDir(); err != nil { 30 | allErrors = errors.Join(allErrors, err) 31 | } 32 | } 33 | 34 | if allErrors == nil { 35 | c.logger.Infof("Successfully removed image(s) from index: '%s'", name) 36 | } 37 | 38 | return allErrors 39 | } 40 | -------------------------------------------------------------------------------- /pkg/client/testdata/builder.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | id = "some.bp1" 3 | uri = "some-path-1" 4 | 5 | [[buildpacks]] 6 | id = "some/bp2" 7 | uri = "some-path-2" 8 | 9 | [[buildpacks]] 10 | id = "some/bp2" 11 | uri = "some-path-3" 12 | 13 | [[order]] 14 | [[order.group]] 15 | id = "some.bp1" 16 | version = "1.2.3" 17 | 18 | [[order.group]] 19 | id = "some/bp2" 20 | version = "1.2.4" 21 | 22 | [[order]] 23 | [[order.group]] 24 | id = "some.bp1" 25 | version = "1.2.3" 26 | 27 | [stack] 28 | id = "com.example.stack" 29 | build-image = "some/build" 30 | run-image = "some/run" 31 | run-image-mirrors = ["gcr.io/some/run2"] -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-api-0.4/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-api-0.4/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-api-0.4/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-api-0.4/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-1/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-1" 5 | version = "1" 6 | homepage = "http://buildpack-1" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "flatten/bp-2" 11 | version = "2" 12 | 13 | [[order.group]] 14 | id = "flatten/bp-3" 15 | version = "3" 16 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-2/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-2/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-flatten/buildpack-2/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-2" 5 | version = "2" 6 | homepage = "http://buildpack-2" 7 | 8 | [[stacks]] 9 | id = "*" 10 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-3/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-3" 5 | version = "3" 6 | homepage = "http://buildpack-3" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "flatten/bp-4" 11 | version = "4" 12 | 13 | [[order.group]] 14 | id = "flatten/bp-5" 15 | version = "5" 16 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-4/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-4/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-flatten/buildpack-4/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-4/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-4" 5 | version = "4" 6 | homepage = "http://buildpack-4" 7 | 8 | [[stacks]] 9 | id = "*" 10 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-5/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-5" 5 | version = "5" 6 | homepage = "http://buildpack-5" 7 | 8 | [[order]] 9 | [[order.group]] 10 | id = "flatten/bp-6" 11 | version = "6" 12 | 13 | [[order.group]] 14 | id = "flatten/bp-7" 15 | version = "7" 16 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-6/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-6/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-flatten/buildpack-6/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-6/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-6" 5 | version = "6" 6 | homepage = "http://buildpack-6" 7 | 8 | [[stacks]] 9 | id = "*" 10 | 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-7/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-7/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-flatten/buildpack-7/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-flatten/buildpack-7/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "flatten/bp-7" 5 | version = "7" 6 | homepage = "http://buildpack-7" 7 | 8 | [[stacks]] 9 | id = "*" 10 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/README.md: -------------------------------------------------------------------------------- 1 | When creating multi-platform buildpacks, the root buildpack.toml file must be copied into each 2 | plaform root folder; this operation must be done by the caller of the method: 3 | 4 | `PackageBuildpack(ctx context.Context, opts PackageBuildpackOptions) error` 5 | 6 | To simplify the tests, the buildpack.toml is already copied in each buildpack folder. 7 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-composite-with-dependencies-on-disk/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/composite-buildpack" 5 | version = "0.0.1" 6 | 7 | # Order used for detection 8 | [[order]] 9 | [[order.group]] 10 | id = "samples/bp-1" 11 | version = "0.0.1" 12 | 13 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-composite-with-dependencies-on-disk/package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "." 3 | 4 | [[targets]] 5 | os = "linux" 6 | arch = "amd64" 7 | 8 | [[targets]] 9 | os = "linux" 10 | arch = "arm64" 11 | 12 | [[dependencies]] 13 | uri = "../samples/bp-1" 14 | 15 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-composite/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/composite-buildpack" 5 | version = "0.0.1" 6 | 7 | # Order used for detection 8 | [[order]] 9 | [[order.group]] 10 | id = "samples/bp-1" 11 | version = "0.0.1" 12 | 13 | [[order.group]] 14 | id = "samples/bp-2" 15 | version = "0.0.1" 16 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-composite/package.toml: -------------------------------------------------------------------------------- 1 | [buildpack] 2 | uri = "." 3 | 4 | [[targets]] 5 | os = "linux" 6 | arch = "amd64" 7 | 8 | [[targets]] 9 | os = "linux" 10 | arch = "arm64" 11 | 12 | [[dependencies]] 13 | uri = "localhost:3333/bp-1" 14 | 15 | [[dependencies]] 16 | uri = "localhost:3333/bp-2" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@18.01/bin/build: -------------------------------------------------------------------------------- 1 | build-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@18.01/bin/detect: -------------------------------------------------------------------------------- 1 | detect-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@18.01/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | [[targets.distributions]] 11 | name = "ubuntu" 12 | versions = ["18.01", "21.01"] 13 | 14 | [[targets]] 15 | os = "linux" 16 | arch = "arm64" 17 | variant = "v6" 18 | [[targets.distributions]] 19 | name = "ubuntu" 20 | versions = ["18.01", "21.01"] 21 | 22 | [[stacks]] 23 | id = "*" 24 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@21.01/bin/build: -------------------------------------------------------------------------------- 1 | build-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@21.01/bin/detect: -------------------------------------------------------------------------------- 1 | detect-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/amd64/v5/ubuntu@21.01/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@18.01/bin/build: -------------------------------------------------------------------------------- 1 | build-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@18.01/bin/detect: -------------------------------------------------------------------------------- 1 | detect-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@18.01/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@21.01/bin/build: -------------------------------------------------------------------------------- 1 | build-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@21.01/bin/detect: -------------------------------------------------------------------------------- 1 | detect-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format-with-versions/linux/arm/v6/ubuntu@21.01/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/amd64/bin/build: -------------------------------------------------------------------------------- 1 | build-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/amd64/bin/detect: -------------------------------------------------------------------------------- 1 | detect-amd64-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/amd64/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/arm/bin/build: -------------------------------------------------------------------------------- 1 | build-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/arm/bin/detect: -------------------------------------------------------------------------------- 1 | detect-arm-contents 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/arm/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-new-format/linux/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.10" 2 | 3 | [buildpack] 4 | id = "samples/multi-platform" 5 | version = "0.0.1" 6 | 7 | [[targets]] 8 | os = "linux" 9 | arch = "amd64" 10 | 11 | [[targets]] 12 | os = "linux" 13 | arch = "arm64" 14 | 15 | [[stacks]] 16 | id = "*" 17 | 18 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-old-format/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-old-format/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-multi-platform/buildpack-old-format/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-multi-platform/buildpack-old-format/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-1/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-1/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-1/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-1/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "buildpack-1-id" 5 | version = "buildpack-1-version-1" 6 | homepage = "http://non-deterministic.buildpack-1" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-2/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-2/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-2/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-1-version-2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "buildpack-1-id" 5 | version = "buildpack-1-version-2" 6 | homepage = "http://non-deterministic.buildpack-1" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | 12 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-1/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-1/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-1/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-1/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "buildpack-2-id" 5 | version = "buildpack-2-version-1" 6 | homepage = "http://non-deterministic.buildpack-2" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-2/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-2/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-2/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack-non-deterministic/buildpack-2-version-2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "buildpack-2-id" 5 | version = "buildpack-2-version-2" 6 | homepage = "http://non-deterministic.buildpack-2" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack2/bin/build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack2/bin/build -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack2/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/buildpack2/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/buildpack2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "some-other-buildpack-id" 5 | version = "some-other-buildpack-version" 6 | 7 | [[stacks]] 8 | id = "some.stack.id" 9 | mixins = ["mixinA", "build:mixinB", "run:mixinC"] 10 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/config-does-not-exist/README: -------------------------------------------------------------------------------- 1 | This folder is intentionally empty to test the scenario when the docker config.json file doesn't exist 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/current-context-does-not-match/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "desktop-linux" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/current-context-does-not-match/contexts/meta/fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "bad-name", 3 | "Endpoints": { 4 | "docker": { 5 | "Host": "unix:///Users/user/.docker/run/docker.sock" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/docker-endpoint-does-not-exist/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "desktop-linux" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/docker-endpoint-does-not-exist/contexts/meta/fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "desktop-linux", 3 | "Endpoints": { 4 | "foo": { 5 | "Host": "unix:///Users/user/.docker/run/docker.sock" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/empty-context/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "some-bad-context" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/invalid-config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "some-bad-context 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/invalid-metadata/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "desktop-linux" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/error-cases/invalid-metadata/contexts/meta/fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "desktop-linux", 3 | "Endpoints": { 4 | "docker": { 5 | "Host": "unix:///Users/user/.docker/run/docker.sock 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/current-context-not-defined/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auths": { 3 | "https://index.docker.io/v1/": {} 4 | }, 5 | "credsStore": "desktop", 6 | "experimental": "disabled" 7 | } 8 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/custom-context/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "desktop-linux" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/custom-context/contexts/meta/fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "desktop-linux", 3 | "Endpoints": { 4 | "docker": { 5 | "Host": "unix:///Users/user/.docker/run/docker.sock" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/default-context/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "default" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/two-endpoints-context/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentContext": "desktop-linux" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/docker-context/happy-cases/two-endpoints-context/contexts/meta/fe9c6bd7a66301f49ca9b6a70b217107cd1284598bfc254700c989b916da791e/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "desktop-linux", 3 | "Endpoints": { 4 | "docker": { 5 | "Host": "unix:///Users/user/.docker/run/docker.sock" 6 | }, 7 | "foo": { 8 | "Host": "something else" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /pkg/client/testdata/downloader/dirA/file.txt: -------------------------------------------------------------------------------- 1 | some file contents -------------------------------------------------------------------------------- /pkg/client/testdata/empty-file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/empty-file -------------------------------------------------------------------------------- /pkg/client/testdata/extension-api-0.9/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/extension-api-0.9/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/extension-api-0.9/bin/generate: -------------------------------------------------------------------------------- 1 | generate-contents -------------------------------------------------------------------------------- /pkg/client/testdata/extension-api-0.9/extension.toml: -------------------------------------------------------------------------------- 1 | api = "0.9" 2 | 3 | [extension] 4 | id = "ext.one" 5 | version = "1.2.3" 6 | homepage = "http://one.extension" 7 | -------------------------------------------------------------------------------- /pkg/client/testdata/extension/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/extension/bin/detect -------------------------------------------------------------------------------- /pkg/client/testdata/extension/bin/generate: -------------------------------------------------------------------------------- 1 | generate-contents -------------------------------------------------------------------------------- /pkg/client/testdata/extension/extension.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [extension] 4 | id = "ext.one" 5 | version = "1.2.3" 6 | homepage = "http://one.extension" 7 | -------------------------------------------------------------------------------- /pkg/client/testdata/jar-file.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/jar-file.jar -------------------------------------------------------------------------------- /pkg/client/testdata/just-a-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/just-a-file.txt -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/lifecycle.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/lifecycle/lifecycle.tar -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.3/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [api] 5 | buildpack = "0.2" 6 | platform = "0.3" -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /pkg/client/testdata/lifecycle/platform-0.4/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [apis] 5 | [apis.buildpack] 6 | deprecated = ["0.2", "0.3"] 7 | supported = ["0.2", "0.3", "0.4", "0.9"] 8 | 9 | [apis.platform] 10 | deprecated = ["0.2"] 11 | supported = ["0.3", "0.4"] -------------------------------------------------------------------------------- /pkg/client/testdata/non-zip-file: -------------------------------------------------------------------------------- 1 | some-content -------------------------------------------------------------------------------- /pkg/client/testdata/registry/3/fo/example_foo: -------------------------------------------------------------------------------- 1 | {"ns":"example","name":"foo","version":"1.0.0","yanked":false,"addr":"example.com/some/package@sha256:8c27fe111c11b722081701dfed3bd55e039b9ce92865473cf4cdfa918071c566"} 2 | {"ns":"example","name":"foo","version":"1.1.0","yanked":false,"addr":"example.com/some/package@sha256:74eb48882e835d8767f62940d453eb96ed2737de3a16573881dcea7dea769df7"} 3 | {"ns":"example","name":"foo","version":"1.2.0","yanked":false,"addr":"example.com/some/package@sha256:2560f05307e8de9d830f144d09556e19dd1eb7d928aee900ed02208ae9727e7a"} 4 | -------------------------------------------------------------------------------- /pkg/client/testdata/registry/ja/va/example_java: -------------------------------------------------------------------------------- 1 | {"ns":"example","name":"java","version":"1.0.0","yanked":false,"addr":"example.com/some/package@sha256:8c27fe111c11b722081701dfed3bd55e039b9ce92865473cf4cdfa918071c566"} 2 | -------------------------------------------------------------------------------- /pkg/client/testdata/some-app/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore -------------------------------------------------------------------------------- /pkg/client/testdata/zip-file.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/pkg/client/testdata/zip-file.zip -------------------------------------------------------------------------------- /pkg/client/version.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | // Version returns the version of the client 4 | func (c *Client) Version() string { 5 | return c.version 6 | } 7 | -------------------------------------------------------------------------------- /pkg/dist/distribution.go: -------------------------------------------------------------------------------- 1 | // Package dist is responsible for cataloging all data types in relation 2 | // to distributing Cloud Native Buildpack components. 3 | package dist 4 | -------------------------------------------------------------------------------- /pkg/dist/extension_descriptor.go: -------------------------------------------------------------------------------- 1 | package dist 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/buildpacks/lifecycle/api" 7 | ) 8 | 9 | type ExtensionDescriptor struct { 10 | WithAPI *api.Version `toml:"api"` 11 | WithInfo ModuleInfo `toml:"extension"` 12 | WithTargets []Target `toml:"targets,omitempty"` 13 | } 14 | 15 | func (e *ExtensionDescriptor) EnsureStackSupport(_ string, _ []string, _ bool) error { 16 | return nil 17 | } 18 | 19 | func (e *ExtensionDescriptor) EnsureTargetSupport(_, _, _, _ string) error { 20 | return nil 21 | } 22 | 23 | func (e *ExtensionDescriptor) EscapedID() string { 24 | return strings.ReplaceAll(e.Info().ID, "/", "_") 25 | } 26 | 27 | func (e *ExtensionDescriptor) Kind() string { 28 | return "extension" 29 | } 30 | 31 | func (e *ExtensionDescriptor) API() *api.Version { 32 | return e.WithAPI 33 | } 34 | 35 | func (e *ExtensionDescriptor) Info() ModuleInfo { 36 | return e.WithInfo 37 | } 38 | 39 | func (e *ExtensionDescriptor) Order() Order { 40 | return nil 41 | } 42 | 43 | func (e *ExtensionDescriptor) Stacks() []Stack { 44 | return nil 45 | } 46 | 47 | func (e *ExtensionDescriptor) Targets() []Target { 48 | return e.WithTargets 49 | } 50 | -------------------------------------------------------------------------------- /pkg/dist/image.go: -------------------------------------------------------------------------------- 1 | package dist 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/pkg/errors" 7 | 8 | "github.com/buildpacks/pack/internal/style" 9 | ) 10 | 11 | type Labeled interface { 12 | Label(name string) (value string, err error) 13 | } 14 | 15 | type Labelable interface { 16 | SetLabel(name string, value string) error 17 | } 18 | 19 | func SetLabel(labelable Labelable, label string, data interface{}) error { 20 | dataBytes, err := json.Marshal(data) 21 | if err != nil { 22 | return errors.Wrapf(err, "marshalling data to JSON for label %s", style.Symbol(label)) 23 | } 24 | if err := labelable.SetLabel(label, string(dataBytes)); err != nil { 25 | return errors.Wrapf(err, "setting label %s", style.Symbol(label)) 26 | } 27 | return nil 28 | } 29 | 30 | func GetLabel(labeled Labeled, label string, obj interface{}) (ok bool, err error) { 31 | labelData, err := labeled.Label(label) 32 | if err != nil { 33 | return false, errors.Wrapf(err, "retrieving label %s", style.Symbol(label)) 34 | } 35 | if labelData != "" { 36 | if err := json.Unmarshal([]byte(labelData), obj); err != nil { 37 | return false, errors.Wrapf(err, "unmarshalling label %s", style.Symbol(label)) 38 | } 39 | return true, nil 40 | } 41 | return false, nil 42 | } 43 | -------------------------------------------------------------------------------- /pkg/image/pull_policy.go: -------------------------------------------------------------------------------- 1 | package image 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | ) 6 | 7 | // PullPolicy defines a policy for how to manage images 8 | type PullPolicy int 9 | 10 | const ( 11 | // PullAlways images, even if they are present 12 | PullAlways PullPolicy = iota 13 | // PullNever images, even if they are not present 14 | PullNever 15 | // PullIfNotPresent pulls images if they aren't present 16 | PullIfNotPresent 17 | ) 18 | 19 | var nameMap = map[string]PullPolicy{"always": PullAlways, "never": PullNever, "if-not-present": PullIfNotPresent, "": PullAlways} 20 | 21 | // ParsePullPolicy from string 22 | func ParsePullPolicy(policy string) (PullPolicy, error) { 23 | if val, ok := nameMap[policy]; ok { 24 | return val, nil 25 | } 26 | 27 | return PullAlways, errors.Errorf("invalid pull policy %s", policy) 28 | } 29 | 30 | func (p PullPolicy) String() string { 31 | switch p { 32 | case PullAlways: 33 | return "always" 34 | case PullNever: 35 | return "never" 36 | case PullIfNotPresent: 37 | return "if-not-present" 38 | } 39 | 40 | return "" 41 | } 42 | -------------------------------------------------------------------------------- /pkg/project/v01/project.go: -------------------------------------------------------------------------------- 1 | package v01 2 | 3 | import ( 4 | "github.com/BurntSushi/toml" 5 | "github.com/buildpacks/lifecycle/api" 6 | 7 | "github.com/buildpacks/pack/pkg/project/types" 8 | ) 9 | 10 | type Descriptor struct { 11 | Project types.Project `toml:"project"` 12 | Build types.Build `toml:"build"` 13 | Metadata map[string]interface{} `toml:"metadata"` 14 | } 15 | 16 | func NewDescriptor(projectTomlContents string) (types.Descriptor, toml.MetaData, error) { 17 | versionedDescriptor := &Descriptor{} 18 | 19 | tomlMetaData, err := toml.Decode(projectTomlContents, versionedDescriptor) 20 | if err != nil { 21 | return types.Descriptor{}, tomlMetaData, err 22 | } 23 | 24 | return types.Descriptor{ 25 | Project: versionedDescriptor.Project, 26 | Build: versionedDescriptor.Build, 27 | Metadata: versionedDescriptor.Metadata, 28 | SchemaVersion: api.MustParse("0.1"), 29 | }, tomlMetaData, nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/testmocks/mock_image.go: -------------------------------------------------------------------------------- 1 | package testmocks 2 | 3 | import ( 4 | "github.com/buildpacks/imgutil" 5 | "github.com/buildpacks/imgutil/fakes" 6 | ) 7 | 8 | type MockImage struct { 9 | *fakes.Image 10 | EntrypointCall struct { 11 | callCount int 12 | Received struct{} 13 | Returns struct { 14 | StringArr []string 15 | Error error 16 | } 17 | Stub func() ([]string, error) 18 | } 19 | } 20 | 21 | func NewImage(name, topLayerSha string, identifier imgutil.Identifier) *MockImage { 22 | return &MockImage{ 23 | Image: fakes.NewImage(name, topLayerSha, identifier), 24 | } 25 | } 26 | 27 | func (m *MockImage) Entrypoint() ([]string, error) { 28 | if m.EntrypointCall.Stub != nil { 29 | return m.EntrypointCall.Stub() 30 | } 31 | return m.EntrypointCall.Returns.StringArr, m.EntrypointCall.Returns.Error 32 | } 33 | -------------------------------------------------------------------------------- /project.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | version = "1.0.2" 3 | source-url = "https://github.com/buildpacks/pack" 4 | 5 | [[build.env]] 6 | name = "BP_GO_TARGETS" 7 | value = "./cmd/pack" 8 | -------------------------------------------------------------------------------- /registry/type.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | const ( 4 | TypeGit = "git" 5 | TypeGitHub = "github" 6 | ) 7 | 8 | var Types = []string{ 9 | TypeGit, 10 | TypeGitHub, 11 | } 12 | -------------------------------------------------------------------------------- /resources/pack-build.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/resources/pack-build.gif -------------------------------------------------------------------------------- /testdata/builder.toml: -------------------------------------------------------------------------------- 1 | [[buildpacks]] 2 | id = "some.bp1" 3 | uri = "some-path-1" 4 | 5 | [[buildpacks]] 6 | id = "some/bp2" 7 | uri = "some-path-2" 8 | 9 | [[buildpacks]] 10 | id = "some/bp2" 11 | uri = "some-path-3" 12 | 13 | [[order]] 14 | [[order.group]] 15 | id = "some.bp1" 16 | version = "1.2.3" 17 | 18 | [[order.group]] 19 | id = "some/bp2" 20 | version = "1.2.4" 21 | 22 | [[order]] 23 | [[order.group]] 24 | id = "some.bp1" 25 | version = "1.2.3" 26 | 27 | [stack] 28 | id = "com.example.stack" 29 | build-image = "some/build" 30 | run-image = "some/run" 31 | run-image-mirrors = ["gcr.io/some/run2"] -------------------------------------------------------------------------------- /testdata/buildpack-api-0.4/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /testdata/buildpack-api-0.4/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/buildpack-api-0.4/bin/detect -------------------------------------------------------------------------------- /testdata/buildpack-api-0.4/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.4" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /testdata/buildpack/bin/build: -------------------------------------------------------------------------------- 1 | build-contents -------------------------------------------------------------------------------- /testdata/buildpack/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/buildpack/bin/detect -------------------------------------------------------------------------------- /testdata/buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "bp.one" 5 | version = "1.2.3" 6 | homepage = "http://one.buildpack" 7 | 8 | [[stacks]] 9 | id = "some.stack.id" 10 | mixins = ["mixinX", "build:mixinY", "run:mixinZ"] 11 | -------------------------------------------------------------------------------- /testdata/buildpack2/bin/build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/buildpack2/bin/build -------------------------------------------------------------------------------- /testdata/buildpack2/bin/detect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/buildpack2/bin/detect -------------------------------------------------------------------------------- /testdata/buildpack2/buildpack.toml: -------------------------------------------------------------------------------- 1 | api = "0.3" 2 | 3 | [buildpack] 4 | id = "some-other-buildpack-id" 5 | version = "some-other-buildpack-version" 6 | 7 | [[stacks]] 8 | id = "some.stack.id" 9 | mixins = ["mixinA", "build:mixinB", "run:mixinC"] 10 | -------------------------------------------------------------------------------- /testdata/downloader/dirA/file.txt: -------------------------------------------------------------------------------- 1 | some file contents -------------------------------------------------------------------------------- /testdata/empty-file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/empty-file -------------------------------------------------------------------------------- /testdata/jar-file.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/jar-file.jar -------------------------------------------------------------------------------- /testdata/just-a-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/just-a-file.txt -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.3/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [api] 5 | buildpack = "0.2" 6 | platform = "0.3" -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/analyzer: -------------------------------------------------------------------------------- 1 | analyzer -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/builder: -------------------------------------------------------------------------------- 1 | builder -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/creator: -------------------------------------------------------------------------------- 1 | creator -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/detector: -------------------------------------------------------------------------------- 1 | detector -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/exporter: -------------------------------------------------------------------------------- 1 | exporter -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/launcher: -------------------------------------------------------------------------------- 1 | launcher -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle-v0.0.0-arch/restorer: -------------------------------------------------------------------------------- 1 | restorer -------------------------------------------------------------------------------- /testdata/lifecycle/platform-0.4/lifecycle.toml: -------------------------------------------------------------------------------- 1 | [lifecycle] 2 | version = "0.0.0" 3 | 4 | [apis] 5 | [apis.buildpack] 6 | deprecated = ["0.2", "0.3"] 7 | supported = ["0.2", "0.3", "0.4"] 8 | 9 | [apis.platform] 10 | deprecated = ["0.2"] 11 | supported = ["0.3", "0.4"] -------------------------------------------------------------------------------- /testdata/non-zip-file: -------------------------------------------------------------------------------- 1 | some-content -------------------------------------------------------------------------------- /testdata/registry/3/fo/example_foo: -------------------------------------------------------------------------------- 1 | {"ns":"example","name":"foo","version":"1.0.0","yanked":false,"addr":"example.com/some/package@sha256:8c27fe111c11b722081701dfed3bd55e039b9ce92865473cf4cdfa918071c566"} 2 | {"ns":"example","name":"foo","version":"1.1.0","yanked":false,"addr":"example.com/some/package@sha256:74eb48882e835d8767f62940d453eb96ed2737de3a16573881dcea7dea769df7"} 3 | {"ns":"example","name":"foo","version":"1.2.0","yanked":false,"addr":"example.com/some/package@sha256:2560f05307e8de9d830f144d09556e19dd1eb7d928aee900ed02208ae9727e7a"} 4 | -------------------------------------------------------------------------------- /testdata/registry/ja/va/example_java: -------------------------------------------------------------------------------- 1 | {"ns":"example","name":"java","version":"1.0.0","yanked":false,"addr":"example.com/some/package@sha256:8c27fe111c11b722081701dfed3bd55e039b9ce92865473cf4cdfa918071c566"} 2 | -------------------------------------------------------------------------------- /testdata/some-app/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore -------------------------------------------------------------------------------- /testdata/zip-file.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buildpacks/pack/d5a88c789d16cfff60e953007d811d425de65040/testdata/zip-file.zip -------------------------------------------------------------------------------- /testhelpers/assert_file.go: -------------------------------------------------------------------------------- 1 | package testhelpers 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func (a *AssertionManager) FileExists(filePath string) { 8 | a.testObject.Helper() 9 | _, err := os.Stat(filePath) 10 | if err != nil { 11 | if os.IsNotExist(err) { 12 | a.testObject.Fatalf("Expected file %s to exist.", filePath) 13 | } else { 14 | a.testObject.Fatal("Unexpected error:", err.Error()) 15 | } 16 | } 17 | } 18 | 19 | func (a *AssertionManager) FileIsNotEmpty(filePath string) { 20 | a.testObject.Helper() 21 | info, err := os.Stat(filePath) 22 | if err != nil { 23 | a.testObject.Fatal("Unexpected error:", err.Error()) 24 | } 25 | 26 | if info.IsDir() { 27 | a.testObject.Fatalf("File %s is a directory.", filePath) 28 | } 29 | 30 | if info.Size() == 0 { 31 | a.testObject.Fatalf("Expected file %s to not be empty.", filePath) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package tools 4 | 5 | import ( 6 | _ "github.com/golang/mock/mockgen" 7 | _ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint" 8 | _ "golang.org/x/tools/cmd/goimports" 9 | ) 10 | --------------------------------------------------------------------------------