1
0
Fork 0
mirror of https://codeberg.org/Mo8it/git-webhook-client synced 2024-10-18 07:22:39 +00:00

Use anyhow and simplelog

This commit is contained in:
Mo 2022-10-23 17:11:49 +02:00
parent 6e297455b9
commit fb23798d78
8 changed files with 75 additions and 35 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*.log
/Cargo.lock
/config.json
/db/

View file

@ -1,23 +1,27 @@
[package]
name = "git-webhook-client"
version = "0.1.0"
version = "0.2.0"
authors = ["Mo Bitar <mo8it@proton.me>"]
edition = "2021"
readme = "README.adoc"
license-file = "LICENSE"
repository = "https://codeberg.org/Mo8it/git-webhook-client"
license-file = "LICENSE.txt"
[dependencies]
chrono = "0.4.22"
diesel = { version = "2.0.2", features = [
anyhow = "1.0"
chrono = "0.4"
diesel = { version = "2.0", features = [
"r2d2",
"sqlite",
"returning_clauses_for_sqlite_3_35",
"without-deprecated",
] }
hex = "0.4.3"
hmac = "0.12.1"
hex = "0.4"
hmac = "0.12"
log = "0.4"
rocket = "0.5.0-rc.2"
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.87"
sha2 = "0.10.6"
serde_json = "1.0"
sha2 = "0.10"
simplelog = "0.12"

View file

@ -22,7 +22,7 @@ Currently, only Gitea is supported. If you want support for Gitlab or Github, th
=== Configuration
The program looks for the configuration file `config.json` that contains the following:
The program looks for the configuration file configured with the environment variable `GWC_CONFIG_FILE` that contains the following:
. `secret`: The secret of the webhook.
. `base_url`: The base_url of the webhook client.

View file

@ -1,7 +1,7 @@
use serde::Deserialize;
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
#[derive(Deserialize)]
pub struct Hook {
@ -15,19 +15,18 @@ pub struct Hook {
pub struct Config {
pub secret: String,
pub base_url: String,
pub log_file: String,
pub hooks: Vec<Hook>,
}
impl Config {
pub fn new() -> Self {
let config_path = Path::new("config.json");
let config_file = File::open(config_path).unwrap_or_else(|_| {
panic!(
"Can not open the config file at the path {}!",
config_path
.to_str()
.expect("Can not convert the config file path into a string")
)
let config_file_var = "GWC_CONFIG_FILE";
let config_path = env::var(config_file_var)
.unwrap_or_else(|_| panic!("Environment variable {config_file_var} missing!"));
let config_file = File::open(&config_path).unwrap_or_else(|e| {
panic!("Can not open the config file at the path {config_path}: {e}")
});
let config_reader = BufReader::new(config_file);
let config: Self =

View file

@ -1,6 +1,8 @@
use anyhow::{Context, Result};
use chrono::Local;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
use log::error;
use std::env;
use crate::config::Hook;
@ -10,8 +12,10 @@ use crate::schema::hooklog;
pub type DBPool = Pool<ConnectionManager<SqliteConnection>>;
pub fn establish_connection_pool() -> DBPool {
let database_url =
env::var("DATABASE_URL").expect("Environment variable DATABASE_URL missing!");
let database_url_var = "DATABASE_URL";
let database_url = env::var(database_url_var)
.unwrap_or_else(|_| panic!("Environment variable {database_url_var} missing!"));
let manager = ConnectionManager::<SqliteConnection>::new(&database_url);
Pool::builder()
@ -19,14 +23,11 @@ pub fn establish_connection_pool() -> DBPool {
.expect("Could not build database connection pool!")
}
fn get_conn(
pool: &DBPool,
) -> Result<PooledConnection<ConnectionManager<SqliteConnection>>, String> {
pool.get()
.map_err(|_| "Could not get database pool!".to_string())
fn get_conn(pool: &DBPool) -> Result<PooledConnection<ConnectionManager<SqliteConnection>>> {
pool.get().context("Could not get database pool!")
}
pub fn add_hook_log(pool: &DBPool, hook: &Hook) -> Result<HookLog, String> {
pub fn add_hook_log(pool: &DBPool, hook: &Hook) -> Result<HookLog> {
let conn = &mut get_conn(pool)?;
let command_with_args = hook.command.to_owned() + " " + &hook.args.join(" ");
@ -41,7 +42,7 @@ pub fn add_hook_log(pool: &DBPool, hook: &Hook) -> Result<HookLog, String> {
diesel::insert_into(hooklog::table)
.values(&new_hook_log)
.get_result::<HookLog>(conn)
.map_err(|e| e.to_string())
.context("Could not insert hook log!")
}
pub fn fill_hook_log(
@ -54,7 +55,7 @@ pub fn fill_hook_log(
let conn = &mut match get_conn(pool) {
Ok(pool) => pool,
Err(e) => {
println!("Error while trying to fill hook log: {e}");
error!("Could not get a database pool connection to fill hook log with id {hook_log_id}: {e}");
return;
}
};
@ -73,12 +74,12 @@ pub fn fill_hook_log(
{
Ok(_) => (),
Err(e) => {
println!("Could not update hook log: {e}");
error!("Could not update hook log with id {hook_log_id}: {e}");
}
};
}
pub fn get_hook_log(pool: &DBPool, id: i32) -> Result<HookLog, String> {
pub fn get_hook_log(pool: &DBPool, id: i32) -> Result<HookLog> {
// id=0 not allowed!
let conn = &mut get_conn(pool)?;
@ -92,5 +93,5 @@ pub fn get_hook_log(pool: &DBPool, id: i32) -> Result<HookLog, String> {
.first(conn)
};
hl.map_err(|e| e.to_string())
hl.context("Could not get hook log!")
}

29
src/logging.rs Normal file
View file

@ -0,0 +1,29 @@
use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode, WriteLogger};
use std::fs::OpenOptions;
use crate::config;
pub fn init_logger(config: &config::Config) {
let logger = if cfg!(debug_assertions) {
TermLogger::init(
LevelFilter::Debug,
simplelog::Config::default(),
TerminalMode::Mixed,
ColorChoice::Auto,
)
} else {
WriteLogger::init(
LevelFilter::Info,
simplelog::Config::default(),
OpenOptions::new()
.create(true)
.append(true)
.open(&config.log_file)
.unwrap_or_else(|e| {
panic!("Could not open the log file {}: {e}", &config.log_file)
}),
)
};
logger.expect("Could not initialize the logger!");
}

View file

@ -1,19 +1,27 @@
mod config;
mod db;
mod guards;
mod logging;
mod models;
mod routes;
mod schema;
mod states;
use log::info;
use rocket_dyn_templates::Template;
#[rocket::launch]
fn rocket() -> _ {
let config = config::Config::new();
logging::init_logger(&config);
info!("Starting client");
rocket::build()
.mount("/", rocket::routes![routes::index])
.mount("/api", rocket::routes![routes::trigger])
.manage(states::DB::new())
.manage(states::Config::new())
.manage(states::Config::new(config))
.attach(Template::fairing())
}

View file

@ -20,9 +20,7 @@ pub struct Config {
}
impl Config {
pub fn new() -> Self {
let config = config::Config::new();
pub fn new(config: config::Config) -> Self {
Self {
secret: config.secret.as_bytes().to_owned(),
base_url: config.base_url,