Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Move recipe out to its own module #18

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ use tokio::runtime::Runtime;

use crate::{
commands::template::TemplateCommand,
module_recipe::Recipe,
ops::{self, ARCHIVE_SUFFIX},
};

use super::{template::Recipe, BlueBuildCommand};
use super::BlueBuildCommand;

#[derive(Debug, Clone, Args, TypedBuilder)]
pub struct BuildCommand {
Expand Down
3 changes: 2 additions & 1 deletion src/commands/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use typed_builder::TypedBuilder;
use users::{Users, UsersCache};

use crate::{
commands::{build::BuildCommand, template::Recipe},
commands::build::BuildCommand,
module_recipe::Recipe,
ops::{self, ARCHIVE_SUFFIX, LOCAL_BUILD},
};

Expand Down
203 changes: 2 additions & 201 deletions src/commands/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use serde::{Deserialize, Serialize};
use serde_yaml::Value;
use typed_builder::TypedBuilder;

use crate::module_recipe::Recipe;

use super::BlueBuildCommand;

#[derive(Debug, Clone, Template, TypedBuilder)]
Expand All @@ -31,132 +33,6 @@ pub struct ContainerFileTemplate<'a> {
#[template(path = "export.sh", escape = "none")]
pub struct ExportsTemplate;

#[derive(Serialize, Clone, Deserialize, Debug, TypedBuilder)]
pub struct Recipe {
#[builder(setter(into))]
pub name: String,

#[builder(setter(into))]
pub description: String,

#[serde(alias = "base-image")]
#[builder(setter(into))]
pub base_image: String,

#[serde(alias = "image-version")]
#[builder(setter(into))]
pub image_version: String,

#[serde(alias = "blue-build-tag")]
#[builder(default, setter(into, strip_option))]
pub blue_build_tag: Option<String>,

#[serde(flatten)]
pub modules_ext: ModuleExt,

#[serde(flatten)]
#[builder(setter(into))]
pub extra: IndexMap<String, Value>,
}

impl Recipe {
#[must_use]
pub fn generate_tags(&self) -> Vec<String> {
trace!("Recipe::generate_tags()");
debug!("Generating image tags for {}", &self.name);

let mut tags: Vec<String> = Vec::new();
let image_version = &self.image_version;
let timestamp = Local::now().format("%Y%m%d").to_string();

if let (Ok(commit_branch), Ok(default_branch), Ok(commit_sha), Ok(pipeline_source)) = (
env::var("CI_COMMIT_REF_NAME"),
env::var("CI_DEFAULT_BRANCH"),
env::var("CI_COMMIT_SHORT_SHA"),
env::var("CI_PIPELINE_SOURCE"),
) {
trace!("CI_COMMIT_REF_NAME={commit_branch}, CI_DEFAULT_BRANCH={default_branch},CI_COMMIT_SHORT_SHA={commit_sha}, CI_PIPELINE_SOURCE={pipeline_source}");
warn!("Detected running in Gitlab, pulling information from CI variables");

if let Ok(mr_iid) = env::var("CI_MERGE_REQUEST_IID") {
trace!("CI_MERGE_REQUEST_IID={mr_iid}");
if pipeline_source == "merge_request_event" {
debug!("Running in a MR");
tags.push(format!("mr-{mr_iid}-{image_version}"));
}
}

if default_branch == commit_branch {
debug!("Running on the default branch");
tags.push(image_version.to_string());
tags.push(format!("{image_version}-{timestamp}"));
tags.push(timestamp);
} else {
debug!("Running on branch {commit_branch}");
tags.push(format!("{commit_branch}-{image_version}"));
}

tags.push(format!("{commit_sha}-{image_version}"));
} else if let (
Ok(github_event_name),
Ok(github_event_number),
Ok(github_sha),
Ok(github_ref_name),
) = (
env::var("GITHUB_EVENT_NAME"),
env::var("PR_EVENT_NUMBER"),
env::var("GITHUB_SHA"),
env::var("GITHUB_REF_NAME"),
) {
trace!("GITHUB_EVENT_NAME={github_event_name},PR_EVENT_NUMBER={github_event_number},GITHUB_SHA={github_sha},GITHUB_REF_NAME={github_ref_name}");
warn!("Detected running in Github, pulling information from GITHUB variables");

let mut short_sha = github_sha;
short_sha.truncate(7);

if github_event_name == "pull_request" {
debug!("Running in a PR");
tags.push(format!("pr-{github_event_number}-{image_version}"));
} else if github_ref_name == "live" {
tags.push(image_version.to_owned());
tags.push(format!("{image_version}-{timestamp}"));
tags.push("latest".to_string());
} else {
tags.push(format!("br-{github_ref_name}-{image_version}"));
}
tags.push(format!("{short_sha}-{image_version}"));
} else {
warn!("Running locally");
tags.push(format!("{image_version}-local"));
}
info!("Finished generating tags!");
debug!("Tags: {tags:#?}");
tags
}
}

#[derive(Serialize, Clone, Deserialize, Debug, Template, TypedBuilder)]
#[template(path = "Containerfile.module", escape = "none")]
pub struct ModuleExt {
#[builder(default, setter(into))]
pub modules: Vec<Module>,
}

#[derive(Serialize, Deserialize, Debug, Clone, TypedBuilder)]
pub struct Module {
#[serde(rename = "type")]
#[builder(default, setter(into, strip_option))]
pub module_type: Option<String>,

#[serde(rename = "from-file")]
#[builder(default, setter(into, strip_option))]
pub from_file: Option<String>,

#[serde(flatten)]
#[builder(default, setter(into))]
pub config: IndexMap<String, Value>,
}

#[derive(Debug, Clone, Args, TypedBuilder)]
pub struct TemplateCommand {
/// The recipe file to create a template from
Expand Down Expand Up @@ -228,81 +104,6 @@ fn print_script(script_contents: &ExportsTemplate) -> String {
)
}

fn get_containerfile_list(module: &Module) -> Option<Vec<String>> {
if module.module_type.as_ref()? == "containerfile" {
Some(
module
.config
.get("containerfiles")?
.as_sequence()?
.iter()
.filter_map(|t| Some(t.as_str()?.to_owned()))
.collect(),
)
} else {
None
}
}

fn print_containerfile(containerfile: &str) -> String {
trace!("print_containerfile({containerfile})");
debug!("Loading containerfile contents for {containerfile}");

let path = format!("config/containerfiles/{containerfile}/Containerfile");

let file = fs::read_to_string(&path).unwrap_or_else(|e| {
error!("Failed to read file {path}: {e}");
process::exit(1);
});

trace!("Containerfile contents {path}:\n{file}");

file
}

fn get_module_from_file(file_name: &str) -> String {
trace!("get_module_from_file({file_name})");

let io_err_fn = |e| {
error!("Failed to read module {file_name}: {e}");
process::exit(1);
};

let file_path = PathBuf::from("config").join(file_name);

let file = fs::read_to_string(file_path).unwrap_or_else(io_err_fn);

let serde_err_fn = |e| {
error!("Failed to deserialize module {file_name}: {e}");
process::exit(1);
};

let template_err_fn = |e| {
error!("Failed to render module {file_name}: {e}");
process::exit(1);
};

serde_yaml::from_str::<ModuleExt>(file.as_str()).map_or_else(
|_| {
let module = serde_yaml::from_str::<Module>(file.as_str()).unwrap_or_else(serde_err_fn);

ModuleExt::builder()
.modules(vec![module])
.build()
.render()
.unwrap_or_else(template_err_fn)
},
|module_ext| module_ext.render().unwrap_or_else(template_err_fn),
)
}

fn print_module_context(module: &Module) -> String {
serde_json::to_string(module).unwrap_or_else(|e| {
error!("Failed to parse module: {e}");
process::exit(1);
})
}

fn running_gitlab_actions() -> bool {
trace!(" running_gitlab_actions()");

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
#![allow(clippy::module_name_repetitions)]

pub mod commands;
pub mod module_recipe;
mod ops;
Loading
Loading