use cargo_dist_schema::{
target_lexicon::{OperatingSystem, Triple},
DashScript, GhaRunStep, PowershellScript,
};
use semver::Version;
use serde::Serialize;
use crate::config::v0::CargoDistUrlOverrideRef;
use self::github::GithubCiInfo;
pub mod github;
const SELF_DIST_VERSION: &str = env!("CARGO_PKG_VERSION");
const BASE_DIST_FETCH_URL: &str = "https://github.com/axodotdev/cargo-dist/releases/download";
const BASE_CARGO_AUDITABLE_FETCH_LATEST_URL: &str =
"https://github.com/rust-secure-code/cargo-auditable/releases/latest/download";
const BASE_CARGO_CYCLONEDX_FETCH_URL: &str =
"https://github.com/CycloneDX/cyclonedx-rust-cargo/releases/download";
const CARGO_CYCLONEDX_VERSION: &str = "0.5.5";
const BASE_OMNIBOR_FETCH_URL: &str = "https://github.com/omnibor/omnibor-rs/releases/download";
const OMNIBOR_VERSION: &str = "0.7.0";
#[derive(Debug, Default)]
pub struct CiInfo {
pub github: Option<GithubCiInfo>,
}
struct DistInstallSettings<'a> {
version: &'a Version,
url_override: Option<&'a CargoDistUrlOverrideRef>,
}
pub trait InstallStrategy {
fn dash(&self) -> GhaRunStep;
fn powershell(&self) -> GhaRunStep;
fn for_triple(&self, triple: &Triple) -> GhaRunStep {
match triple.operating_system {
OperatingSystem::Linux | OperatingSystem::Darwin(_) => self.dash(),
OperatingSystem::Windows => self.powershell(),
_ => panic!("unsupported host triple {triple}"),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub enum DistInstallStrategy {
Installer {
installer_url: String,
installer_name: String,
},
GitBranch {
branch: String,
},
}
impl DistInstallSettings<'_> {
fn install_strategy(&self) -> DistInstallStrategy {
if let Some(branch) = self.version.pre.strip_prefix("github-") {
return DistInstallStrategy::GitBranch {
branch: branch.to_owned(),
};
}
if let Some(url) = self.url_override.as_ref() {
return DistInstallStrategy::Installer {
installer_url: url.as_str().to_owned(),
installer_name: "cargo-dist-installer".to_owned(),
};
}
let version = self.version;
let format = cargo_dist_schema::format_of_version(version);
let installer_name = if format.unsupported() {
panic!("requested dist v{version}, which is not supported by the this copy of dist ({SELF_DIST_VERSION})");
} else if format.artifact_names_contain_versions() {
format!("cargo-dist-v{version}-installer")
} else {
"cargo-dist-installer".to_owned()
};
DistInstallStrategy::Installer {
installer_url: format!("{BASE_DIST_FETCH_URL}/v{version}"),
installer_name,
}
}
}
impl InstallStrategy for DistInstallStrategy {
fn dash(&self) -> GhaRunStep {
DashScript::new(match self {
DistInstallStrategy::Installer { installer_url, installer_name } => format!(
"curl --proto '=https' --tlsv1.2 -LsSf {installer_url}/{installer_name}.sh | sh"
),
DistInstallStrategy::GitBranch { branch } => format!(
"cargo install --git https://github.com/axodotdev/cargo-dist/ --branch={branch} --locked cargo-dist"
),
}).into()
}
fn powershell(&self) -> GhaRunStep {
PowershellScript::new(match self {
DistInstallStrategy::Installer { installer_url, installer_name } => format!(
"irm {installer_url}/{installer_name}.ps1 | iex"
),
DistInstallStrategy::GitBranch { branch } => format!(
"cargo install --git https://github.com/axodotdev/cargo-dist/ --branch={branch} --locked cargo-dist"
),
}).into()
}
}
struct CargoAuditableInstallStrategy;
impl InstallStrategy for CargoAuditableInstallStrategy {
fn dash(&self) -> GhaRunStep {
let installer_url =
format!("{BASE_CARGO_AUDITABLE_FETCH_LATEST_URL}/cargo-auditable-installer.sh");
DashScript::new(format!(
"curl --proto '=https' --tlsv1.2 -LsSf {installer_url} | sh"
))
.into()
}
fn powershell(&self) -> GhaRunStep {
let installer_url =
format!("{BASE_CARGO_AUDITABLE_FETCH_LATEST_URL}/cargo-auditable-installer.ps1");
PowershellScript::new(format!(r#"powershell -c "irm {installer_url} | iex""#)).into()
}
}
struct CargoCyclonedxInstallStrategy;
impl InstallStrategy for CargoCyclonedxInstallStrategy {
fn dash(&self) -> GhaRunStep {
let installer_url =
format!("{BASE_CARGO_CYCLONEDX_FETCH_URL}/cargo-cyclonedx-{CARGO_CYCLONEDX_VERSION}/cargo-cyclonedx-installer.sh");
DashScript::new(format!(
"curl --proto '=https' --tlsv1.2 -LsSf {installer_url} | sh"
))
.into()
}
fn powershell(&self) -> GhaRunStep {
let installer_url =
format!("{BASE_CARGO_CYCLONEDX_FETCH_URL}/cargo-cyclonedx-{CARGO_CYCLONEDX_VERSION}/cargo-cyclonedx-installer.ps1");
PowershellScript::new(format!(r#"powershell -c "irm {installer_url} | iex""#)).into()
}
}
struct OmniborInstallStrategy;
impl InstallStrategy for OmniborInstallStrategy {
fn dash(&self) -> GhaRunStep {
let installer_url = format!(
"{BASE_OMNIBOR_FETCH_URL}/omnibor-cli-v{OMNIBOR_VERSION}/omnibor-cli-installer.sh"
);
DashScript::new(format!(
"curl --proto '=https' --tlsv1.2 -LsSf {installer_url} | sh"
))
.into()
}
fn powershell(&self) -> GhaRunStep {
let installer_url = format!(
"{BASE_OMNIBOR_FETCH_URL}/omnibor-cli-v{OMNIBOR_VERSION}/omnibor-cli-installer.ps1"
);
PowershellScript::new(format!(r#"powershell -c "irm {installer_url} | iex""#)).into()
}
}