feat(init): Add the new/init subcommands (#85)

This commit is contained in:
Gerald Pinder 2024-11-14 20:15:12 -05:00 committed by GitHub
parent e3b246ef91
commit 918da22952
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 765 additions and 152 deletions

View file

@ -15,7 +15,7 @@ use blue_build_utils::{
};
use cached::proc_macro::cached;
use log::{debug, info, trace, warn};
use miette::{bail, IntoDiagnostic, Result};
use miette::{bail, miette, IntoDiagnostic, Result};
use once_cell::sync::Lazy;
use semver::Version;
use serde::Deserialize;
@ -23,19 +23,18 @@ use tempfile::TempDir;
use crate::{
drivers::{
opts::{RunOptsEnv, RunOptsVolume},
opts::{
BuildOpts, BuildTagPushOpts, GetMetadataOpts, PushOpts, RunOpts, RunOptsEnv,
RunOptsVolume, TagOpts,
},
traits::{BuildDriver, DriverVersion, InspectDriver, RunDriver},
types::ImageMetadata,
types::Platform,
},
logging::CommandLogging,
signal_handler::{add_cid, remove_cid, ContainerId, ContainerRuntime},
};
use super::{
opts::{BuildOpts, BuildTagPushOpts, GetMetadataOpts, PushOpts, RunOpts, TagOpts},
types::ImageMetadata,
BuildDriver, DriverVersion, InspectDriver, RunDriver,
};
#[derive(Deserialize, Debug, Clone)]
struct DockerImageMetadata {
manifest: DockerImageMetadataManifest,
@ -238,7 +237,14 @@ impl BuildDriver for DockerDriver {
trace!("{command:?}");
let mut child = command.spawn().into_diagnostic()?;
write!(child.stdin.as_mut().unwrap(), "{password}").into_diagnostic()?;
write!(
child
.stdin
.as_mut()
.ok_or_else(|| miette!("Unable to open pipe to stdin"))?,
"{password}"
)
.into_diagnostic()?;
let output = child.wait_with_output().into_diagnostic()?;
@ -399,6 +405,8 @@ fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
impl RunDriver for DockerDriver {
fn run(opts: &RunOpts) -> std::io::Result<ExitStatus> {
trace!("DockerDriver::run({opts:#?})");
let cid_path = TempDir::new()?;
let cid_file = cid_path.path().join("cid");
let cid = ContainerId::new(&cid_file, ContainerRuntime::Docker, false);
@ -414,6 +422,8 @@ impl RunDriver for DockerDriver {
}
fn run_output(opts: &RunOpts) -> std::io::Result<std::process::Output> {
trace!("DockerDriver::run({opts:#?})");
let cid_path = TempDir::new()?;
let cid_file = cid_path.path().join("cid");
let cid = ContainerId::new(&cid_file, ContainerRuntime::Docker, false);
@ -432,7 +442,8 @@ fn docker_run(opts: &RunOpts, cid_file: &Path) -> Command {
let command = cmd!(
"docker",
"run",
format!("--cidfile={}", cid_file.display()),
"--cidfile",
cid_file,
if opts.privileged => "--privileged",
if opts.remove => "--rm",
if opts.pull => "--pull=always",

View file

@ -1,3 +1,5 @@
use std::path::PathBuf;
use blue_build_utils::{
constants::{
GITHUB_EVENT_NAME, GITHUB_EVENT_PATH, GITHUB_REF_NAME, GITHUB_SHA, GITHUB_TOKEN_ISSUER_URL,
@ -130,6 +132,10 @@ impl CiDriver for GithubDriver {
.trim()
.to_lowercase())
}
fn default_ci_file_path() -> PathBuf {
PathBuf::from(".github/workflows/build.yml")
}
}
#[cfg(test)]

View file

@ -1,3 +1,5 @@
use std::path::PathBuf;
use blue_build_utils::{
constants::{
CI_COMMIT_REF_NAME, CI_COMMIT_SHORT_SHA, CI_DEFAULT_BRANCH, CI_MERGE_REQUEST_IID,
@ -140,6 +142,10 @@ impl CiDriver for GitlabDriver {
)
.to_lowercase())
}
fn default_ci_file_path() -> PathBuf {
PathBuf::from(".gitlab-ci.yml")
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use std::path::PathBuf;
use blue_build_utils::{cmd, string_vec};
use log::trace;
use miette::bail;
use super::{opts::GenerateTagsOpts, CiDriver, Driver};
@ -13,13 +14,11 @@ impl CiDriver for LocalDriver {
}
fn keyless_cert_identity() -> miette::Result<String> {
trace!("LocalDriver::keyless_cert_identity()");
bail!("Keyless not supported");
unimplemented!()
}
fn oidc_provider() -> miette::Result<String> {
trace!("LocalDriver::oidc_provider()");
bail!("Keyless not supported");
unimplemented!()
}
fn generate_tags(opts: &GenerateTagsOpts) -> miette::Result<Vec<String>> {
@ -75,6 +74,10 @@ impl CiDriver for LocalDriver {
trace!("LocalDriver::get_registry()");
Ok(String::from("localhost"))
}
fn default_ci_file_path() -> PathBuf {
unimplemented!()
}
}
fn commit_sha() -> Option<String> {

View file

@ -19,19 +19,14 @@ use tempfile::TempDir;
use crate::{
drivers::{
opts::{RunOptsEnv, RunOptsVolume},
types::ImageMetadata,
types::Platform,
opts::{BuildOpts, GetMetadataOpts, PushOpts, RunOpts, RunOptsEnv, RunOptsVolume, TagOpts},
types::{ImageMetadata, Platform},
BuildDriver, DriverVersion, InspectDriver, RunDriver,
},
logging::{CommandLogging, Logger},
signal_handler::{add_cid, remove_cid, ContainerId, ContainerRuntime},
};
use super::{
opts::{BuildOpts, GetMetadataOpts, PushOpts, RunOpts, TagOpts},
BuildDriver, DriverVersion, InspectDriver, RunDriver,
};
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
struct PodmanImageMetadata {

View file

@ -12,17 +12,54 @@ use semver::{Version, VersionReq};
use crate::drivers::{functions::get_private_key, types::CiDriverType, Driver};
#[cfg(feature = "sigstore")]
use super::sigstore_driver::SigstoreDriver;
use super::{
buildah_driver::BuildahDriver,
cosign_driver::CosignDriver,
docker_driver::DockerDriver,
github_driver::GithubDriver,
gitlab_driver::GitlabDriver,
local_driver::LocalDriver,
opts::{
BuildOpts, BuildTagPushOpts, CheckKeyPairOpts, GenerateImageNameOpts, GenerateKeyPairOpts,
GenerateTagsOpts, GetMetadataOpts, PushOpts, RunOpts, SignOpts, SignVerifyOpts, TagOpts,
VerifyOpts, VerifyType,
},
podman_driver::PodmanDriver,
skopeo_driver::SkopeoDriver,
types::ImageMetadata,
};
trait PrivateDriver {}
macro_rules! impl_private_driver {
($($driver:ty),* $(,)?) => {
$(
impl PrivateDriver for $driver {}
)*
};
}
impl_private_driver!(
Driver,
DockerDriver,
PodmanDriver,
BuildahDriver,
GithubDriver,
GitlabDriver,
LocalDriver,
CosignDriver,
SkopeoDriver,
CiDriverType,
);
#[cfg(feature = "sigstore")]
impl_private_driver!(SigstoreDriver);
/// Trait for retrieving version of a driver.
pub trait DriverVersion {
#[allow(private_bounds)]
pub trait DriverVersion: PrivateDriver {
/// The version req string slice that follows
/// the semver standard <https://semver.org/>.
const VERSION_REQ: &'static str;
@ -43,7 +80,8 @@ pub trait DriverVersion {
/// Allows agnostic building, tagging
/// pushing, and login.
pub trait BuildDriver {
#[allow(private_bounds)]
pub trait BuildDriver: PrivateDriver {
/// Runs the build logic for the driver.
///
/// # Errors
@ -148,7 +186,8 @@ pub trait BuildDriver {
}
/// Allows agnostic inspection of images.
pub trait InspectDriver {
#[allow(private_bounds)]
pub trait InspectDriver: PrivateDriver {
/// Gets the metadata on an image tag.
///
/// # Errors
@ -156,7 +195,9 @@ pub trait InspectDriver {
fn get_metadata(opts: &GetMetadataOpts) -> Result<ImageMetadata>;
}
pub trait RunDriver: Sync + Send {
/// Allows agnostic running of containers.
#[allow(private_bounds)]
pub trait RunDriver: PrivateDriver {
/// Run a container to perform an action.
///
/// # Errors
@ -170,7 +211,9 @@ pub trait RunDriver: Sync + Send {
fn run_output(opts: &RunOpts) -> std::io::Result<Output>;
}
pub trait SigningDriver {
/// Allows agnostic management of signature keys.
#[allow(private_bounds)]
pub trait SigningDriver: PrivateDriver {
/// Generate a new private/public key pair.
///
/// # Errors
@ -275,7 +318,8 @@ pub trait SigningDriver {
}
/// Allows agnostic retrieval of CI-based information.
pub trait CiDriver {
#[allow(private_bounds)]
pub trait CiDriver: PrivateDriver {
/// Determines if we're on the main branch of
/// a repository.
fn on_default_branch() -> bool;
@ -374,4 +418,6 @@ pub trait CiDriver {
/// # Errors
/// Will error if the environment variables aren't set.
fn get_registry() -> Result<String>;
fn default_ci_file_path() -> PathBuf;
}