dofigen_lib/lib.rs
1//! # dofigen_lib
2//!
3//! `dofigen_lib` help creating Dockerfile with a simplified structure and made to cache the build with Buildkit.
4//! You also can parse the structure from YAML or JSON.
5//!
6//! ```
7//! use dofigen_lib::*;
8//! use pretty_assertions_sorted::assert_eq_sorted;
9//!
10//! let mut context = DofigenContext::new();
11//!
12//! let dofigen = context.parse_from_string(r#"
13//! fromImage:
14//! path: ubuntu
15//! "#).unwrap();
16//!
17//! let dockerfile = generate_dockerfile(&dofigen).unwrap();
18//! ```
19
20mod context;
21mod deserialize;
22mod dockerfile_struct;
23mod dofigen_struct;
24mod errors;
25mod extend;
26#[cfg(feature = "permissive")]
27mod from_str;
28mod generator;
29#[cfg(feature = "json_schema")]
30mod json_schema;
31mod linter;
32pub mod lock;
33pub use {
34 context::*, deserialize::*, dofigen_struct::*, errors::*, extend::*,
35 generator::GenerationContext, linter::*,
36};
37
38#[cfg(all(feature = "strict", feature = "permissive"))]
39compile_error!("You can't enable both 'strict' and 'permissive' features at the same time.");
40
41pub(crate) const DOCKERFILE_VERSION: &str = "1.11";
42
43const FILE_HEADER_COMMENTS: [&str; 2] = [
44 concat!(
45 "This file is generated by Dofigen v",
46 env!("CARGO_PKG_VERSION")
47 ),
48 concat!("See ", env!("CARGO_PKG_REPOSITORY")),
49];
50
51/// Generates the Dockerfile content from a Dofigen struct.
52///
53/// # Examples
54///
55/// ```
56/// use dofigen_lib::*;
57/// use pretty_assertions_sorted::assert_eq_sorted;
58///
59/// let dofigen = Dofigen {
60/// stage: Stage {
61/// from: ImageName {
62/// path: String::from("ubuntu"),
63/// ..Default::default()
64/// }.into(),
65/// ..Default::default()
66/// },
67/// ..Default::default()
68/// };
69/// let dockerfile: String = generate_dockerfile(&dofigen).unwrap();
70/// assert_eq_sorted!(
71/// dockerfile,
72/// "# syntax=docker/dockerfile:1.11\n# This file is generated by Dofigen v0.0.0\n# See https://github.com/lenra-io/dofigen\n\n# runtime\nFROM ubuntu AS runtime\nUSER 1000:1000\n"
73/// );
74/// ```
75#[deprecated(
76 since = "2.2.0",
77 note = "Please use `GenerationContext::generate_dockerfile` from `dofigen_lib` instead"
78)]
79pub fn generate_dockerfile(dofigen: &Dofigen) -> Result<String> {
80 GenerationContext::from(dofigen.clone()).generate_dockerfile()
81}
82
83/// Generates the .dockerignore file content from an Dofigen struct.
84///
85/// # Examples
86///
87/// ## Define the build context
88///
89/// ```
90/// use dofigen_lib::*;
91/// use pretty_assertions_sorted::assert_eq_sorted;
92///
93/// let dofigen = Dofigen {
94/// context: vec![String::from("/src")].into(),
95/// ..Default::default()
96/// };
97/// let dockerfile: String = generate_dockerignore(&dofigen);
98/// assert_eq_sorted!(
99/// dockerfile,
100/// "# This file is generated by Dofigen v0.0.0\n# See https://github.com/lenra-io/dofigen\n\n**\n!/src\n"
101/// );
102/// ```
103///
104/// ## Ignore a path
105///
106/// ```
107/// use dofigen_lib::*;
108/// use pretty_assertions_sorted::assert_eq_sorted;
109///
110/// let dofigen = Dofigen {
111/// ignore: vec![String::from("target")].into(),
112/// ..Default::default()
113/// };
114/// let dockerfile: String = generate_dockerignore(&dofigen);
115/// assert_eq_sorted!(
116/// dockerfile,
117/// "# This file is generated by Dofigen v0.0.0\n# See https://github.com/lenra-io/dofigen\n\ntarget\n"
118/// );
119/// ```
120///
121/// ## Define context ignoring a specific files
122///
123/// ```
124/// use dofigen_lib::*;
125/// use pretty_assertions_sorted::assert_eq_sorted;
126///
127/// let dofigen = Dofigen {
128/// context: vec![String::from("/src")].into(),
129/// ignore: vec![String::from("/src/*.test.rs")].into(),
130/// ..Default::default()
131/// };
132/// let dockerfile: String = generate_dockerignore(&dofigen);
133/// assert_eq_sorted!(
134/// dockerfile,
135/// "# This file is generated by Dofigen v0.0.0\n# See https://github.com/lenra-io/dofigen\n\n**\n!/src\n/src/*.test.rs\n"
136/// );
137/// ```
138#[deprecated(
139 since = "2.2.0",
140 note = "Please use `GenerationContext::generate_dockerignore` from `dofigen_lib` instead"
141)]
142pub fn generate_dockerignore(dofigen: &Dofigen) -> String {
143 GenerationContext::from(dofigen.clone())
144 .generate_dockerignore()
145 .unwrap()
146}
147
148/// Generates the effective Dofigen content from a Dofigen struct.
149///
150/// # Examples
151///
152/// ```
153/// use dofigen_lib::*;
154/// use pretty_assertions_sorted::assert_eq_sorted;
155///
156/// let dofigen = Dofigen {
157/// stage: Stage {
158/// from: ImageName {
159/// path: String::from("ubuntu"),
160/// ..Default::default()
161/// }.into(),
162/// ..Default::default()
163/// },
164/// ..Default::default()
165/// };
166/// let dofigen: String = generate_effective_content(&dofigen).unwrap();
167/// assert_eq_sorted!(
168/// dofigen,
169/// "fromImage:\n path: ubuntu\n"
170/// );
171/// ```
172pub fn generate_effective_content(dofigen: &Dofigen) -> Result<String> {
173 Ok(serde_yaml::to_string(&dofigen)?)
174}
175
176/// Generates the JSON schema for the Dofigen struct.
177/// This is useful to validate the structure and IDE autocompletion.
178#[cfg(feature = "json_schema")]
179pub fn generate_json_schema() -> String {
180 use schemars::{
181 generate::SchemaSettings,
182 transform::{AddNullable, RestrictFormats, Transform},
183 };
184
185 let settings = SchemaSettings::draft07();
186 let generator = settings.into_generator();
187 let mut schema = generator.into_root_schema_for::<Extend<DofigenPatch>>();
188 let mut nullable = AddNullable::default();
189 nullable.add_const_null = false;
190 nullable.remove_null_type = false;
191 nullable.transform(&mut schema);
192 let mut restrcit_formats = RestrictFormats::default();
193 restrcit_formats.transform(&mut schema);
194 serde_json::to_string_pretty(&schema).unwrap()
195}