librepages/src/settings.rs
Aravinth Manivannan 325d110e9a
feat: switch to user configured branch even when configuration is changed
DESCRIPTION

Branch switching wasn't possible in earlier versions. If user deploys
"master" branch first and then wants to switch to "pages" branch, they
would have to delete the Pages-managed copy of the repository to
re-initialize the repository.

This patch introduces changes to switch to user configured branch on
startup and at each repository update.
2022-04-09 11:04:44 +05:30

118 lines
3.5 KiB
Rust

/*
* 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::env;
use std::path::Path;
use config::{Config, ConfigError, Environment, File};
use log::warn;
use serde::Deserialize;
use url::Url;
use crate::page::Page;
#[derive(Debug, Clone, Deserialize)]
pub struct Server {
pub port: u32,
pub ip: String,
pub workers: Option<usize>,
}
impl Server {
#[cfg(not(tarpaulin_include))]
pub fn get_ip(&self) -> String {
format!("{}:{}", self.ip, self.port)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct Settings {
pub server: Server,
pub source_code: String,
pub pages: Vec<Page>,
}
#[cfg(not(tarpaulin_include))]
impl Settings {
pub fn new() -> Result<Self, ConfigError> {
let mut s = Config::builder();
const CURRENT_DIR: &str = "./config/default.toml";
const ETC: &str = "/etc/static-pages/config.toml";
let mut read_file = false;
if Path::new(ETC).exists() {
s = s.add_source(File::with_name(ETC));
read_file = true;
}
if Path::new(CURRENT_DIR).exists() {
// merging default config from file
s = s.add_source(File::with_name(CURRENT_DIR));
read_file = true;
}
if let Ok(path) = env::var("PAGES_CONFIG") {
s = s.add_source(File::with_name(&path));
read_file = true;
}
if !read_file {
log::warn!("configuration file not found");
}
s = s.add_source(Environment::with_prefix("PAGES").separator("__"));
let mut settings = s.build()?.try_deserialize::<Settings>()?;
settings.check_url();
match env::var("PORT") {
Ok(val) => {
settings.server.port = val.parse().unwrap();
}
Err(e) => warn!("couldn't interpret PORT: {}", e),
}
for (index, page) in settings.pages.iter().enumerate() {
Url::parse(&page.repo).unwrap();
let path = Path::new(&page.path);
if path.exists() && path.is_file() {
panic!("Path is a file, should be a directory: {:?}", page);
}
if !path.exists() {
std::fs::create_dir_all(&path).unwrap();
}
for (index2, page2) in settings.pages.iter().enumerate() {
if index2 == index {
continue;
}
if page.secret == page2.secret || page.repo == page2.repo || page.path == page2.path
{
panic!("duplicate page onfiguration {:?} and {:?}", page, page2);
}
}
page.update();
}
Ok(settings)
}
#[cfg(not(tarpaulin_include))]
fn check_url(&self) {
Url::parse(&self.source_code).expect("Please enter a URL for source_code in settings");
}
}