Skip to content

Commit

Permalink
Upgrade to magic_migrate proc macro interface (#392)
Browse files Browse the repository at this point in the history
* Update magic_migrate version

* Use the preferred derive macro

* Use the preferred derive macro

* Use the preferred derive macro

* Use the preferred derive macro

* Fix docs

* Update cache_diff

* Update example to use derive macro
  • Loading branch information
schneems authored Feb 11, 2025
1 parent 99305fb commit 0abf912
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 188 deletions.
25 changes: 19 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
resolver = "2"
members = ["buildpacks/ruby", "commons"]

[workspace.dependencies]
cache_diff = { version = "1.1", features = ["bullet_stream"] }

[workspace.package]
edition = "2021"
rust-version = "1.82"
Expand Down
2 changes: 1 addition & 1 deletion buildpacks/ruby/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ureq = { version = "2", default-features = false, features = ["tls"] }
url = "2"
magic_migrate = "1.0"
toml = "0.8"
cache_diff = { version = "1.0.0", features = ["bullet_stream"] }
cache_diff.workspace = true

[dev-dependencies]
libcnb-test = "=0.26.1"
Expand Down
15 changes: 3 additions & 12 deletions buildpacks/ruby/src/layers/bundle_download_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use libcnb::data::layer_name;
use libcnb::layer::{EmptyLayerCause, LayerState};
use libcnb::layer_env::{LayerEnv, ModificationBehavior, Scope};
use libcnb::Env;
use magic_migrate::{try_migrate_deserializer_chain, TryMigrate};
use magic_migrate::TryMigrate;
use serde::{Deserialize, Serialize};
use std::io::Stdout;
use std::path::Path;
Expand Down Expand Up @@ -70,24 +70,15 @@ pub(crate) fn handle(
}

pub(crate) type Metadata = MetadataV1;
try_migrate_deserializer_chain!(
deserializer: toml::Deserializer::new,
error: MetadataError,
chain: [MetadataV1],
);

#[derive(Deserialize, Serialize, Debug, Clone, CacheDiff)]
#[derive(Deserialize, Serialize, Debug, Clone, CacheDiff, TryMigrate)]
#[try_migrate(from = None)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV1 {
#[cache_diff(rename = "Bundler version")]
pub(crate) version: ResolvedBundlerVersion,
}

#[derive(Debug, thiserror::Error)]
pub(crate) enum MetadataError {
// Update if migrating between a metadata version can error
}

fn download_bundler(
bullet: Print<SubBullet<Stdout>>,
env: &Env,
Expand Down
16 changes: 7 additions & 9 deletions buildpacks/ruby/src/layers/bundle_install_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use libcnb::{
layer_env::{LayerEnv, ModificationBehavior, Scope},
Env,
};
use magic_migrate::{try_migrate_deserializer_chain, TryMigrate};
use magic_migrate::TryMigrate;
use serde::{Deserialize, Serialize};
use std::io::Stdout;
use std::{path::Path, process::Command};
Expand Down Expand Up @@ -121,22 +121,19 @@ pub(crate) fn handle(
}

pub(crate) type Metadata = MetadataV3;
try_migrate_deserializer_chain!(
chain: [MetadataV1, MetadataV2, MetadataV3],
error: MetadataMigrateError,
deserializer: toml::Deserializer::new,
);

#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, TryMigrate)]
#[serde(deny_unknown_fields)]
#[try_migrate(from = None)]
pub(crate) struct MetadataV1 {
pub(crate) stack: String,
pub(crate) ruby_version: ResolvedRubyVersion,
pub(crate) force_bundle_install_key: String,
pub(crate) digest: MetadataDigest, // Must be last for serde to be happy https://github.com/toml-rs/toml-rs/issues/142
}

#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, TryMigrate)]
#[try_migrate(from = MetadataV1)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV2 {
pub(crate) distro_name: String,
Expand All @@ -147,7 +144,8 @@ pub(crate) struct MetadataV2 {
pub(crate) digest: MetadataDigest, // Must be last for serde to be happy https://github.com/toml-rs/toml-rs/issues/142
}

#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, CacheDiff)]
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, CacheDiff, TryMigrate)]
#[try_migrate(from = MetadataV2)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV3 {
#[cache_diff(rename = "OS Distribution")]
Expand Down
16 changes: 7 additions & 9 deletions buildpacks/ruby/src/layers/ruby_install_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use flate2::read::GzDecoder;
use libcnb::data::layer_name;
use libcnb::layer::{EmptyLayerCause, LayerState};
use libcnb::layer_env::LayerEnv;
use magic_migrate::{try_migrate_deserializer_chain, TryMigrate};
use magic_migrate::TryMigrate;
use serde::{Deserialize, Serialize};
use std::io::{self, Stdout};
use std::path::Path;
Expand Down Expand Up @@ -85,14 +85,16 @@ fn install_ruby(metadata: &Metadata, layer_path: &Path) -> Result<(), RubyBuildp
Ok(())
}

