crossbundle_tools/commands/apple/
codesign.rs

1use crate::error::*;
2use std::{
3    path::{Path, PathBuf},
4    process::Command,
5};
6
7const XCODE_PATH: &str = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate";
8const BIN_PATH: &str = "/usr/bin/codesign_allocate";
9
10/// Signs app. Runs `codesign ...` command.
11pub fn codesign(
12    item_path: &Path,
13    force: bool,
14    sign_identity: Option<String>,
15    entitlements: Option<PathBuf>,
16) -> Result<()> {
17    if !item_path.exists() {
18        return Err(AppleError::CodesignFailed("Item not found".to_owned()).into());
19    }
20    let mut codesign_allocate_path = XCODE_PATH;
21    if !Path::new(codesign_allocate_path).exists() {
22        codesign_allocate_path = BIN_PATH;
23        if !Path::new(codesign_allocate_path).exists() {
24            return Err(AppleError::CodesignAllocateNotFound.into());
25        }
26    }
27    let mut cmd = Command::new("codesign");
28    cmd.env("CODESIGN_ALLOCATE", codesign_allocate_path);
29    if force {
30        cmd.arg("--force");
31    }
32    if let Some(sign_identity) = sign_identity {
33        cmd.args(["--sign", &sign_identity]);
34    } else {
35        cmd.args(["--sign", "-"]);
36    }
37    cmd.arg("--timestamp=none");
38    if let Some(entitlements) = entitlements {
39        cmd.args(["--entitlements", entitlements.to_str().unwrap()]);
40    }
41    cmd.arg(item_path);
42    let output = cmd.output()?;
43    if !output.status.success() {
44        return Err(AppleError::CodesignFailed(
45            String::from_utf8(output.stderr)
46                .unwrap()
47                .replace("error: ", "")
48                .replace('\n', ""),
49        )
50        .into());
51    }
52    Ok(())
53}