1#[cfg(unix)]
4use std::os::unix::fs::PermissionsExt;
5
6use axoasset::AxoClient;
7use camino::Utf8Path;
8use cargo_dist_schema::TripleNameRef;
9
10use crate::{config::ProductionMode, DistResult};
11
12mod macos;
13mod ssldotcom;
14
15#[derive(Debug)]
17pub struct Signing {
18 macos: Option<macos::Codesign>,
19 ssldotcom: Option<ssldotcom::CodeSignTool>,
20}
21
22impl Signing {
23 pub fn new(
25 client: &AxoClient,
26 host_target: &TripleNameRef,
27 dist_dir: &Utf8Path,
28 ssldotcom_windows_sign: Option<ProductionMode>,
29 macos_sign: bool,
30 ) -> DistResult<Self> {
31 let ssldotcom =
32 ssldotcom::CodeSignTool::new(client, host_target, dist_dir, ssldotcom_windows_sign)?;
33 let macos = if macos_sign {
34 macos::Codesign::new(host_target)?
35 } else {
36 None
37 };
38 Ok(Self { macos, ssldotcom })
39 }
40
41 pub fn sign(&self, file: &Utf8Path) -> DistResult<()> {
43 if let Some(signer) = &self.ssldotcom {
44 let extension = file.extension().unwrap_or_default();
45 if let "exe" | "msi" | "ps1" = extension {
46 signer.sign(file)?;
47 }
48 }
49 if let Some(signer) = &self.macos {
50 #[cfg(unix)]
53 let is_executable = file.metadata()?.permissions().mode() & 0o111 != 0;
54 #[cfg(windows)]
55 let is_executable = true;
56
57 if file.is_file() && is_executable {
61 signer.sign(file)?;
62 }
63 }
64 Ok(())
65 }
66}