#[derive(Deserialize, Serialize, Debug, Clone)]
#[derive(Deserialize, Serialize, Debug, Clone, TryMigrate)]
#[try_migrate(from = None)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV1 {
pub(crate) stack: String,
pub(crate) version: ResolvedRubyVersion,
}

#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, TryMigrate)]
#[try_migrate(from = MetadataV1)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV2 {
pub(crate) distro_name: String,
Expand All @@ -101,7 +103,8 @@ pub(crate) struct MetadataV2 {
pub(crate) ruby_version: ResolvedRubyVersion,
}

#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, CacheDiff)]
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, CacheDiff, TryMigrate)]
#[try_migrate(from = MetadataV2)]
#[serde(deny_unknown_fields)]
pub(crate) struct MetadataV3 {
#[cache_diff(rename = "OS Distribution")]
Expand All @@ -123,11 +126,6 @@ impl MetadataV3 {
}

pub(crate) type Metadata = MetadataV3;
try_migrate_deserializer_chain!(
chain: [MetadataV1, MetadataV2, MetadataV3],
error: MetadataMigrateError,
deserializer: toml::Deserializer::new,
);

#[derive(thiserror::Error, Debug)]
pub(crate) enum MetadataMigrateError {
Expand Down
2 changes: 1 addition & 1 deletion commons/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ walkdir = "2"
filetime = "0.2"
magic_migrate = "1.0.1"
toml = "0.8"
cache_diff = "1.0"
cache_diff.workspace = true

[dev-dependencies]
filetime = "0.2"
Expand Down
34 changes: 11 additions & 23 deletions commons/src/layer/diff_migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ use bullet_stream as _;
/// When a `CacheDiff::diff` is empty, the layer is kept and the old data is returned. Otherwise,
/// the layer is deleted and the changes are returned.
///
/// **TUTORIAL:** In the [`diff_migrate`] module docs
/// **TUTORIAL:** In the [`crate::layer::diff_migrate`] module docs
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DiffMigrateLayer {
/// Whether the layer is intended for build.
Expand Down Expand Up @@ -138,7 +138,7 @@ impl DiffMigrateLayer {
/// When given a prior [`LayerRename::from`] that exists, but the [`LayerRename::to`]
/// does not, then the contents of the prior layer will be copied before being deleted.
///
/// After that this function callse [`cached_layer`] on the new layer.
/// After that this function calls [`crate::layer::diff_migrate::DiffMigrateLayer::cached_layer`] on the new layer.
///
/// # Panics
///
Expand Down Expand Up @@ -320,10 +320,11 @@ mod tests {
use libcnb::data::layer_name;
use libcnb::generic::{GenericMetadata, GenericPlatform};
use libcnb::layer::{EmptyLayerCause, InvalidMetadataAction, LayerState, RestoredLayerAction};
use magic_migrate::{migrate_toml_chain, try_migrate_deserializer_chain, Migrate, TryMigrate};
use magic_migrate::TryMigrate;
use std::convert::Infallible;
/// Struct for asserting the behavior of `CacheBuddy`
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, TryMigrate)]
#[try_migrate(from = None)]
#[serde(deny_unknown_fields)]
struct TestMetadata {
value: String,
Expand All @@ -337,7 +338,6 @@ mod tests {
}
}
}
migrate_toml_chain! {TestMetadata}

struct FakeBuildpack;
impl libcnb::Buildpack for FakeBuildpack {
Expand Down Expand Up @@ -555,13 +555,15 @@ mod tests {
}

/// Struct for asserting the behavior of `invalid_metadata_action`
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, TryMigrate)]
#[try_migrate(from = None)]
#[serde(deny_unknown_fields)]
struct PersonV1 {
name: String,
}
/// Struct for asserting the behavior of `invalid_metadata_action`
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, TryMigrate)]
#[try_migrate(from = PersonV1)]
#[serde(deny_unknown_fields)]
struct PersonV2 {
name: String,
Expand All @@ -583,25 +585,11 @@ mod tests {
}
}
}
#[derive(Debug, Eq, PartialEq)]
#[derive(Debug, Eq, PartialEq, thiserror::Error)]
#[error("Not Richard")]
struct NotRichard {
name: String,
}
impl From<NotRichard> for PersonMigrationError {
fn from(value: NotRichard) -> Self {
PersonMigrationError::NotRichard(value)
}
}
#[derive(Debug, Eq, PartialEq, thiserror::Error)]
enum PersonMigrationError {
#[error("Not Richard")]
NotRichard(NotRichard),
}
try_migrate_deserializer_chain!(
deserializer: toml::Deserializer::new,
error: PersonMigrationError,
chain: [PersonV1, PersonV2],
);

#[test]
fn test_invalid_metadata_action() {
Expand Down
Loading

0 comments on commit 0abf912

Please sign in to comment.