refactor: Enable pedantic clippy lints

Updated files to comply with the new lint.
This commit is contained in:
Gerald Pinder 2024-03-12 18:07:46 -04:00
parent 580c3d6ce7
commit a54b78c8dc
19 changed files with 152 additions and 66 deletions

View file

@ -27,6 +27,8 @@ suspicious = "warn"
perf = "warn"
style = "warn"
nursery = "warn"
pedantic = "warn"
module_name_repetitions = "allow"
[package]
name = "blue-build"

View file

@ -73,6 +73,7 @@ impl<'a> Module<'a> {
self.get_module_type_list("containerfile", "snippets")
}
#[must_use]
pub fn print_module_context(&'a self) -> String {
serde_json::to_string(self).unwrap_or_else(|e| {
error!("Failed to parse module!!!!!: {e}");
@ -80,6 +81,7 @@ impl<'a> Module<'a> {
})
}
#[must_use]
pub fn get_files_list(&'a self) -> Option<Vec<(String, String)>> {
Some(
self.config

View file

@ -39,6 +39,7 @@ impl ModuleExt<'_> {
)
}
#[must_use]
pub fn get_akmods_info_list(&self, os_version: &str) -> Vec<AkmodsInfo> {
trace!("get_akmods_image_list({self:#?}, {os_version})");

View file

@ -1,7 +1,10 @@
use std::{borrow::Cow, env, fs, path::Path};
use anyhow::Result;
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
CI_COMMIT_REF_NAME, CI_COMMIT_SHORT_SHA, CI_DEFAULT_BRANCH, CI_MERGE_REQUEST_IID,
CI_PIPELINE_SOURCE, GITHUB_EVENT_NAME, GITHUB_REF_NAME, GITHUB_SHA, PR_EVENT_NUMBER,
};
use chrono::Local;
use indexmap::IndexMap;
use log::{debug, trace, warn};

View file

@ -1,4 +1,4 @@
use blue_build::commands::*;
use blue_build::commands::{BlueBuildArgs, BlueBuildCommand, CommandArgs};
use clap::Parser;
use env_logger::WriteStyle;

View file

@ -1,6 +1,9 @@
use blue_build_recipe::Recipe;
use blue_build_template::{GithubIssueTemplate, Template};
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
BUG_REPORT_WARNING_MESSAGE, GITHUB_CHAR_LIMIT, LC_TERMINAL, LC_TERMINAL_VERSION, TERM_PROGRAM,
TERM_PROGRAM_VERSION, UNKNOWN_SHELL, UNKNOWN_TERMINAL, UNKNOWN_VERSION,
};
use clap::Args;
use clap_complete::Shell;
use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
@ -82,7 +85,6 @@ impl BugReportCommand {
.color(Colors::BrightWhiteFg)
);
const WARNING_MESSAGE: &str = "Please copy the above report and open an issue manually.";
let question = requestty::Question::confirm("anonymous")
.message(
"Forward the pre-filled report above to GitHub in your browser?"
@ -103,11 +105,11 @@ impl BugReportCommand {
return Err(e.into());
}
} else {
println!("{WARNING_MESSAGE}");
println!("{BUG_REPORT_WARNING_MESSAGE}");
}
}
Err(_) => {
println!("Will not open an issue in your browser! {WARNING_MESSAGE}");
println!("Will not open an issue in your browser! {BUG_REPORT_WARNING_MESSAGE}");
}
}

View file

