kellnr_settings/
settings.rs1use std::convert::TryFrom;
2use std::path::{Path, PathBuf};
3
4use config::{Config, ConfigError, Environment, File};
5use serde::{Deserialize, Serialize};
6
7use crate::config_source::{SourceMap, init_default_sources};
8use crate::docs::Docs;
9use crate::local::Local;
10use crate::log::Log;
11use crate::oauth2::OAuth2;
12use crate::origin::Origin;
13use crate::postgresql::Postgresql;
14use crate::proxy::Proxy;
15use crate::registry::Registry;
16use crate::s3::S3;
17use crate::setup::Setup;
18use crate::toolchain::Toolchain;
19
20#[derive(Debug, Deserialize, Serialize, Eq, PartialEq, Clone)]
21#[serde(default)]
22pub struct Settings {
23 pub setup: Setup,
24 pub registry: Registry,
25 pub docs: Docs,
26 pub proxy: Proxy,
27 pub log: Log,
28 pub local: Local,
29 pub origin: Origin,
30 pub postgresql: Postgresql,
31 pub s3: S3,
32 pub oauth2: OAuth2,
33 pub toolchain: Toolchain,
34 #[serde(skip)]
37 pub sources: SourceMap,
38}
39
40impl Default for Settings {
41 fn default() -> Self {
42 Self {
43 setup: Setup::default(),
44 registry: Registry::default(),
45 docs: Docs::default(),
46 proxy: Proxy::default(),
47 log: Log::default(),
48 local: Local::default(),
49 origin: Origin::default(),
50 postgresql: Postgresql::default(),
51 s3: S3::default(),
52 oauth2: OAuth2::default(),
53 toolchain: Toolchain::default(),
54 sources: init_default_sources(),
55 }
56 }
57}
58
59impl TryFrom<Option<&Path>> for Settings {
60 type Error = ConfigError;
61
62 fn try_from(config_file: Option<&Path>) -> Result<Self, Self::Error> {
63 let mut builder = Config::builder();
64
65 if let Some(path) = config_file {
67 builder = builder.add_source(File::from(path).required(true));
68 }
69
70 builder = builder.add_source(
72 Environment::with_prefix("KELLNR")
73 .list_separator(",")
74 .with_list_parse_key("registry.required_crate_fields")
75 .with_list_parse_key("oauth2.scopes")
76 .try_parsing(true)
77 .prefix_separator("_")
78 .separator("__"),
79 );
80
81 builder.build()?.try_deserialize()
82 }
83}
84
85impl Settings {
86 pub fn bin_path(&self) -> PathBuf {
87 PathBuf::from(&self.registry.data_dir).join("crates")
88 }
89
90 pub fn doc_queue_path(&self) -> PathBuf {
91 PathBuf::from(&self.registry.data_dir).join("doc_queue")
92 }
93
94 pub fn sqlite_path(&self) -> PathBuf {
95 PathBuf::from(&self.registry.data_dir).join("db.sqlite")
96 }
97
98 pub fn docs_path(&self) -> PathBuf {
99 PathBuf::from(&self.registry.data_dir).join("docs")
100 }
101
102 pub fn base_path(&self) -> PathBuf {
103 PathBuf::from(&self.registry.data_dir).join("git")
104 }
105
106 pub fn crates_io_bin_path(&self) -> PathBuf {
107 PathBuf::from(&self.registry.data_dir).join("cratesio")
108 }
109
110 pub fn crates_io_path(&self) -> String {
111 format!("{}/cratesio", self.registry.data_dir)
112 }
113
114 pub fn crates_path(&self) -> String {
115 format!("{}/crates", self.registry.data_dir)
116 }
117
118 pub fn crates_path_or_bucket(&self) -> String {
119 if self.s3.enabled {
120 self.s3.crates_bucket.clone()
121 } else {
122 self.crates_path()
123 }
124 }
125
126 pub fn crates_io_path_or_bucket(&self) -> String {
127 if self.s3.enabled {
128 self.s3.cratesio_bucket.clone()
129 } else {
130 self.crates_io_path()
131 }
132 }
133
134 pub fn toolchain_path(&self) -> String {
135 format!("{}/toolchains", self.registry.data_dir)
136 }
137
138 pub fn toolchain_path_or_bucket(&self) -> String {
139 if self.s3.enabled {
140 self.s3.toolchain_bucket.clone()
141 } else {
142 self.toolchain_path()
143 }
144 }
145}
146
147pub fn get_settings() -> Result<Settings, ConfigError> {
148 let path = crate::compile_time_config::KELLNR_COMPTIME__CONFIG_FILE.map(Path::new);
149 Settings::try_from(path)
150}
151
152pub fn test_settings() -> Settings {
154 Settings {
155 registry: Registry {
156 data_dir: "/tmp/kdata_test".to_string(),
157 ..Registry::default()
158 },
159 sources: init_default_sources(),
160 ..Settings::default()
161 }
162}