Skip to main content

cargo_nfpm/
generator.rs

1//! Loading and converting the `Cargo.toml` to a `nfpm.yaml`.
2
3use anyhow::Context;
4
5use crate::cargo_schema::CargoManifest;
6use crate::nfpm_schema;
7use crate::triple::LlvmTriple;
8
9#[derive(Debug, Clone, Copy, clap::ValueEnum)]
10pub enum OutputFormat {
11    Apk,
12    Archlinux,
13    Deb,
14    Ipk,
15    Rpm,
16}
17
18pub fn get_config_from_package(
19    package: &cargo_metadata::Package,
20    triple: &str,
21    format: OutputFormat,
22) -> anyhow::Result<nfpm_schema::Config> {
23    let manifest_str =
24        std::fs::read_to_string(&package.manifest_path).context("reading Cargo.toml manifest")?;
25    let manifest: CargoManifest = toml::from_str(&manifest_str).context("parsing Cargo.toml")?;
26
27    let mut base_config = manifest
28        .package
29        .metadata
30        .as_ref()
31        .and_then(|metadata| metadata.nfpm.clone())
32        .unwrap_or_default();
33
34    merge_base_config_with_package(package, &mut base_config)
35        .context("merging config with manifest values")?;
36
37    let parsed = LlvmTriple::new(triple)
38        .with_context(|| format!("parsing cargo target triple: {triple}"))?;
39    base_config.arch = match format {
40        OutputFormat::Apk => Some(parsed.to_apk_arch()?.to_owned()),
41        OutputFormat::Archlinux => Some(parsed.to_archlinux_arch()?.to_owned()),
42        OutputFormat::Deb => Some(parsed.to_deb_arch()?.to_owned()),
43        OutputFormat::Ipk => Some(parsed.to_ipk_arch()?.to_owned()),
44        OutputFormat::Rpm => Some(parsed.to_rpm_arch()?.to_owned()),
45    };
46
47    // Set some sane defaults.
48    if base_config.epoch.is_none() {
49        base_config.epoch = Some("1".to_owned());
50    }
51    if base_config.release.is_none() {
52        base_config.release = Some("1".to_owned());
53    }
54    if base_config.platform.is_none() {
55        base_config.platform = Some("linux".to_owned());
56    }
57    if base_config.section.is_none() {
58        base_config.section = Some("default".to_owned());
59    }
60    if base_config.priority.is_none() {
61        base_config.priority = Some("extra".to_owned());
62    }
63
64    assert!(base_config.name.is_some());
65    assert!(base_config.arch.is_some());
66    assert!(base_config.version.is_some());
67
68    Ok(base_config)
69}
70
71fn merge_base_config_with_package(
72    package: &cargo_metadata::Package,
73    config: &mut nfpm_schema::Config,
74) -> anyhow::Result<()> {
75    // Only apply defaults if override isn't set.
76    if config.name.is_none() {
77        config.name = Some(package.name.as_ref().to_owned());
78    }
79    if config.version.is_none() {
80        config.version = Some(package.version.to_string());
81    }
82    if config.maintainer.is_none() {
83        config.maintainer = Some(package.authors.join(", "));
84    }
85    if config.description.is_none() {
86        if let Some(description) = &package.description {
87            config.description = Some(description.clone());
88        }
89    }
90    // The properties `documentation`, `readme`, and `repository` have no corresponding
91    // config value.
92    if config.homepage.is_none() {
93        if let Some(homepage) = &package.homepage {
94            config.homepage = Some(homepage.clone());
95        }
96    }
97    if config.license.is_none() {
98        if let Some(license) = &package.license {
99            config.license = Some(license.clone());
100        }
101    }
102
103    Ok(())
104}