1use 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 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}