feat: load settings from configuration file
This commit is contained in:
parent
68704573c6
commit
e37f335652
4 changed files with 545 additions and 89 deletions
266
Cargo.lock
generated
266
Cargo.lock
generated
|
@ -29,12 +29,6 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -59,6 +53,12 @@ dependencies = [
|
|||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.3.12"
|
||||
|
@ -197,7 +197,7 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -225,23 +225,26 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.12.0"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54ad70579325f1a38ea4c13412b82241c5900700a69785d73e2736bd65a33f86"
|
||||
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"json5",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"pathdiff",
|
||||
"ron",
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
"serde-hjson",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
|
@ -283,6 +286,19 @@ version = "2.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "0.4.3"
|
||||
|
@ -298,15 +314,6 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlv-list"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68df3f2b690c1b86e65ef7830956aededf3cb0a16f898f79b9a6f421a7b6211b"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.30"
|
||||
|
@ -495,15 +502,6 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
|
@ -637,6 +635,12 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "if_chain"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.18"
|
||||
|
@ -662,7 +666,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.11.2",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -707,23 +711,25 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json5"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.121"
|
||||
|
@ -793,12 +799,6 @@ version = "0.3.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
|
@ -852,12 +852,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.1"
|
||||
version = "5.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -876,7 +877,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -943,16 +953,6 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
|
||||
dependencies = [
|
||||
"dlv-list",
|
||||
"hashbrown 0.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
|
@ -985,12 +985,6 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
|
@ -1103,6 +1097,30 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
|
@ -1221,7 +1239,7 @@ dependencies = [
|
|||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile 0.3.0",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
|
@ -1261,24 +1279,18 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.7.0"
|
||||
name = "rust-ini"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags",
|
||||
"serde",
|
||||
]
|
||||
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.17.0"
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63471c4aa97a1cf8332a5f97709a79a4234698de6a1f5087faf66f2dae810e22"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"ordered-multimap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1387,6 +1399,18 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
|
@ -1396,6 +1420,18 @@ dependencies = [
|
|||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-hjson"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num-traits 0.1.43",
|
||||
"regex",
|
||||
"serde 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.136"
|
||||
|
@ -1415,7 +1451,7 @@ checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
|||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1427,7 +1463,7 @@ dependencies = [
|
|||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1500,17 +1536,26 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"actix-rt",
|
||||
"config",
|
||||
"derive_more",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
"serde_json",
|
||||
"tera",
|
||||
"tokio",
|
||||
"trust-dns-resolver",
|
||||
"url",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.89"
|
||||
|
@ -1552,7 +1597,7 @@ dependencies = [
|
|||
"pest_derive",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
"serde_json",
|
||||
"slug",
|
||||
"unic-segment",
|
||||
|
@ -1662,7 +1707,7 @@ version = "0.5.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde 1.0.136",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1859,6 +1904,49 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d0f08911ab0fee2c5009580f04615fa868898ee57de10692a45da0c3bcc3e5e"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde 1.0.136",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url",
|
||||
"validator_derive",
|
||||
"validator_types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator_derive"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d85135714dba11a1bd0b3eb1744169266f1a38977bf4e3ff5e2e1acb8c2b7eee"
|
||||
dependencies = [
|
||||
"if_chain",
|
||||
"lazy_static",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
"validator_types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator_types"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded9d97e1d42327632f5f3bae6403c04886e2de3036261ef42deebd931a6a291"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
36
config/default.toml
Normal file
36
config/default.toml
Normal file
|
@ -0,0 +1,36 @@
|
|||
log = "info" # possible values: "info", "warn", "trace", "error", "debug"
|
||||
source_code = "https://github.com/forgeflux-org/starchart"
|
||||
allow_new_index = true # allow registration on server
|
||||
admin_email = "admin@starchart.example.com"
|
||||
|
||||
[server]
|
||||
# The port at which you want authentication to listen to
|
||||
# takes a number, choose from 1000-10000 if you dont know what you are doing
|
||||
port = 7000
|
||||
#IP address. Enter 0.0.0.0 to listen on all availale addresses
|
||||
ip= "0.0.0.0"
|
||||
# enter your hostname, eg: example.com
|
||||
domain = "localhost"
|
||||
proxy_has_tls = false
|
||||
cookie_secret = "f12d9adf4e364648664442b8f50bf478e748e1d77c4797b2ec1f56803278"
|
||||
#workers = 2
|
||||
|
||||
[database]
|
||||
# This section deals with the database location and how to access it
|
||||
# Please note that at the moment, we have support for only postgresqa.
|
||||
# Example, if you are Batman, your config would be:
|
||||
# hostname = "batcave.org"
|
||||
# port = "5432"
|
||||
# username = "batman"
|
||||
# password = "somereallycomplicatedBatmanpassword"
|
||||
hostname = "localhost"
|
||||
port = "5432"
|
||||
username = "postgres"
|
||||
password = "password"
|
||||
name = "postgres"
|
||||
pool = 4
|
||||
database_type = "postgres"
|
||||
|
||||
|
||||
[repository]
|
||||
root = "/tmp/starchart.batsense.net"
|
|
@ -16,11 +16,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
pub mod gitea;
|
||||
pub mod settings;
|
||||
pub mod utils;
|
||||
pub mod verify;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
||||
pub const GIT_COMMIT_HASH: &str = env!("GIT_HASH");
|
||||
pub const DOMAIN: &str = "developer-starchart.forgeflux.org";
|
||||
|
||||
#[actix_rt::main]
|
||||
|
|
330
src/settings.rs
Normal file
330
src/settings.rs
Normal file
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* ForgeFlux StarChart - A federated software forge spider
|
||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
use std::path::Path;
|
||||
use std::{env, fs};
|
||||
|
||||
use config::{Config, ConfigError, Environment, File};
|
||||
use derive_more::Display;
|
||||
use log::warn;
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Server {
|
||||
pub port: u32,
|
||||
pub domain: String,
|
||||
pub ip: String,
|
||||
pub proxy_has_tls: bool,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub fn get_ip(&self) -> String {
|
||||
format!("{}:{}", self.ip, self.port)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Display, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum LogLevel {
|
||||
#[display(fmt = "debug")]
|
||||
Debug,
|
||||
#[display(fmt = "info")]
|
||||
Info,
|
||||
#[display(fmt = "trace")]
|
||||
Trace,
|
||||
#[display(fmt = "error")]
|
||||
Error,
|
||||
#[display(fmt = "warn")]
|
||||
Warn,
|
||||
}
|
||||
|
||||
impl LogLevel {
|
||||
fn set_log_level(&self) {
|
||||
const LOG_VAR: &str = "RUST_LOG";
|
||||
if env::var(LOG_VAR).is_err() {
|
||||
env::set_var("RUST_LOG", format!("{}", self));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Repository {
|
||||
pub root: String,
|
||||
}
|
||||
|
||||
impl Repository {
|
||||
fn create_root_dir(&self) {
|
||||
let root = Path::new(&self.root);
|
||||
if root.exists() {
|
||||
if !root.is_dir() {
|
||||
fs::remove_file(&root).unwrap();
|
||||
fs::create_dir_all(&root).unwrap();
|
||||
}
|
||||
} else {
|
||||
fs::create_dir_all(&root).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Display, PartialEq, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum DBType {
|
||||
#[display(fmt = "postgres")]
|
||||
Postgres,
|
||||
#[display(fmt = "sqlite")]
|
||||
Sqlite,
|
||||
}
|
||||
|
||||
impl DBType {
|
||||
fn from_url(url: &Url) -> Result<Self, ConfigError> {
|
||||
match url.scheme() {
|
||||
"sqlite" => Ok(Self::Sqlite),
|
||||
"postgres" => Ok(Self::Postgres),
|
||||
_ => Err(ConfigError::Message("Unknown database type".into())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct DatabaseBuilder {
|
||||
pub port: u32,
|
||||
pub hostname: String,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub name: String,
|
||||
pub database_type: DBType,
|
||||
}
|
||||
|
||||
impl DatabaseBuilder {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn extract_database_url(url: &Url) -> Self {
|
||||
log::debug!("Databse name: {}", url.path());
|
||||
let mut path = url.path().split('/');
|
||||
path.next();
|
||||
let name = path.next().expect("no database name").to_string();
|
||||
DatabaseBuilder {
|
||||
port: url.port().expect("Enter database port").into(),
|
||||
hostname: url.host().expect("Enter database host").to_string(),
|
||||
username: url.username().into(),
|
||||
password: url.password().expect("Enter database password").into(),
|
||||
name,
|
||||
database_type: DBType::from_url(url).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Database {
|
||||
pub url: String,
|
||||
pub pool: u32,
|
||||
pub database_type: DBType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Validate, Clone, Deserialize)]
|
||||
pub struct Settings {
|
||||
pub log: LogLevel,
|
||||
pub database: Database,
|
||||
pub allow_new_index: bool,
|
||||
pub server: Server,
|
||||
#[validate(url)]
|
||||
pub source_code: String,
|
||||
pub repository: Repository,
|
||||
#[validate(email)]
|
||||
pub admin_email: String,
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
impl Settings {
|
||||
fn set_source_code(&mut self) {
|
||||
if !self.source_code.ends_with('/') {
|
||||
self.source_code.push('/');
|
||||
}
|
||||
let mut base = url::Url::parse(&self.source_code).unwrap();
|
||||
base = base.join("tree/").unwrap();
|
||||
base = base.join(crate::GIT_COMMIT_HASH).unwrap();
|
||||
self.source_code = base.into();
|
||||
}
|
||||
|
||||
pub fn new() -> Result<Self, ConfigError> {
|
||||
let mut s = Config::new();
|
||||
|
||||
// setting default values
|
||||
#[cfg(test)]
|
||||
s.set_default("database.pool", 2.to_string())
|
||||
.expect("Couldn't get the number of CPUs");
|
||||
|
||||
const CURRENT_DIR: &str = "./config/default.toml";
|
||||
const ETC: &str = "/etc/starchart/config.toml";
|
||||
|
||||
if let Ok(path) = env::var("STARCHART_CONFIG") {
|
||||
s.merge(File::with_name(&path))?;
|
||||
} else if Path::new(CURRENT_DIR).exists() {
|
||||
// merging default config from file
|
||||
s.merge(File::with_name(CURRENT_DIR))?;
|
||||
} else if Path::new(ETC).exists() {
|
||||
s.merge(File::with_name(ETC))?;
|
||||
} else {
|
||||
log::warn!("configuration file not found");
|
||||
}
|
||||
|
||||
s.merge(Environment::with_prefix("STARCHART").separator("__"))?;
|
||||
|
||||
check_url(&s);
|
||||
|
||||
match env::var("PORT") {
|
||||
Ok(val) => {
|
||||
s.set("server.port", val).unwrap();
|
||||
}
|
||||
Err(e) => warn!("couldn't interpret PORT: {}", e),
|
||||
}
|
||||
|
||||
match env::var("DATABASE_URL") {
|
||||
Ok(val) => {
|
||||
let url = Url::parse(&val).expect("couldn't parse Database URL");
|
||||
let database_conf = DatabaseBuilder::extract_database_url(&url);
|
||||
set_from_database_url(&mut s, &database_conf);
|
||||
}
|
||||
Err(e) => warn!("couldn't interpret DATABASE_URL: {}", e),
|
||||
}
|
||||
|
||||
set_database_url(&mut s);
|
||||
|
||||
let mut settings: Settings = s.try_into()?;
|
||||
|
||||
settings.log.set_log_level();
|
||||
settings.repository.create_root_dir();
|
||||
settings.validate().unwrap();
|
||||
settings.set_source_code();
|
||||
settings.validate().unwrap();
|
||||
|
||||
Ok(settings)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn check_url(s: &Config) {
|
||||
let url = s
|
||||
.get::<String>("source_code")
|
||||
.expect("Couldn't access source_code");
|
||||
|
||||
Url::parse(&url).expect("Please enter a URL for source_code in settings");
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn set_from_database_url(s: &mut Config, database_conf: &DatabaseBuilder) {
|
||||
s.set("database.username", database_conf.username.clone())
|
||||
.expect("Couldn't set database username");
|
||||
s.set("database.password", database_conf.password.clone())
|
||||
.expect("Couldn't access database password");
|
||||
s.set("database.hostname", database_conf.hostname.clone())
|
||||
.expect("Couldn't access database hostname");
|
||||
s.set("database.port", database_conf.port as i64)
|
||||
.expect("Couldn't access database port");
|
||||
s.set("database.name", database_conf.name.clone())
|
||||
.expect("Couldn't access database name");
|
||||
s.set(
|
||||
"database.database_type",
|
||||
format!("{}", database_conf.database_type),
|
||||
)
|
||||
.expect("Couldn't access database type");
|
||||
}
|
||||
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn set_database_url(s: &mut Config) {
|
||||
s.set(
|
||||
"database.url",
|
||||
format!(
|
||||
r"{}://{}:{}@{}:{}/{}",
|
||||
s.get::<String>("database.database_type")
|
||||
.expect("Couldn't access database database_type"),
|
||||
s.get::<String>("database.username")
|
||||
.expect("Couldn't access database username"),
|
||||
s.get::<String>("database.password")
|
||||
.expect("Couldn't access database password"),
|
||||
s.get::<String>("database.hostname")
|
||||
.expect("Couldn't access database hostname"),
|
||||
s.get::<String>("database.port")
|
||||
.expect("Couldn't access database port"),
|
||||
s.get::<String>("database.name")
|
||||
.expect("Couldn't access database name")
|
||||
),
|
||||
)
|
||||
.expect("Couldn't set databse url");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::utils::get_random;
|
||||
|
||||
#[test]
|
||||
fn database_type_test() {
|
||||
for i in ["sqlite://foo", "postgres://bar", "unknown://"].iter() {
|
||||
let url = Url::parse(i).unwrap();
|
||||
if i.contains("sqlite") {
|
||||
assert_eq!(DBType::from_url(&url).unwrap(), DBType::Sqlite);
|
||||
} else if i.contains("unknown") {
|
||||
assert!(DBType::from_url(&url).is_err());
|
||||
} else {
|
||||
assert_eq!(DBType::from_url(&url).unwrap(), DBType::Postgres);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_dir_is_created_test() {
|
||||
let dir;
|
||||
loop {
|
||||
let mut tmp = env::temp_dir();
|
||||
tmp = tmp.join(get_random(10));
|
||||
|
||||
if tmp.exists() {
|
||||
continue;
|
||||
} else {
|
||||
dir = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let repo = Repository {
|
||||
root: dir.to_str().unwrap().to_owned(),
|
||||
};
|
||||
|
||||
repo.create_root_dir();
|
||||
assert!(dir.exists());
|
||||
assert!(dir.is_dir());
|
||||
let file = dir.join("foo");
|
||||
fs::write(&file, "foo").unwrap();
|
||||
repo.create_root_dir();
|
||||
assert!(dir.exists());
|
||||
assert!(dir.is_dir());
|
||||
|
||||
assert!(file.exists());
|
||||
assert!(file.is_file());
|
||||
|
||||
let repo = Repository {
|
||||
root: file.to_str().unwrap().to_owned(),
|
||||
};
|
||||
|
||||
repo.create_root_dir();
|
||||
assert!(file.exists());
|
||||
assert!(file.is_dir());
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue