embed-licensing 0.3.1

Embed licensing information of dependencies to comply with free software licenses
Documentation
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
//
// SPDX-License-Identifier: MPL-2.0

use std::collections::HashSet;
use std::rc::Rc;

use cargo_platform::{Cfg, CfgExpr, Platform};
use pretty_assertions::assert_eq;

use embed_licensing::{collect_from_manifest, CollectConfig, CollectPlatform, Licensing};

mod common;
use common::*;

fn simple_dependency(name: &str) -> Result<Rc<TestPackage>> {
    Ok(Rc::new(TestPackage::new(SimpleManifest {
        name: name.to_string(),
        version: "1.0.0".to_string(),
        license: Some(spdx::Expression::parse("MIT")?),
        license_file: None,
        authors: vec!["Jane Person <jane.person@example.com>".to_string()],
        repository: Some("https://example.com/dependency.git".to_string()),
        dependencies: vec![].into(),
        dev_dependencies: vec![].into(),
        build_dependencies: vec![].into(),
    })?))
}

fn fixture() -> Result<TestPackage> {
    let dependency_only_windows = simple_dependency("only_windows")?;
    let dependency_only_linux = simple_dependency("only_linux")?;
    let dependency_only_aarch64_apple_darwin = simple_dependency("only_aarch64_apple_darwin")?;
    let dependency_only_amd64_linux_gnu = simple_dependency("only_amd64_linux_gnu")?;
    TestPackage::new(SimpleManifest {
        name: "foo".to_string(),
        version: "0.1.0".to_string(),
        license: Some(spdx::Expression::parse("GPL-3.0-or-later")?),
        license_file: None,
        authors: vec!["Jane Person <jane.person@example.com>".to_string()],
        repository: Some("https://example.com/foo.git".to_string()),
        dependencies: vec![
            (
                Some(Platform::Cfg(CfgExpr::Value(Cfg::Name(
                    "windows".to_string(),
                )))),
                dependency_only_windows,
            ),
            (
                Some(Platform::Cfg(CfgExpr::Value(Cfg::KeyPair(
                    "target_os".to_string(),
                    "linux".to_string(),
                )))),
                dependency_only_linux,
            ),
            (
                Some(Platform::Name("aarch64-apple-darwin".to_string())),
                dependency_only_aarch64_apple_darwin,
            ),
            (
                Some(Platform::Name("x86_64-unknown-linux-gnu".to_string())),
                dependency_only_amd64_linux_gnu,
            ),
        ]
        .into(),
        dev_dependencies: vec![].into(),
        build_dependencies: vec![].into(),
    })
}

fn dependency_names(licensing: &Licensing) -> HashSet<&str> {
    licensing
        .packages
        .iter()
        .map(|p| p.name.as_str())
        .collect::<HashSet<_>>()
}

#[test]
fn any() -> Result<()> {
    let pkg = fixture()?;

    let licensing = collect_from_manifest(
        pkg.manifest_path(),
        CollectConfig {
            platform: CollectPlatform::Any,
            ..Default::default()
        },
    )?;

    assert_eq!(
        dependency_names(&licensing),
        HashSet::from([
            "foo",
            "only_aarch64_apple_darwin",
            "only_amd64_linux_gnu",
            "only_linux",
            "only_windows",
        ])
    );

    Ok(())
}

#[test]
fn static_windows_pc() -> Result<()> {
    let pkg = fixture()?;

    let licensing = collect_from_manifest(
        pkg.manifest_path(),
        CollectConfig {
            platform: CollectPlatform::Static {
                target: "x86_64-pc-windows-gnu".to_string(),
                cfg: vec![
                    Cfg::Name("windows".to_string()),
                    Cfg::KeyPair("target_os".to_string(), "windows".to_string()),
                ],
            },
            ..Default::default()
        },
    )?;

    assert_eq!(
        dependency_names(&licensing),
        HashSet::from(["foo", "only_windows",])
    );

    Ok(())
}

#[test]
fn static_apple_arm() -> Result<()> {
    let pkg = fixture()?;

    let licensing = collect_from_manifest(
        pkg.manifest_path(),
        CollectConfig {
            platform: CollectPlatform::Static {
                target: "aarch64-apple-darwin".to_string(),
                cfg: vec![
                    Cfg::Name("unix".to_string()),
                    Cfg::KeyPair("target_os".to_string(), "macos".to_string()),
                ],
            },
            ..Default::default()
        },
    )?;

    assert_eq!(
        dependency_names(&licensing),
        HashSet::from(["foo", "only_aarch64_apple_darwin",])
    );

    Ok(())
}

#[test]
fn static_linux_pc() -> Result<()> {
    let pkg = fixture()?;

    let licensing = collect_from_manifest(
        pkg.manifest_path(),
        CollectConfig {
            platform: CollectPlatform::Static {
                target: "x86_64-unknown-linux-gnu".to_string(),
                cfg: vec![
                    Cfg::Name("unix".to_string()),
                    Cfg::KeyPair("target_os".to_string(), "linux".to_string()),
                ],
            },
            ..Default::default()
        },
    )?;

    assert_eq!(
        dependency_names(&licensing),
        HashSet::from(["foo", "only_amd64_linux_gnu", "only_linux",])
    );

    Ok(())
}

#[test]
fn static_linux_arm() -> Result<()> {
    let pkg = fixture()?;

    let licensing = collect_from_manifest(
        pkg.manifest_path(),
        CollectConfig {
            platform: CollectPlatform::Static {
                target: "aarch64-unknown-linux-gnu".to_string(),
                cfg: vec![
                    Cfg::Name("unix".to_string()),
                    Cfg::KeyPair("target_os".to_string(), "linux".to_string()),
                ],
            },
            ..Default::default()
        },
    )?;

    assert_eq!(
        dependency_names(&licensing),
        HashSet::from(["foo", "only_linux",])
    );

    Ok(())
}