diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cli.rs | 79 | ||||
-rw-r--r-- | src/config.rs | 17 | ||||
-rw-r--r-- | src/main.rs | 20 | ||||
-rw-r--r-- | src/pages/mod.rs | 4 | ||||
-rw-r--r-- | src/pages/repo/about.rs | 44 | ||||
-rw-r--r-- | src/pages/repo/details.rs | 37 | ||||
-rw-r--r-- | src/pages/repo/mod.rs | 14 | ||||
-rw-r--r-- | src/state/mod.rs | 14 | ||||
-rw-r--r-- | src/types/mod.rs | 30 |
9 files changed, 227 insertions, 32 deletions
diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..500a901 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,79 @@ +use clap::{App, Arg}; +use colored::Colorize; +use std::{ + env, + fs::File, + path::{Path, PathBuf}, +}; + +pub struct Paths { + pub config: File, + pub data: PathBuf, +} + +/// Initialise the application by getting valid path options +pub fn init() -> Paths { + let app = App::new("webgit") + .about("The friendly and simple git web frontend") + .version("0.0.0") + .arg( + Arg::with_name("CONFIG") + .short("c") + .long("config") + .takes_value(true) + .help( + "Provide the path to the system configuration. Alternatively \ + set WEBGIT_CONFIG_PATH in your env", + ), + ) + .arg( + Arg::with_name("DATA_DIR") + .short("d") + .long("data-dir") + .takes_value(true) + .help( + "Specify where webgit should save git repositories. Alternatively \ + set WEBGIT_DATA_DIR in your env", + ), + ); + + let matches = app.get_matches(); + + Paths { + config: File::open( + env::var_os("WEBGIT_CONFIG_PATH") + .map(|os| match os.into_string() { + Ok(p) => p.to_owned(), + Err(_) => { + eprintln!("{}: Failed to parse provided config path!", "Error:".red()); + std::process::exit(2); + } + }) + .unwrap_or_else(|| match matches.value_of("CONFIG") { + Some(p) => p.to_owned(), + None => { + eprintln!("{}: No config provided!", "Error:".red()); + std::process::exit(2); + } + }), + ) + .expect(&format!("{}: Config file not found!", "Error:".red())), + data: Path::new( + &env::var_os("WEBGIT_DATA_DIR") + .map(|os| { + os.into_string().expect(&format!( + "{}: Failed to parse provided data-dir path!", + "Error".red() + )) + }) + .unwrap_or_else(|| match matches.value_of("CONFIG") { + Some(p) => p.to_owned(), + None => { + eprintln!("{}: No data dir provided!", "Error:".red()); + std::process::exit(2); + } + }), + ) + .into(), + } +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..99e8cff --- /dev/null +++ b/src/config.rs @@ -0,0 +1,17 @@ +//! Configuration to run octopus + +pub struct Config { + app_path: String, + port: u16, + handle_ssl: bool, + cache_path: String, + repos_path: String, + repo_discovery: bool, + repos: Vec<RepoConfig> +} + +pub struct RepoConfig { + name: String, + description: String, + category: String, +} diff --git a/src/main.rs b/src/main.rs index d6a4b36..6d0ef79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,25 @@ mod pages; mod repo; +// mod router; +mod types; use actix_files as fs; use actix_web::{web, App, HttpServer}; use std::io; +use std::path::PathBuf; #[actix_rt::main] async fn main() -> io::Result<()> { - HttpServer::new(|| { + std::env::set_var("RUST_LOG", "actix_web=info"); + env_logger::init(); + let root = PathBuf::new(); + + HttpServer::new(move || { App::new() - .service(fs::Files::new("/static", "static")) - .service(web::resource("/{repo}").route(web::get().to(pages::repo::about::render))) - // default - .default_service( - // 404 for GET request - web::resource("").route(web::get().to(pages::p404::render)), - ) + .service(fs::Files::new("/static", root.join("static"))) + .service(web::resource("/{repo}").route(web::get().to(pages::repo::about))) + .service(web::resource("/{repo}/details").route(web::get().to(pages::repo::details))) + .default_service(web::resource("").route(web::get().to(pages::p404))) }) .bind("127.0.0.1:8080")? .run() diff --git a/src/pages/mod.rs b/src/pages/mod.rs index d53561b..f838eee 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -4,4 +4,6 @@ //! which is exported from the module and then called by the router pub mod repo; -pub mod p404; + +mod p404; +pub use p404::render as p404; diff --git a/src/pages/repo/about.rs b/src/pages/repo/about.rs index 8797edd..fa88eb1 100644 --- a/src/pages/repo/about.rs +++ b/src/pages/repo/about.rs @@ -1,35 +1,35 @@ +use super::RepoWrapper; +use crate::types::RepoData; use actix_web::{web, HttpRequest, HttpResponse, Result}; use askama::Template; #[derive(Template)] -#[template(path = "repo.html")] -struct Repo<'a> { - project_owner: &'a str, - project_summary: &'a str, - project_name: &'a str, - project_logo: &'a str, - project_logo_alt_text: &'a str, - first_commit: &'a str, - num_commits: usize, - num_contributors: usize, +#[template(path = "repo/about.html")] +struct AboutRepo { + repo: RepoWrapper, + readme: String, } /// Renders the "repository/about" subpage pub async fn render(req: HttpRequest, path: web::Path<String>) -> Result<HttpResponse> { - println!("Rendering path: {:#?}", path); - dbg!(req); - - let repo = Repo { - project_owner: "spacekookie", - project_summary: "A lightweight web frontend for git repositories", - project_name: "webgit", - project_logo: "rust.png", - project_logo_alt_text: "Rust logo", - first_commit: "f6ca929", - num_commits: 123, - num_contributors: 3, + let repo = AboutRepo { + readme: include_str!("../../../README").to_string(), + repo: RepoWrapper { + data: RepoData { + owner: "spacekookie".into(), + name: "octopus".into(), + tagline: "A lightweight web frontend for git repositories".into(), + num_commit: 141, + num_branch: 1, + num_tag: 0, + num_contributor: 3, + size: "13.12M".into(), + }, + logo: "fakeavi.png".into(), + }, } .render() .unwrap(); + Ok(HttpResponse::Ok().content_type("text/html").body(repo)) } diff --git a/src/pages/repo/details.rs b/src/pages/repo/details.rs new file mode 100644 index 0000000..4745e96 --- /dev/null +++ b/src/pages/repo/details.rs @@ -0,0 +1,37 @@ +use super::RepoWrapper; +use crate::types::{BranchData, CommitData, RepoData}; +use actix_web::{web, HttpRequest, HttpResponse, Result}; +use askama::Template; + +#[derive(Template)] +#[template(path = "repo/details.html")] +struct AboutRepo { + repo: RepoWrapper, + branches: Vec<BranchData>, + commits: Vec<CommitData>, +} + +/// Renders the "repository/about" subpage +pub async fn render(req: HttpRequest, path: web::Path<String>) -> Result<HttpResponse> { + let repo = AboutRepo { + branches: vec![], + commits: vec![], + repo: RepoWrapper { + data: RepoData { + owner: "spacekookie".into(), + name: "octopus".into(), + tagline: "A lightweight web frontend for git repositories".into(), + num_commit: 141, + num_branch: 1, + num_tag: 0, + num_contributor: 3, + size: "13.12M".into(), + }, + logo: "fakeavi.png".into(), + }, + } + .render() + .unwrap(); + + Ok(HttpResponse::Ok().content_type("text/html").body(repo)) +} diff --git a/src/pages/repo/mod.rs b/src/pages/repo/mod.rs index c339350..7d90c97 100644 --- a/src/pages/repo/mod.rs +++ b/src/pages/repo/mod.rs @@ -1,3 +1,15 @@ //! The repository page subtree -pub mod about; +mod about; +mod details; + +pub use about::render as about; +pub use details::render as details; + +use crate::types::RepoData; + +/// A template wrapper for repository data +pub(self) struct RepoWrapper { + pub(self) data: RepoData, + pub(self) logo: String, +} diff --git a/src/state/mod.rs b/src/state/mod.rs new file mode 100644 index 0000000..5e7f927 --- /dev/null +++ b/src/state/mod.rs @@ -0,0 +1,14 @@ +//! Core octopus state handling + +use std::sync::Arc; + +pub(crate) type StateRef = Arc<OctoState>; + +/// Holds all state handles for the application +pub(crate) struct OctoState {} + +impl OctoState { + pub(crate) fn new() -> StateRef { + Arc::new(Self {}) + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..d764b84 --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1,30 @@ +//! Octopus data types + +/// A simple overview of a repository +/// +/// This type can be generated by the octopus Repository state wrapper +pub(crate) struct RepoData { + pub owner: String, + pub name: String, + pub tagline: String, + pub num_commit: usize, + pub num_branch: usize, + pub num_tag: usize, + pub num_contributor: usize, + pub size: String, +} + +/// Data about an individual commit +pub(crate) struct CommitData { + pub hash: String, + pub message: String, + pub author: String, + pub date: String, + pub diff: (usize, usize), +} + +/// Data about a branch +pub(crate) struct BranchData { + pub name: String, + pub last_commit: CommitData, +} |