diff --git a/CHANGELOG.md b/CHANGELOG.md index cb6b686c..d4272df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ separate changelogs for each crate were used. If you need to refer to these old ### Added -- `libherokubuildpack`: Add `env::DefaultEnvLayer` and `env::ConfigureEnvLayer` structs for setting environment variables ([#598](https://github.com/heroku/libcnb.rs/pull/598)) +- `libherokubuildpack`: Add `env_layer::set_default` and `env_layer::set_envs` helper functions for setting environment variables ([#598](https://github.com/heroku/libcnb.rs/pull/598)) - `libcnb-package`: Add cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) ### Changed diff --git a/libherokubuildpack/Cargo.toml b/libherokubuildpack/Cargo.toml index 7a6e110e..5a0abab1 100644 --- a/libherokubuildpack/Cargo.toml +++ b/libherokubuildpack/Cargo.toml @@ -15,10 +15,10 @@ include = ["src/**/*", "LICENSE", "README.md"] all-features = true [features] -default = ["command", "download", "digest", "error", "env", "log", "tar", "toml", "fs", "write"] +default = ["command", "download", "digest", "error", "env_layer", "log", "tar", "toml", "fs", "write"] download = ["dep:ureq", "dep:thiserror"] digest = ["dep:sha2"] -env = ["dep:libcnb"] +env_layer = ["dep:libcnb"] error = ["log", "dep:libcnb"] log = ["dep:termcolor"] tar = ["dep:tar", "dep:flate2"] diff --git a/libherokubuildpack/src/env.rs b/libherokubuildpack/src/env_layer.rs similarity index 54% rename from libherokubuildpack/src/env.rs rename to libherokubuildpack/src/env_layer.rs index 9831516a..8b206a9f 100644 --- a/libherokubuildpack/src/env.rs +++ b/libherokubuildpack/src/env_layer.rs @@ -1,8 +1,10 @@ use libcnb::build::BuildContext; +use libcnb::data::layer::LayerName; use libcnb::data::layer_content_metadata::LayerTypes; use libcnb::generic::GenericMetadata; -use libcnb::layer::{Layer, LayerResult, LayerResultBuilder}; +use libcnb::layer::{Layer, LayerData, LayerResult, LayerResultBuilder}; use libcnb::layer_env::{LayerEnv, ModificationBehavior, Scope}; +use libcnb::Buildpack; use std::ffi::OsString; use std::marker::PhantomData; use std::path::Path; @@ -10,8 +12,8 @@ use std::path::Path; /// Set default environment variables /// /// If all you need to do is set default environment values, you can use -/// the `DefaultEnvLayer::new` function to set those values without having -/// to create a struct from scratch. +/// the `env_layer::set_default` function to set those values without having +/// to create a struct from scratch. Example: /// /// ```no_run ///# use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder}; @@ -27,7 +29,7 @@ use std::path::Path; /// use libcnb::Env; /// use libcnb::data::layer_name; /// use libcnb::layer_env::Scope; -/// use libherokubuildpack::env::DefaultEnvLayer; +/// use libherokubuildpack::env_layer; /// ///# impl Buildpack for HelloWorldBuildpack { ///# type Platform = GenericPlatform; @@ -39,32 +41,45 @@ use std::path::Path; ///# } /// ///# fn build(&self, context: BuildContext) -> libcnb::Result { +/// // Don't forget to apply context.platform.env() in addition to current envs; /// let env = Env::from_current(); -/// // Don't forget to apply context.platform.env() too; /// -/// let layer = context // -/// .handle_layer( -/// layer_name!("default_env"), -/// DefaultEnvLayer::new( -/// [ -/// ("JRUBY_OPTS", "-Xcompile.invokedynamic=false"), -/// ("RACK_ENV", "production"), -/// ("RAILS_ENV", "production"), -/// ("RAILS_SERVE_STATIC_FILES", "enabled"), -/// ("RAILS_LOG_TO_STDOUT", "enabled"), -/// ("MALLOC_ARENA_MAX", "2"), -/// ("DISABLE_SPRING", "1"), -/// ] -/// .into_iter(), -/// ), -/// )?; +/// let layer = env_layer::set_default(&context, layer_name!("default_env"), +/// [ +/// ("JRUBY_OPTS", "-Xcompile.invokedynamic=false"), +/// ("RACK_ENV", "production"), +/// ("RAILS_ENV", "production"), +/// ("RAILS_SERVE_STATIC_FILES", "enabled"), +/// ("RAILS_LOG_TO_STDOUT", "enabled"), +/// ("MALLOC_ARENA_MAX", "2"), +/// ("DISABLE_SPRING", "1"), +/// ] +/// .into_iter(), +/// )?; /// let env = layer.env.apply(Scope::Build, &env); /// ///# todo!() ///# } ///# } -/// /// ``` +pub fn set_default( + context: &BuildContext, + layer_name: LayerName, + envs: E, +) -> libcnb::Result, ::Error> +where + B: Buildpack, + E: IntoIterator + Clone, + K: Into, + V: Into, +{ + context.handle_layer(layer_name, DefaultEnvLayer::new(envs)) +} + +/// Set default environment variables in a layer +/// +/// This struct is used by the helper function `set_default`. You can also use it directly with +/// with [`BuildContext::handle_layer`] to set default environment variables. pub struct DefaultEnvLayer; impl DefaultEnvLayer { @@ -91,11 +106,9 @@ impl DefaultEnvLayer { /// Set environment variables /// -/// If you want to set many default environment variables you can use -/// `DefaultEnvLayer`. If you need to set different types of environment -/// variables you can use this struct `ConfigureEnvLayer` -/// -/// Example: +/// If you want to set many default environment variables you can use the +/// `env_layer::set_default` function. If you need to set different types of environment +/// variables you can use the `env_layer::set_envs` function. Example: /// /// ```no_run ///# use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder}; @@ -111,7 +124,7 @@ impl DefaultEnvLayer { /// use libcnb::Env; /// use libcnb::data::layer_name; /// use libcnb::layer_env::{LayerEnv, ModificationBehavior, Scope}; -/// use libherokubuildpack::env::ConfigureEnvLayer; +/// use libherokubuildpack::env_layer; /// ///# impl Buildpack for HelloWorldBuildpack { ///# type Platform = GenericPlatform; @@ -123,47 +136,61 @@ impl DefaultEnvLayer { ///# } /// ///# fn build(&self, context: BuildContext) -> libcnb::Result { -/// let env = Env::from_current(); /// // Don't forget to apply context.platform.env() too; +/// let env = Env::from_current(); /// -/// let layer = context // -/// .handle_layer( +/// let env = { +/// let layer = env_layer::set_envs( +/// &context, /// layer_name!("configure_env"), -/// ConfigureEnvLayer::new( -/// LayerEnv::new() -/// .chainable_insert( -/// Scope::All, -/// ModificationBehavior::Override, -/// "BUNDLE_GEMFILE", // Tells bundler where to find the `Gemfile` -/// context.app_dir.join("Gemfile"), -/// ) -/// .chainable_insert( -/// Scope::All, -/// ModificationBehavior::Override, -/// "BUNDLE_CLEAN", // After successful `bundle install` bundler will automatically run `bundle clean` -/// "1", -/// ) -/// .chainable_insert( -/// Scope::All, -/// ModificationBehavior::Override, -/// "BUNDLE_DEPLOYMENT", // Requires the `Gemfile.lock` to be in sync with the current `Gemfile`. -/// "1", -/// ) -/// .chainable_insert( -/// Scope::All, -/// ModificationBehavior::Default, -/// "MY_ENV_VAR", -/// "Whatever I want" -/// ) -/// ), +/// LayerEnv::new() +/// .chainable_insert( +/// Scope::All, +/// ModificationBehavior::Override, +/// "BUNDLE_GEMFILE", // Tells bundler where to find the `Gemfile` +/// context.app_dir.join("Gemfile"), +/// ) +/// .chainable_insert( +/// Scope::All, +/// ModificationBehavior::Override, +/// "BUNDLE_CLEAN", // After successful `bundle install` bundler will automatically run `bundle clean` +/// "1", +/// ) +/// .chainable_insert( +/// Scope::All, +/// ModificationBehavior::Override, +/// "BUNDLE_DEPLOYMENT", // Requires the `Gemfile.lock` to be in sync with the current `Gemfile`. +/// "1", +/// ) +/// .chainable_insert( +/// Scope::All, +/// ModificationBehavior::Default, +/// "MY_ENV_VAR", +/// "Whatever I want" +/// ) /// )?; -/// let env = layer.env.apply(Scope::Build, &env); +/// layer.env.apply(Scope::Build, &env) +/// }; /// ///# todo!() ///# } ///# } -/// /// ``` +pub fn set_envs( + context: &BuildContext, + layer_name: LayerName, + envs: LayerEnv, +) -> libcnb::Result, ::Error> +where + B: Buildpack, +{ + context.handle_layer(layer_name, ConfigureEnvLayer::new(envs)) +} + +/// Set custom environment variables in a layer +/// +/// This struct is used by the helper function `set_envs`. You can also use it directly with +/// use directly with [`BuildContext::handle_layer`] to set specific environment variables. pub struct ConfigureEnvLayer { pub(crate) data: LayerEnv, pub(crate) _buildpack: std::marker::PhantomData, diff --git a/libherokubuildpack/src/lib.rs b/libherokubuildpack/src/lib.rs index 784810f5..10e0d79e 100644 --- a/libherokubuildpack/src/lib.rs +++ b/libherokubuildpack/src/lib.rs @@ -13,8 +13,8 @@ pub mod command; pub mod digest; #[cfg(feature = "download")] pub mod download; -#[cfg(feature = "env")] -pub mod env; +#[cfg(feature = "env_layer")] +pub mod env_layer; #[cfg(feature = "error")] pub mod error; #[cfg(feature = "fs")]