Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to the new "component" vs "composite" buildpack terminology #682

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `libcnb-data`:
- `ExecDProgramOutputKey`, `ProcessType`, `LayerName`, `BuildpackId` and `StackId` now implement `Ord` and `PartialOrd`. ([#658](https://github.com/heroku/libcnb.rs/pull/658))
- Add `generic::GenericMetadata` as a generic metadata type. Also makes it the default for `BuildpackDescriptor`, `SingleBuildpackDescriptor`, `MetaBuildpackDescriptor` and `LayerContentMetadata`. ([#664](https://github.com/heroku/libcnb.rs/pull/664))
- Added `generic::GenericMetadata` as a generic metadata type. Also makes it the default for `BuildpackDescriptor`, `SingleBuildpackDescriptor`, `CompositeBuildpackDescriptor` and `LayerContentMetadata`. ([#664](https://github.com/heroku/libcnb.rs/pull/664))
- `libcnb-test`:
- Added the `BuildpackReference::WorkspaceBuildpack` enum variant. This allows for the testing of any libcnb.rs or composite buildpack in the Cargo workspace, instead of only the buildpack of the current crate. **Note: The testing of composite buildpacks requires `pack` CLI version `>=0.30`.** ([#666](https://github.com/heroku/libcnb.rs/pull/666))

### Changed

- Renamed `libcnb-data`'s `Buildpackage` to `PackageDescriptor`. This required changes in many other names across multiple libcnb.rs crates for consistency. See the PR diff for details, but renames should be straightforward and unsurprising. ([#656](https://github.com/heroku/libcnb.rs/pull/656))
- `libcnb-data`:
- Renamed multiple types to match the new composite vs component buildpack [upstream terminology](https://github.com/buildpacks/spec/blob/main/buildpack.md#cnb-terminology). Renamed `SingleBuildpackDescriptor` to `ComponentBuildpackDescriptor`, `MetaBuildpackDescriptor` to `CompositeBuildpackDescriptor` and `BuildpackDescriptor::{Single,Meta}` to `BuildpackDescriptor::{Component,Composite}`. ([#682](https://github.com/heroku/libcnb.rs/pull/682))
- `libcnb-cargo`:
- No longer outputs paths for non-libcnb.rs and non-meta buildpacks. ([#657](https://github.com/heroku/libcnb.rs/pull/657))
- Build output for humans changed slightly, output intended for machines/scripting didn't change. ([#657](https://github.com/heroku/libcnb.rs/pull/657))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
api = "0.8"

[buildpack]
id = "multiple-buildpacks/meta-one"
name = "Meta-buildpack Test"
id = "multiple-buildpacks/composite-one"
name = "Composite Buildpack Test"
version = "0.0.0"
homepage = "https://example.com"
description = "Official test example"
Expand Down
35 changes: 21 additions & 14 deletions libcnb-cargo/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,17 @@ fn package_buildpack_in_single_buildpack_project() {

#[test]
#[ignore = "integration test"]
fn package_single_meta_buildpack_in_monorepo_buildpack_project() {
fn package_single_composite_buildpack_in_monorepo_buildpack_project() {
let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap();

let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST)
.args(["libcnb", "package", "--release"])
.current_dir(fixture_dir.path().join("meta-buildpacks").join("meta-one"))
.current_dir(
fixture_dir
.path()
.join("composite-buildpacks")
.join("composite-one"),
)
.output()
.unwrap();

Expand All @@ -61,14 +66,14 @@ fn package_single_meta_buildpack_in_monorepo_buildpack_project() {
String::from_utf8_lossy(&output.stdout),
format!(
"{}\n",
packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one"))
packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/composite-one"))
.to_string_lossy()
)
);

validate_packaged_meta_buildpack(
&packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")),
&buildpack_id!("multiple-buildpacks/meta-one"),
validate_packaged_composite_buildpack(
&packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/composite-one")),
&buildpack_id!("multiple-buildpacks/composite-one"),
&[
PackageDescriptorDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!(
"multiple-buildpacks/one"
Expand Down Expand Up @@ -148,7 +153,9 @@ fn package_all_buildpacks_in_monorepo_buildpack_project() {
format!(
"{}\n",
[
packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")),
packaged_buildpack_dir_resolver(&buildpack_id!(
"multiple-buildpacks/composite-one"
)),
packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/one")),
packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/two")),
]
Expand All @@ -157,9 +164,9 @@ fn package_all_buildpacks_in_monorepo_buildpack_project() {
)
);

validate_packaged_meta_buildpack(
&packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")),
&buildpack_id!("multiple-buildpacks/meta-one"),
validate_packaged_composite_buildpack(
&packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/composite-one")),
&buildpack_id!("multiple-buildpacks/composite-one"),
&[
PackageDescriptorDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!(
"multiple-buildpacks/one"
Expand All @@ -185,7 +192,7 @@ fn package_all_buildpacks_in_monorepo_buildpack_project() {

#[test]
#[ignore = "integration test"]
fn package_non_libcnb_buildpack_in_meta_buildpack_project() {
fn package_non_libcnb_buildpack_in_composite_buildpack_project() {
let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap();

let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST)
Expand Down Expand Up @@ -227,7 +234,7 @@ fn package_command_respects_ignore_files() {
// The `ignore` crate supports `.ignore` files. So this first `cargo libcnb package` execution
// just sanity checks that our ignore rules will be respected.
let ignore_file = fixture_dir.path().join(".ignore");
fs::write(&ignore_file, "meta-buildpacks\nbuildpacks\n").unwrap();
fs::write(&ignore_file, "composite-buildpacks\nbuildpacks\n").unwrap();

let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST)
.args(["libcnb", "package", "--release"])
Expand All @@ -251,7 +258,7 @@ fn package_command_respects_ignore_files() {
// in a git repository will be respected.
fs::create_dir(fixture_dir.path().join(".git")).unwrap();
let ignore_file = fixture_dir.path().join(".gitignore");
fs::write(ignore_file, "meta-buildpacks\nbuildpacks\n").unwrap();
fs::write(ignore_file, "composite-buildpacks\nbuildpacks\n").unwrap();

let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST)
.args(["libcnb", "package", "--release"])
Expand Down Expand Up @@ -281,7 +288,7 @@ fn validate_packaged_buildpack(packaged_buildpack_dir: &Path, buildpack_id: &Bui
);
}

fn validate_packaged_meta_buildpack(
fn validate_packaged_composite_buildpack(
packaged_buildpack_dir: &Path,
buildpack_id: &BuildpackId,
expected_package_descriptor_dependencies: &[PackageDescriptorDependency],
Expand Down
79 changes: 45 additions & 34 deletions libcnb-data/src/buildpack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ pub use version::*;
/// For parsing of [buildpack.toml](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpacktoml-toml)
/// files when support for multiple types of buildpack is required.
///
/// When a specific buildpack type is expected, use [`SingleBuildpackDescriptor`] or [`MetaBuildpackDescriptor`] directly instead,
/// since it allows for more detailed error messages if parsing fails.
/// When a specific buildpack type is expected, use [`ComponentBuildpackDescriptor`] or
/// [`CompositeBuildpackDescriptor`] directly instead, since they allow for more detailed
/// error messages if parsing fails.
///
/// # Example:
/// ```
Expand Down Expand Up @@ -49,40 +50,41 @@ pub use version::*;
/// toml::from_str::<BuildpackDescriptor>(toml_str)
/// .expect("buildpack.toml did not match a known type!");
/// match buildpack_descriptor {
/// BuildpackDescriptor::Single(buildpack) => {
/// println!("Found buildpack: {}", buildpack.buildpack.id);
/// BuildpackDescriptor::Component(buildpack) => {
/// println!("Found component buildpack: {}", buildpack.buildpack.id);
/// }
/// BuildpackDescriptor::Meta(buildpack) => {
/// println!("Found meta-buildpack: {}", buildpack.buildpack.id);
/// BuildpackDescriptor::Composite(buildpack) => {
/// println!("Found composite buildpack: {}", buildpack.buildpack.id);
/// }
/// };
/// ```
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum BuildpackDescriptor<BM = GenericMetadata> {
Single(SingleBuildpackDescriptor<BM>),
Meta(MetaBuildpackDescriptor<BM>),
Component(ComponentBuildpackDescriptor<BM>),
Composite(CompositeBuildpackDescriptor<BM>),
}

impl<BM> BuildpackDescriptor<BM> {
pub fn buildpack(&self) -> &Buildpack {
match self {
BuildpackDescriptor::Single(descriptor) => &descriptor.buildpack,
BuildpackDescriptor::Meta(descriptor) => &descriptor.buildpack,
BuildpackDescriptor::Component(descriptor) => &descriptor.buildpack,
BuildpackDescriptor::Composite(descriptor) => &descriptor.buildpack,
}
}
}

/// Data structure for the Buildpack descriptor (buildpack.toml) of a single buildpack.
/// Data structure for the Buildpack descriptor (buildpack.toml) of a component buildpack.
///
/// Representation of [buildpack.toml](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpacktoml-toml)
/// when the buildpack is a single buildpack that implements the Buildpack Interface (ie: not a meta-buildpack).
/// when the buildpack is a component buildpack - one that implements the Buildpack Interface
/// (ie: contains `/bin/detect` and `/bin/build` executables).
///
/// If support for multiple buildpack types is required, use [`BuildpackDescriptor`] instead.
///
/// # Example:
/// ```
/// use libcnb_data::buildpack::{SingleBuildpackDescriptor, Stack};
/// use libcnb_data::buildpack::{ComponentBuildpackDescriptor, Stack};
/// use libcnb_data::buildpack_id;
///
/// let toml_str = r#"
Expand All @@ -105,29 +107,31 @@ impl<BM> BuildpackDescriptor<BM> {
/// "#;
///
/// let buildpack_descriptor =
/// toml::from_str::<SingleBuildpackDescriptor>(toml_str).unwrap();
/// toml::from_str::<ComponentBuildpackDescriptor>(toml_str).unwrap();
/// assert_eq!(buildpack_descriptor.buildpack.id, buildpack_id!("foo/bar"));
/// assert_eq!(buildpack_descriptor.stacks, [Stack::Any]);
/// ```
#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct SingleBuildpackDescriptor<BM = GenericMetadata> {
pub struct ComponentBuildpackDescriptor<BM = GenericMetadata> {
pub api: BuildpackApi,
pub buildpack: Buildpack,
pub stacks: Vec<Stack>,
pub metadata: BM,
}

/// Data structure for the Buildpack descriptor (buildpack.toml) of a meta-buildpack.
/// Data structure for the Buildpack descriptor (buildpack.toml) of a composite buildpack.
///
/// Representation of [buildpack.toml](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpacktoml-toml)
/// when the buildpack is a meta-buildpack.
/// when the buildpack is a composite buildpack - one that does not implement the Buildpack Interface
/// itself (ie: does not contain `/bin/detect` and `/bin/build` executables) but instead references
/// other buildpacks via an order definition.
///
/// If support for multiple buildpack types is required, use [`BuildpackDescriptor`] instead.
///
/// # Example:
/// ```
/// use libcnb_data::buildpack::MetaBuildpackDescriptor;
/// use libcnb_data::buildpack::CompositeBuildpackDescriptor;
/// use libcnb_data::buildpack_id;
///
/// let toml_str = r#"
Expand All @@ -153,12 +157,12 @@ pub struct SingleBuildpackDescriptor<BM = GenericMetadata> {
/// "#;
///
/// let buildpack_descriptor =
/// toml::from_str::<MetaBuildpackDescriptor>(toml_str).unwrap();
/// toml::from_str::<CompositeBuildpackDescriptor>(toml_str).unwrap();
/// assert_eq!(buildpack_descriptor.buildpack.id, buildpack_id!("foo/bar"));
/// ```
#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct MetaBuildpackDescriptor<BM = GenericMetadata> {
pub struct CompositeBuildpackDescriptor<BM = GenericMetadata> {
pub api: BuildpackApi,
pub buildpack: Buildpack,
pub order: Vec<Order>,
Expand Down Expand Up @@ -216,7 +220,7 @@ mod tests {

#[test]
#[allow(clippy::too_many_lines)]
fn deserialize_singlebuildpack() {
fn deserialize_component_buildpack() {
let toml_str = r#"
api = "0.9"

Expand Down Expand Up @@ -261,7 +265,8 @@ id = "*"
checksum = "abc123"
"#;

let buildpack_descriptor = toml::from_str::<SingleBuildpackDescriptor>(toml_str).unwrap();
let buildpack_descriptor =
toml::from_str::<ComponentBuildpackDescriptor>(toml_str).unwrap();

assert_eq!(
buildpack_descriptor.api,
Expand Down Expand Up @@ -343,7 +348,7 @@ checksum = "abc123"
}

#[test]
fn deserialize_metabuildpack() {
fn deserialize_composite_buildpack() {
let toml_str = r#"
api = "0.9"

Expand Down Expand Up @@ -381,7 +386,8 @@ optional = true
checksum = "abc123"
"#;

let buildpack_descriptor = toml::from_str::<MetaBuildpackDescriptor>(toml_str).unwrap();
let buildpack_descriptor =
toml::from_str::<CompositeBuildpackDescriptor>(toml_str).unwrap();

assert_eq!(
buildpack_descriptor.api,
Expand Down Expand Up @@ -453,7 +459,7 @@ checksum = "abc123"
}

#[test]
fn deserialize_minimal_singlebuildpack() {
fn deserialize_minimal_component_buildpack() {
let toml_str = r#"
api = "0.9"

Expand All @@ -465,7 +471,8 @@ version = "0.0.1"
id = "*"
"#;

let buildpack_descriptor = toml::from_str::<SingleBuildpackDescriptor>(toml_str).unwrap();
let buildpack_descriptor =
toml::from_str::<ComponentBuildpackDescriptor>(toml_str).unwrap();

assert_eq!(
buildpack_descriptor.api,
Expand Down Expand Up @@ -494,7 +501,7 @@ id = "*"
}

#[test]
fn deserialize_minimal_metabuildpack() {
fn deserialize_minimal_composite_buildpack() {
let toml_str = r#"
api = "0.9"

Expand All @@ -509,7 +516,8 @@ id = "foo/bar"
version = "0.0.1"
"#;

let buildpack_descriptor = toml::from_str::<MetaBuildpackDescriptor>(toml_str).unwrap();
let buildpack_descriptor =
toml::from_str::<CompositeBuildpackDescriptor>(toml_str).unwrap();

assert_eq!(
buildpack_descriptor.api,
Expand Down Expand Up @@ -546,7 +554,7 @@ version = "0.0.1"
}

#[test]
fn deserialize_buildpackdescriptor_single() {
fn deserialize_buildpackdescriptor_component() {
let toml_str = r#"
api = "0.9"

Expand All @@ -561,12 +569,12 @@ id = "*"
let buildpack_descriptor = toml::from_str::<BuildpackDescriptor>(toml_str).unwrap();
assert!(matches!(
buildpack_descriptor,
BuildpackDescriptor::Single(_)
BuildpackDescriptor::Component(_)
));
}

#[test]
fn deserialize_buildpackdescriptor_meta() {
fn deserialize_buildpackdescriptor_composite() {
let toml_str = r#"
api = "0.9"

Expand All @@ -582,7 +590,10 @@ version = "0.0.1"
"#;

let buildpack_descriptor = toml::from_str::<BuildpackDescriptor>(toml_str).unwrap();
assert!(matches!(buildpack_descriptor, BuildpackDescriptor::Meta(_)));
assert!(matches!(
buildpack_descriptor,
BuildpackDescriptor::Composite(_)
));
}

#[test]
Expand Down Expand Up @@ -610,10 +621,10 @@ version = "0.0.1"
"data did not match any variant of untagged enum BuildpackDescriptor\n"
);

let err = toml::from_str::<SingleBuildpackDescriptor>(toml_str).unwrap_err();
let err = toml::from_str::<ComponentBuildpackDescriptor>(toml_str).unwrap_err();
assert!(err.to_string().contains("unknown field `order`"));

let err = toml::from_str::<MetaBuildpackDescriptor>(toml_str).unwrap_err();
let err = toml::from_str::<CompositeBuildpackDescriptor>(toml_str).unwrap_err();
assert!(err.to_string().contains("unknown field `stacks`"));
}
}
7 changes: 5 additions & 2 deletions libcnb-data/src/package_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ pub struct PackageDescriptor {
/// The buildpack to package.
pub buildpack: PackageDescriptorBuildpackReference,

/// A set of dependent buildpack locations, for packaging a meta-buildpack. Each dependent buildpack location must correspond to an order group within the meta-buildpack being packaged.
/// A set of dependent buildpack locations, for packaging a composite buildpack.
///
/// Each dependent buildpack location must correspond to an order group within the composite buildpack being packaged.
#[serde(default)]
pub dependencies: Vec<PackageDescriptorDependency>,

Expand All @@ -62,6 +64,7 @@ impl Default for PackageDescriptor {
#[serde(deny_unknown_fields)]
pub struct PackageDescriptorBuildpackReference {
/// A URL or path to an archive, or a path to a directory.
///
/// If the `uri` field is a relative path it will be relative to the `package.toml` file.
#[serde(deserialize_with = "deserialize_uri_reference")]
#[serde(serialize_with = "serialize_uri_reference")]
Expand All @@ -83,7 +86,7 @@ impl TryFrom<&str> for PackageDescriptorBuildpackReference {
}
}

/// A dependent buildpack location for packaging a meta-buildpack.
/// A dependent buildpack location for packaging a composite buildpack.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq, Clone)]
#[serde(deny_unknown_fields)]
pub struct PackageDescriptorDependency {
Expand Down
Loading