Skip to main content

libcnb/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod build;
4pub mod detect;
5pub mod exec_d;
6pub mod generic;
7pub mod layer;
8pub mod layer_env;
9pub mod sbom;
10
11// Internals that need to be public for macros
12#[doc(hidden)]
13pub mod internals;
14
15mod buildpack;
16mod env;
17mod error;
18mod exit_code;
19mod platform;
20mod runtime;
21mod target;
22#[cfg(feature = "trace")]
23mod tracing;
24mod util;
25
26pub use buildpack::Buildpack;
27pub use env::*;
28pub use error::*;
29pub use libcnb_common::toml_file::*;
30pub use platform::*;
31pub use runtime::*;
32pub use target::*;
33
34#[cfg(all(test, not(feature = "trace")))]
35use serde_json as _;
36
37/// Provides types for CNB data formats. Is a re-export of the `libcnb-data` crate.
38#[doc(inline)]
39pub use libcnb_data as data;
40
41const LIBCNB_SUPPORTED_BUILDPACK_API: data::buildpack::BuildpackApi =
42    data::buildpack::BuildpackApi {
43        major: 0,
44        minor: 10,
45    };
46
47/// Generates a main function for the given buildpack.
48///
49/// It will create the main function and wires up the buildpack to the framework.
50///
51/// # Example:
52/// ```
53/// use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder};
54/// use libcnb::detect::{DetectContext, DetectResult, DetectResultBuilder};
55/// use libcnb::generic::{GenericError, GenericMetadata, GenericPlatform};
56/// use libcnb::{buildpack_main, Buildpack};
57///
58/// pub(crate) struct MyBuildpack;
59///
60/// impl Buildpack for MyBuildpack {
61///     type Platform = GenericPlatform;
62///     type Metadata = GenericMetadata;
63///     type Error = GenericError;
64///
65///     fn detect(
66///         &self,
67///         context: DetectContext<Self>,
68///     ) -> libcnb::Result<DetectResult, Self::Error> {
69///         DetectResultBuilder::pass().build()
70///     }
71///
72///     fn build(&self, context: BuildContext<Self>) -> libcnb::Result<BuildResult, Self::Error> {
73///         BuildResultBuilder::new().build()
74///     }
75/// }
76///
77/// buildpack_main!(MyBuildpack);
78/// ```
79#[macro_export]
80macro_rules! buildpack_main {
81    ($buildpack:expr) => {
82        fn main() {
83            ::libcnb::libcnb_runtime(&$buildpack);
84        }
85    };
86}
87
88/// Resolves the path to an additional buildpack binary by Cargo target name.
89///
90/// This can be used to copy additional binaries to layers or use them for exec.d.
91///
92/// To add an additional binary to a buildpack, add a new file with a main function to `bin/`.
93/// Cargo will [automatically configure it as a binary target](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery)
94/// with the name of file.
95///
96/// **Note**: This only works properly if the buildpack is packaged with `libcnb-cargo`/`libcnb-test`.
97///
98/// ```no_run,compile_fail
99/// use libcnb::additional_buildpack_binary_path;
100/// # let layer_dir = std::path::PathBuf::from(".");
101///
102/// std::fs::copy(
103///     // This would not compile in this doctest since there is no `runtime_tool` binary target.
104///     additional_buildpack_binary_path!("runtime_tool"),
105///     layer_dir.join("runtime_tool"),
106/// )
107/// .unwrap();
108/// ```
109#[macro_export]
110macro_rules! additional_buildpack_binary_path {
111    ($target_name:expr) => {
112        ::libcnb::internals::verify_bin_target_exists!(
113            $target_name,
114            {
115                ::std::env::var("CNB_BUILDPACK_DIR")
116                    .map(::std::path::PathBuf::from)
117                    .expect("Couldn't read CNB_BUILDPACK_DIR environment variable")
118                    .join(".libcnb-cargo")
119                    .join("additional-bin")
120                    .join($target_name)
121            },
122            {
123                compile_error!(concat!(
124                    $target_name,
125                    " is not a valid binary target in this buildpack crate!"
126                ))
127            }
128        )
129    };
130}