parent
ccb0ac9d09
commit
2d9d511bb8
5 changed files with 240 additions and 0 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -1611,9 +1611,11 @@ dependencies = [
|
|||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sqlx",
|
||||
"tera",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
"url",
|
||||
|
@ -2158,6 +2160,19 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.0"
|
||||
|
@ -2732,6 +2747,12 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
|
|
|
@ -48,6 +48,8 @@ rust-embed = "6.3.0"
|
|||
rand = "0.8.5"
|
||||
tracing = { version = "0.1.37", features = ["log"]}
|
||||
tracing-actix-web = "0.6.2"
|
||||
toml = "0.5.9"
|
||||
serde_yaml = "0.9.14"
|
||||
|
||||
[dependencies.cache-buster]
|
||||
git = "https://github.com/realaravinth/cache-buster"
|
||||
|
|
|
@ -34,6 +34,7 @@ mod errors;
|
|||
mod git;
|
||||
mod meta;
|
||||
mod page;
|
||||
mod page_config;
|
||||
mod pages;
|
||||
mod preview;
|
||||
mod serve;
|
||||
|
|
198
src/page_config.rs
Normal file
198
src/page_config.rs
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* 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 serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::git::{ContentType, GitFileMode};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Config {
|
||||
pub source: Source,
|
||||
pub domains: Option<Vec<String>>,
|
||||
pub forms: Option<Forms>,
|
||||
pub image_compression: Option<ImageCompression>,
|
||||
pub redirects: Option<Vec<Redirects>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct Source {
|
||||
production_branch: String,
|
||||
staging: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct Forms {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct ImageCompression {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct Redirects {
|
||||
pub from: String,
|
||||
pub to: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Serialize, PartialEq, Eq)]
|
||||
struct Policy<'a> {
|
||||
rel_path: &'a str,
|
||||
format: SupportedFormat,
|
||||
}
|
||||
|
||||
impl<'a> Policy<'a> {
|
||||
const fn new(rel_path: &'a str, format: SupportedFormat) -> Self {
|
||||
Self { rel_path, format }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Serialize, PartialEq, Eq)]
|
||||
enum SupportedFormat {
|
||||
Json,
|
||||
Yaml,
|
||||
Toml,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load<P: AsRef<Path>>(repo_path: &P, branch: &str) -> Option<Config> {
|
||||
const POLICIES: [Policy; 2] = [
|
||||
Policy::new("librepages.toml", SupportedFormat::Toml),
|
||||
Policy::new("librepages.json", SupportedFormat::Json),
|
||||
];
|
||||
|
||||
if let Some(policy) = Self::discover(repo_path, branch, &POLICIES) {
|
||||
// let path = p.repo.as_ref().join(policy.rel_path);
|
||||
//let contents = fs::read_to_string(path).await.unwrap();
|
||||
|
||||
let file =
|
||||
crate::git::read_preview_file(&repo_path.as_ref().into(), branch, policy.rel_path)
|
||||
.unwrap();
|
||||
if let ContentType::Text(contents) = file.content {
|
||||
let res = match policy.format {
|
||||
SupportedFormat::Json => Self::load_json(&contents),
|
||||
SupportedFormat::Yaml => Self::load_yaml(&contents),
|
||||
SupportedFormat::Toml => Self::load_toml(&contents),
|
||||
};
|
||||
|
||||
return Some(res);
|
||||
};
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
fn discover<'a, P: AsRef<Path>>(
|
||||
repo_path: &P,
|
||||
branch: &str,
|
||||
policies: &'a [Policy<'a>],
|
||||
) -> Option<&'a Policy<'a>> {
|
||||
let repo = git2::Repository::open(&repo_path).unwrap();
|
||||
|
||||
let branch = repo.find_branch(&branch, git2::BranchType::Local).unwrap();
|
||||
// let tree = head.peel_to_tree().unwrap();
|
||||
let branch = branch.into_reference();
|
||||
let tree = branch.peel_to_tree().unwrap();
|
||||
|
||||
for p in policies.iter() {
|
||||
let file_exists = tree.iter().any(|x| {
|
||||
if let Some(name) = x.name() {
|
||||
if policies.iter().any(|p| p.rel_path == name) {
|
||||
let mode: GitFileMode = x.into();
|
||||
match mode {
|
||||
GitFileMode::Executable | GitFileMode::Regular => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
if file_exists {
|
||||
return Some(p);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn load_toml(c: &str) -> Config {
|
||||
toml::from_str(c).unwrap()
|
||||
}
|
||||
|
||||
fn load_yaml(c: &str) -> Config {
|
||||
serde_yaml::from_str(c).unwrap()
|
||||
}
|
||||
|
||||
fn load_json(c: &str) -> Config {
|
||||
serde_json::from_str(&c).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::git::tests::write_file_util;
|
||||
use mktemp::Temp;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn page_config_test() {
|
||||
let tmp_dir = Temp::new_dir().unwrap();
|
||||
let repo_path = tmp_dir.join("page_config_test");
|
||||
|
||||
let content = std::fs::read_to_string(
|
||||
&Path::new("./tests/cases/contains-everything/toml/librepages.toml")
|
||||
.canonicalize()
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
write_file_util(
|
||||
repo_path.to_str().unwrap(),
|
||||
"librepages.toml",
|
||||
Some(&content),
|
||||
);
|
||||
|
||||
let config = Config::load(&repo_path, "master").unwrap();
|
||||
assert!(config.forms.as_ref().unwrap().enable);
|
||||
assert!(config.image_compression.as_ref().unwrap().enable);
|
||||
assert_eq!(config.source.production_branch, "librepages");
|
||||
assert_eq!(config.source.staging.as_ref().unwrap(), "beta");
|
||||
|
||||
assert_eq!(
|
||||
config.redirects.as_ref().unwrap(),
|
||||
&vec![
|
||||
Redirects {
|
||||
from: "/from1".into(),
|
||||
to: "/to1".into()
|
||||
},
|
||||
Redirects {
|
||||
from: "/from2".into(),
|
||||
to: "/to2".into()
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
config.domains.as_ref().unwrap(),
|
||||
&vec!["example.org".to_string(), "example.com".to_string(),]
|
||||
);
|
||||
}
|
||||
}
|
18
tests/cases/contains-everything/toml/librepages.toml
Normal file
18
tests/cases/contains-everything/toml/librepages.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
domains = [
|
||||
"example.org",
|
||||
"example.com",
|
||||
]
|
||||
redirects = [
|
||||
{from = "/from1", to = "/to1"},
|
||||
{from = "/from2", to = "/to2"},
|
||||
]
|
||||
|
||||
[source]
|
||||
production_branch = "librepages"
|
||||
staging = "beta"
|
||||
|
||||
[forms]
|
||||
enable = true
|
||||
|
||||
[image_compression]
|
||||
enable = true
|
Loading…
Reference in a new issue