sancus_lib/
settings.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6//
7// SPDX-License-Identifier: MIT OR Apache-2.0
8//
9// SPDX-FileCopyrightText: 2024 X-Software GmbH <opensource@x-software.com>
10
11use anyhow::{Context, Result};
12use serde::{Deserialize, Serialize};
13use std::path::Path;
14
15#[derive(Debug, Default, Serialize, Deserialize, Clone)]
16#[serde(rename_all = "snake_case")]
17pub struct LicenseFileOverride {
18    pub id: Option<String>,
19    pub file: String,
20}
21
22#[derive(Debug, Default, Serialize, Deserialize, Clone)]
23#[serde(default, rename_all = "snake_case")]
24pub struct Override {
25    pub package: String,
26    pub comment: String,
27    pub license_id: Option<String>,
28    pub overwrite_all_license_ids: bool,
29    pub license_files: Vec<LicenseFileOverride>,
30}
31
32#[derive(Debug, Default, Serialize, Deserialize, Clone)]
33#[serde(rename_all = "snake_case")]
34pub struct VcpkgIgnore {
35    pub directory: String,
36    pub comment: String,
37    pub os: Option<String>,
38}
39
40#[derive(Debug, Default, Serialize, Deserialize, Clone)]
41#[serde(rename_all = "snake_case")]
42pub struct LibIgnore {
43    pub lib: String,
44    pub comment: String,
45}
46
47#[derive(Debug, Default, Serialize, Deserialize, Clone)]
48#[serde(rename_all = "snake_case")]
49pub struct Settings {
50    #[serde(default = "default_overrides")]
51    pub overrides: Vec<Override>,
52    #[serde(default = "default_use_vcpkg_default_ignores")]
53    pub use_vcpkg_default_ignores: bool,
54    #[serde(default = "default_vcpkg_ignores")]
55    pub vcpkg_ignores: Vec<VcpkgIgnore>,
56    #[serde(default = "default_lib_ignores")]
57    pub lib_ignores: Vec<LibIgnore>,
58}
59
60fn default_overrides() -> Vec<Override> {
61    vec![]
62}
63
64fn default_use_vcpkg_default_ignores() -> bool {
65    true
66}
67
68fn default_vcpkg_ignores() -> Vec<VcpkgIgnore> {
69    vec![]
70}
71
72fn default_lib_ignores() -> Vec<LibIgnore> {
73    vec![]
74}
75
76impl Override {
77    pub fn find_override<'a>(package: &str, overrides: &'a [Self]) -> Option<&'a Self> {
78        overrides.iter().find(|&x| x.package == package)
79    }
80}
81
82impl Settings {
83    pub fn default_settings_file() -> std::path::PathBuf {
84        std::path::Path::new("sancus.yaml").to_path_buf()
85    }
86
87    pub fn load(file: &std::path::Path) -> Result<Self> {
88        let str = std::fs::read_to_string(file)
89            .with_context(|| format!("Cannot read settings file {}", file.to_str().unwrap_or("empty")).clone())?;
90        let mut settings = serde_yaml_bw::from_str::<Self>(str.as_str())
91            .with_context(|| format!("Cannot parse settings {}", file.to_str().unwrap_or("empty")).clone())?;
92
93        // Map relative license file overwrites to settings file:
94        let settings_path = file
95            .parent()
96            .unwrap_or_else(|| panic!("Cannot get directory of settings file {}", file.to_string_lossy()));
97        settings.overrides.iter_mut().for_each(|or| {
98            or.license_files.iter_mut().for_each(|lf| {
99                let file_path = Path::new(&lf.file);
100                if file_path.is_relative() {
101                    lf.file = settings_path.join(file_path).to_string_lossy().into_owned()
102                }
103            });
104        });
105        Ok(settings)
106    }
107}