@ -6,7 +6,13 @@ use std::{
use anyhow::{bail, Result};
use blue_build_recipe::Recipe;
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
ARCHIVE_SUFFIX, BUILD_ID_LABEL, CI_DEFAULT_BRANCH, CI_PROJECT_NAME, CI_PROJECT_NAMESPACE,
CI_PROJECT_URL, CI_REGISTRY, CI_SERVER_HOST, CI_SERVER_PROTOCOL, CONTAINER_FILE, COSIGN_PATH,
COSIGN_PRIVATE_KEY, GITHUB_REPOSITORY_OWNER, GITHUB_TOKEN, GITHUB_TOKEN_ISSUER_URL,
GITHUB_WORKFLOW_REF, GITIGNORE_PATH, LABELED_ERROR_MESSAGE, NO_LABEL_ERROR_MESSAGE,
RECIPE_PATH, SIGSTORE_ID_TOKEN,
};
use clap::Args;
use colorized::{Color, Colors};
use log::{debug, info, trace, warn};
@ -165,7 +171,7 @@ impl BlueBuildCommand for BuildCommand {
if !is_ignored {
let containerfile = fs::read_to_string(container_file_path)?;
let has_label = containerfile.lines().any(|line| {
let label = format!("LABEL {}", BUILD_ID_LABEL);
let label = format!("LABEL {BUILD_ID_LABEL}");
line.to_string().trim().starts_with(&label)
});
@ -184,8 +190,8 @@ impl BlueBuildCommand for BuildCommand {
if let Ok(answer) = requestty::prompt_one(question) {
if answer.as_bool().unwrap_or(false) {
blue_build_utils::append_to_file(
GITIGNORE_PATH,
&format!("/{}", CONTAINER_FILE),
&GITIGNORE_PATH,
&format!("/{CONTAINER_FILE}"),
)?;
}
}
@ -229,7 +235,7 @@ impl BuildCommand {
let image_name = self.generate_full_image_name(&recipe)?;
if self.push {
self.login()?;
Self::login()?;
}
self.run_build(&image_name, &tags)?;
@ -239,7 +245,7 @@ impl BuildCommand {
Ok(())
}
fn login(&self) -> Result<()> {
fn login() -> Result<()> {
trace!("BuildCommand::login()");
info!("Attempting to login to the registry");
@ -370,10 +376,10 @@ impl BuildCommand {
strat.tag(&full_image, image_name, tag)?;
if self.push {
let retry_count = if !self.no_retry_push {
self.retry_count
} else {
let retry_count = if self.no_retry_push {
0
} else {
self.retry_count
};
debug!("Pushing all images");
@ -427,33 +433,7 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> {
(_, _, _, _, _, _, _, Ok(cosign_private_key))
if !cosign_private_key.is_empty() && Path::new(COSIGN_PATH).exists() =>
{
info!("Signing image: {image_digest}");
trace!("cosign sign --key=env://COSIGN_PRIVATE_KEY {image_digest}");
if Command::new("cosign")
.arg("sign")
.arg("--key=env://COSIGN_PRIVATE_KEY")
.arg(&image_digest)
.status()?
.success()
{
info!("Successfully signed image!");
} else {
bail!("Failed to sign image: {image_digest}");
}
trace!("cosign verify --key {COSIGN_PATH} {image_name_tag}");
if !Command::new("cosign")
.arg("verify")
.arg(format!("--key={COSIGN_PATH}"))
.arg(&image_name_tag)
.status()?
.success()
{
bail!("Failed to verify image!");
}
sign_priv_public_pair(&image_digest, &image_name_tag)?;
}
// Gitlab keyless
(
@ -541,6 +521,38 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> {
Ok(())
}
fn sign_priv_public_pair(image_digest: &str, image_name_tag: &str) -> Result<()> {
info!("Signing image: {image_digest}");
trace!("cosign sign --key=env://{COSIGN_PRIVATE_KEY} {image_digest}");
if Command::new("cosign")
.arg("sign")
.arg("--key=env://COSIGN_PRIVATE_KEY")
.arg(image_digest)
.status()?
.success()
{
info!("Successfully signed image!");
} else {
bail!("Failed to sign image: {image_digest}");
}
trace!("cosign verify --key {COSIGN_PATH} {image_name_tag}");
if !Command::new("cosign")
.arg("verify")
.arg(format!("--key={COSIGN_PATH}"))
.arg(image_name_tag)
.status()?
.success()
{
bail!("Failed to verify image!");
}
Ok(())
}
fn get_image_digest(image_name: &str, tag: Option<&str>) -> Result<String> {
trace!("get_image_digest({image_name}, {tag:?})");

View file

@ -6,7 +6,7 @@ use std::{
use anyhow::{bail, Result};
use blue_build_recipe::Recipe;
use blue_build_utils::constants::*;
use blue_build_utils::constants::{ARCHIVE_SUFFIX, LOCAL_BUILD};
use clap::Args;
use log::{debug, info, trace};
use typed_builder::TypedBuilder;

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use anyhow::Result;
use blue_build_recipe::Recipe;
use blue_build_template::{ContainerFileTemplate, Template};
use blue_build_utils::constants::*;
use blue_build_utils::constants::RECIPE_PATH;
use clap::Args;
use log::{debug, info, trace};
use typed_builder::TypedBuilder;

View file

@ -1,5 +1,6 @@
//! The root library for blue-build.
#![doc = include_str!("../README.md")]
#![allow(clippy::needless_raw_string_hashes)]
shadow_rs::shadow!(shadow);

View file

@ -14,7 +14,10 @@ use std::{
use anyhow::{anyhow, bail, Result};
use blue_build_recipe::Recipe;
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
IMAGE_VERSION_LABEL, RUN_PODMAN_SOCK, VAR_RUN_PODMAN_PODMAN_SOCK, VAR_RUN_PODMAN_SOCK,
XDG_RUNTIME_DIR,
};
pub use credentials::Credentials;
use log::{debug, error, info, trace};
use once_cell::sync::Lazy;
@ -94,17 +97,37 @@ static OS_VERSION: Lazy<Mutex<HashMap<String, String>>> = Lazy::new(|| Mutex::ne
/// Allows agnostic building, tagging
/// pushing, and login.
pub trait BuildStrategy: Sync + Send {
/// Runs the build logic for the strategy.
///
/// # Errors
/// Will error if the build fails.
fn build(&self, image: &str) -> Result<()>;
/// Runs the tag logic for the strategy.
///
/// # Errors
/// Will error if the tagging fails.
fn tag(&self, src_image: &str, image_name: &str, tag: &str) -> Result<()>;
/// Runs the push logic for the strategy
///
/// # Errors
/// Will error if the push fails.
fn push(&self, image: &str) -> Result<()>;
/// Runs the login logic for the strategy.
///
/// # Errors
/// Will error if login fails.
fn login(&self) -> Result<()>;
}
/// Allows agnostic inspection of images.
pub trait InspectStrategy: Sync + Send {
/// Gets the labels on an image tag.
///
/// # Errors
/// Will error if it is unable to get the labels.
fn get_labels(&self, image_name: &str, tag: &str) -> Result<ImageInspection>;
}
@ -121,12 +144,21 @@ pub struct Strategy<'a> {
}
impl<'a> Strategy<'a> {
/// Initializes the Strategy with user provided credentials.
///
/// If you want to take advantage of a user's credentials,
/// you will want to run init before trying to use any of
/// the strategies.
///
/// # Errors
/// Will error if it is unable to set the user credentials.
pub fn init(self) -> Result<()> {
credentials::set_user_creds(self.username, self.password, self.registry)?;
Ok(())
}
/// Gets the current build's UUID
#[must_use]
pub fn get_build_id() -> Uuid {
*BUILD_ID
}
@ -141,14 +173,22 @@ impl<'a> Strategy<'a> {
INSPECT_STRATEGY.clone()
}
/// Get the current environment credentials.
///
/// # Errors
/// Will error if credentials don't exist.
pub fn get_credentials() -> Result<&'static Credentials> {
credentials::get_credentials()
credentials::get()
}
/// Retrieve the `os_version` for an image.
///
/// This gets cached for faster resolution if it's required
/// in another part of the program.
///
/// # Errors
/// Will error if the image doesn't have OS version info
/// or we are unable to lock a mutex.
pub fn get_os_version(recipe: &Recipe) -> Result<String> {
trace!("get_os_version({recipe:#?})");
let image = format!("{}:{}", &recipe.base_image, &recipe.image_version);

View file

@ -56,7 +56,7 @@ impl BuildStrategy for BuildahStrategy {
fn login(&self) -> Result<()> {
let (registry, username, password) =
credentials::get_credentials().map(|c| (&c.registry, &c.username, &c.password))?;
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
trace!("buildah login -u {username} -p [MASKED] {registry}");
let output = Command::new("buildah")

View file

@ -1,7 +1,9 @@
use std::{env, sync::Mutex};
use anyhow::{anyhow, Result};
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
CI_REGISTRY, CI_REGISTRY_PASSWORD, CI_REGISTRY_USER, GITHUB_ACTIONS, GITHUB_ACTOR, GITHUB_TOKEN,
};
use once_cell::sync::Lazy;
use typed_builder::TypedBuilder;
@ -44,9 +46,9 @@ static ENV_CREDENTIALS: Lazy<Option<Credentials>> = Lazy::new(|| {
let (username, password, registry) = {
USER_CREDS.lock().map_or((None, None, None), |creds| {
(
creds.username.as_ref().map(|s| s.to_owned()),
creds.password.as_ref().map(|s| s.to_owned()),
creds.registry.as_ref().map(|s| s.to_owned()),
creds.username.as_ref().map(std::borrow::ToOwned::to_owned),
creds.password.as_ref().map(std::borrow::ToOwned::to_owned),
creds.registry.as_ref().map(std::borrow::ToOwned::to_owned),
)
})
};
@ -107,9 +109,9 @@ pub fn set_user_creds(
let mut creds_lock = USER_CREDS
.lock()
.map_err(|e| anyhow!("Failed to set credentials: {e}"))?;
creds_lock.username = username.map(|s| s.to_owned());
creds_lock.password = password.map(|s| s.to_owned());
creds_lock.registry = registry.map(|s| s.to_owned());
creds_lock.username = username.map(std::borrow::ToOwned::to_owned);
creds_lock.password = password.map(std::borrow::ToOwned::to_owned);
creds_lock.registry = registry.map(std::borrow::ToOwned::to_owned);
drop(creds_lock);
Ok(())
}
@ -118,7 +120,7 @@ pub fn set_user_creds(
///
/// # Errors
/// Will error if there aren't any credentials available.
pub fn get_credentials() -> Result<&'static Credentials> {
pub fn get() -> Result<&'static Credentials> {
ENV_CREDENTIALS
.as_ref()
.ok_or_else(|| anyhow!("No credentials available"))

View file

@ -4,7 +4,7 @@ use std::{
};
use anyhow::{bail, Result};
use blue_build_utils::constants::*;
use blue_build_utils::constants::{BB_BUILDKIT_CACHE_GHA, SKOPEO_IMAGE};
use log::{info, trace};
use crate::image_inspection::ImageInspection;
@ -83,7 +83,7 @@ impl BuildStrategy for DockerStrategy {
fn login(&self) -> Result<()> {
let (registry, username, password) =
credentials::get_credentials().map(|c| (&c.registry, &c.username, &c.password))?;
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
trace!("docker login -u {username} -p [MASKED] {registry}");
let output = Command::new("docker")

View file

@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::{bail, Result};
use blue_build_utils::constants::*;
use blue_build_utils::constants::BUILD_ID_LABEL;
use futures_util::StreamExt;
use log::{debug, error};
use log::{info, trace};
@ -104,7 +104,7 @@ impl BuildStrategy for PodmanApiStrategy {
trace!("PodmanApiStrategy::push({image})");
let (username, password, registry) =
credentials::get_credentials().map(|c| (&c.username, &c.password, &c.registry))?;
credentials::get().map(|c| (&c.username, &c.password, &c.registry))?;
trace!("Retrieved creds for user {username} on registry {registry}");
self.rt.block_on(async {

View file

@ -61,7 +61,7 @@ impl BuildStrategy for PodmanStrategy {
fn login(&self) -> Result<()> {
let (registry, username, password) =
credentials::get_credentials().map(|c| (&c.registry, &c.username, &c.password))?;
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
trace!("podman login -u {username} -p [MASKED] {registry}");
let output = Command::new("podman")

View file

@ -1,7 +1,10 @@
use std::{borrow::Cow, env, fs, path::Path, process};
use blue_build_recipe::Recipe;
use blue_build_utils::constants::*;
use blue_build_utils::constants::{
CI_PROJECT_NAME, CI_PROJECT_NAMESPACE, CI_REGISTRY, CI_SERVER_HOST, CI_SERVER_PROTOCOL,
COSIGN_PATH, GITHUB_REPOSITORY_OWNER, GITHUB_RESPOSITORY, GITHUB_SERVER_URL,
};
use log::{debug, error, trace};
use typed_builder::TypedBuilder;
use uuid::Uuid;

View file

@ -73,3 +73,5 @@ pub const NO_LABEL_ERROR_MESSAGE: &str =
"It looks you have a Containerfile that has not been generated by BlueBuild. \
Running `build` will override your Containerfile and add an entry to the .gitignore. \
Do you want to continue?";
pub const BUG_REPORT_WARNING_MESSAGE: &str =
"Please copy the above report and open an issue manually.";

View file

@ -1,7 +1,7 @@
pub mod command_output;
pub mod constants;
use std::{io::Write, path::PathBuf, process::Command, thread, time::Duration};
use std::{ffi::OsStr, io::Write, path::PathBuf, process::Command, thread, time::Duration};
use anyhow::{anyhow, Result};
use format_serde_error::SerdeError;
@ -9,6 +9,10 @@ use log::{debug, trace};
pub use command_output::*;
/// Checks for the existance of a given command.
///
/// # Errors
/// Will error if the command doesn't exist.
pub fn check_command_exists(command: &str) -> Result<()> {
trace!("check_command_exists({command})");
debug!("Checking if {command} exists");
@ -29,9 +33,14 @@ pub fn check_command_exists(command: &str) -> Result<()> {
}
}
pub fn append_to_file(file_path: &str, content: &str) -> Result<()> {
trace!("append_to_file({file_path}, {content})");
debug!("Appending {content} to {file_path}");
/// Appends a string to a file.
///
/// # Errors
/// Will error if it fails to append to a file.
pub fn append_to_file<T: Into<PathBuf> + AsRef<OsStr>>(file_path: &T, content: &str) -> Result<()> {
let file_path: PathBuf = file_path.into();
trace!("append_to_file({}, {content})", file_path.display());
debug!("Appending {content} to {}", file_path.display());
let mut file = std::fs::OpenOptions::new()
.append(true)
@ -42,6 +51,8 @@ pub fn append_to_file(file_path: &str, content: &str) -> Result<()> {
Ok(())
}
/// Creates a serde error for displaying the file
/// and where the error occurred.
pub fn serde_yaml_err(contents: &str) -> impl Fn(serde_yaml::Error) -> SerdeError + '_ {
|err: serde_yaml::Error| {
let location = err.location();
@ -57,10 +68,15 @@ pub fn serde_yaml_err(contents: &str) -> impl Fn(serde_yaml::Error) -> SerdeErro
}
}
pub fn retry<V, F>(mut attempts: u8, delay: u64, f: F) -> anyhow::Result<V>
/// Performs a retry on a given closure with a given nubmer of attempts and delay.
///
/// # Errors
/// Will error when retries have been expended.
pub fn retry<V, F>(attempts: u8, delay: u64, f: F) -> anyhow::Result<V>
where
F: Fn() -> anyhow::Result<V>,
{
let mut attempts = attempts;
loop {
match f() {
Ok(v) => return Ok(v),