Skip to content

Commit

Permalink
Switch to the new "component" vs "composite" buildpack terminology (#682
Browse files Browse the repository at this point in the history
)

Upstream has now officially defined names for what we had previously
been calling meta-buildpacks vs single buildpacks:
https://github.com/buildpacks/spec/blob/main/buildpack.md#cnb-terminology

All types, docs and internal functions have been renamed to match.

Fixes #639.
GUS-W-14161652.
  • Loading branch information
edmorley authored Sep 21, 2023
1 parent c194868 commit 3503772
Show file tree
Hide file tree
Showing 16 changed files with 106 additions and 83 deletions.
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

0 comments on commit 3503772

Please sign in to comment.