diff --git a/Cargo.lock b/Cargo.lock
index ebd6ccc..b414955 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/config/default.toml b/config/default.toml
new file mode 100644
index 0000000..a727feb
--- /dev/null
+++ b/config/default.toml
@@ -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"
diff --git a/src/main.rs b/src/main.rs
index 91414f9..9aec316 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,11 +16,13 @@
* along with this program. If not, see .
*/
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]
diff --git a/src/settings.rs b/src/settings.rs
new file mode 100644
index 0000000..c216042
--- /dev/null
+++ b/src/settings.rs
@@ -0,0 +1,330 @@
+/*
+ * ForgeFlux StarChart - A federated software forge spider
+ * Copyright (C) 2022 Aravinth Manivannan
+ *
+ * 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 .
+ */
+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 {
+ 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 {
+ 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::("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::("database.database_type")
+ .expect("Couldn't access database database_type"),
+ s.get::("database.username")
+ .expect("Couldn't access database username"),
+ s.get::("database.password")
+ .expect("Couldn't access database password"),
+ s.get::("database.hostname")
+ .expect("Couldn't access database hostname"),
+ s.get::("database.port")
+ .expect("Couldn't access database port"),
+ s.get::("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());
+ }
+}