Compare commits

...

19 Commits

Author SHA1 Message Date
c2d496f2b4 Add logger to test state
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-30 13:20:24 +01:00
19d37806f2 Remove unused import
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-30 13:11:05 +01:00
b4bd9b8830 Refactor to use slog for structured logging
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-30 13:03:06 +01:00
3c8227d0e9 Add slog dependencies 2020-10-30 13:02:53 +01:00
d6409c21ec Bump version (v0.14.3)
All checks were successful
continuous-integration/drone/tag Build is passing
2020-10-28 09:08:30 +01:00
990b5acbda Merge pull request #184 from vbrandl/dependabot/cargo/git2-0.13.12
Bump git2 from 0.13.11 to 0.13.12
2020-10-28 09:07:35 +01:00
f9e14e2ffd Bump git2 from 0.13.11 to 0.13.12
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.11 to 0.13.12.
- [Release notes](https://github.com/rust-lang/git2-rs/releases)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.11...0.13.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-28 08:05:44 +00:00
a73afe6851 Merge pull request #186 from vbrandl/dependabot/cargo/bytes-0.6.0
Bump bytes from 0.5.6 to 0.6.0
2020-10-28 09:04:22 +01:00
20544b27d9 Bump bytes from 0.5.6 to 0.6.0
Bumps [bytes](https://github.com/tokio-rs/bytes) from 0.5.6 to 0.6.0.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v0.5.6...v0.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-27 09:32:39 +00:00
288573b1a4 Merge pull request #178 from vbrandl/dependabot/cargo/actix-web-3.1.0
Bump actix-web from 3.0.2 to 3.1.0
2020-10-27 10:31:01 +01:00
a12755d7be Merge pull request #182 from vbrandl/dependabot/cargo/structopt-0.3.20
Bump structopt from 0.3.17 to 0.3.20
2020-10-27 09:10:24 +01:00
a248531ce2 Bump actix-web from 3.0.2 to 3.1.0
Bumps [actix-web](https://github.com/actix/actix-web) from 3.0.2 to 3.1.0.
- [Release notes](https://github.com/actix/actix-web/releases)
- [Changelog](https://github.com/actix/actix-web/blob/master/CHANGES.md)
- [Commits](https://github.com/actix/actix-web/compare/web-v3.0.2...web-v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-27 08:07:18 +00:00
de7919a031 Bump structopt from 0.3.17 to 0.3.20
Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.17 to 0.3.20.
- [Release notes](https://github.com/TeXitoi/structopt/releases)
- [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.17...v0.3.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-27 08:07:15 +00:00
3913039010 Merge pull request #183 from vbrandl/dependabot/cargo/serde_json-1.0.59
Bump serde_json from 1.0.57 to 1.0.59
2020-10-27 09:05:57 +01:00
078d3cdcf9 Merge pull request #185 from vbrandl/dependabot/cargo/serde-1.0.117
Bump serde from 1.0.116 to 1.0.117
2020-10-27 09:05:49 +01:00
c552a84870 Merge pull request #188 from vbrandl/dependabot/cargo/futures-0.3.7
Bump futures from 0.3.5 to 0.3.7
2020-10-27 09:05:37 +01:00
7c1a14b6ad Bump futures from 0.3.5 to 0.3.7
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.5 to 0.3.7.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.5...0.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-26 04:17:33 +00:00
c69b8207b8 Bump serde from 1.0.116 to 1.0.117
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-16 04:22:26 +00:00
a319f400e9 Bump serde_json from 1.0.57 to 1.0.59
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.57 to 1.0.59.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.57...v1.0.59)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-13 04:19:16 +00:00
6 changed files with 373 additions and 323 deletions

548
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,30 @@
[package]
name = "hoc"
version = "0.14.2"
version = "0.14.3"
authors = ["Valentin Brandl <vbrandl@riseup.net>"]
edition = "2018"
build = "build.rs"
[dependencies]
actix-web = "3.0.2"
actix-rt = "1.1.1"
actix-slog = "0.2.1"
actix-web = "3.1.0"
badge = "0.3.0"
bytes = "0.5.6"
futures = "0.3.5"
git2 = "0.13.11"
bytes = "0.6.0"
futures = "0.3.7"
git2 = "0.13.12"
lazy_static = "1.4.0"
log = "0.4.11"
log4rs = "0.13.0"
number_prefix = "0.4.0"
openssl-probe = "0.1.2"
reqwest = "0.10.8"
serde = "1.0.116"
serde = "1.0.117"
serde_derive = "1.0.103"
serde_json = "1.0.57"
structopt = "0.3.17"
actix-rt = "1.1.1"
serde_json = "1.0.59"
slog = "2.5.2"
slog-async = "2.5.0"
slog-atomic = "3.0.0"
slog-term = "2.6.0"
structopt = "0.3.20"
[build-dependencies]
ructe = "0.12.0"

View File

@ -1,10 +1,5 @@
use crate::{error::Result, statics::OPT};
use log::LevelFilter;
use log4rs::{
append::{console::ConsoleAppender, file::FileAppender},
config::{Appender, Config, Root},
encode::pattern::PatternEncoder,
};
use slog::{Drain, Logger};
use slog_atomic::AtomicSwitch;
use std::path::PathBuf;
use structopt::StructOpt;
@ -38,33 +33,28 @@ pub(crate) struct Opt {
#[structopt(short = "w", long = "workers", default_value = "4")]
/// Number of worker threads
pub(crate) workers: usize,
#[structopt(
short = "l",
long = "logfile",
parse(from_os_str),
default_value = "./hoc.log"
)]
/// The logfile
pub(crate) logfile: PathBuf,
// #[structopt(
// short = "l",
// long = "logfile",
// parse(from_os_str),
// default_value = "./hoc.log"
// )]
// /// The logfile
// pub(crate) logfile: PathBuf,
}
pub(crate) async fn init() -> Result<()> {
pub(crate) fn init() -> Logger {
std::env::set_var("RUST_LOG", "actix_web=info,hoc=info");
openssl_probe::init_ssl_cert_env_vars();
let stdout = ConsoleAppender::builder().build();
let file = FileAppender::builder()
.encoder(Box::new(PatternEncoder::new("{d} - {m}{n}")))
.build(&OPT.logfile)
.unwrap();
let config = Config::builder()
.appender(Appender::builder().build("stdout", Box::new(stdout)))
.appender(Appender::builder().build("file", Box::new(file)))
.build(
Root::builder()
.appender("stdout")
.appender("file")
.build(LevelFilter::Info),
)?;
log4rs::init_config(config)?;
Ok(())
let decorator = slog_term::PlainDecorator::new(std::io::stdout());
let drain = slog_term::FullFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let drain = AtomicSwitch::new(drain);
let root = Logger::root(drain, o!("version" => env!("CARGO_PKG_VERSION")));
info!(root, "Logging initialized");
root
}

View File

@ -14,8 +14,6 @@ pub(crate) enum Error {
Git(git2::Error),
Internal,
Io(std::io::Error),
Log(log::SetLoggerError),
LogBuilder(log4rs::config::Errors),
Parse(std::num::ParseIntError),
Serial(serde_json::Error),
BranchNotFound,
@ -29,8 +27,6 @@ impl fmt::Display for Error {
Error::Git(e) => write!(fmt, "Git({})", e),
Error::Internal => write!(fmt, "Internal Error"),
Error::Io(e) => write!(fmt, "Io({})", e),
Error::Log(e) => write!(fmt, "Log({})", e),
Error::LogBuilder(e) => write!(fmt, "LogBuilder({})", e),
Error::Parse(e) => write!(fmt, "Parse({})", e),
Error::Serial(e) => write!(fmt, "Serial({})", e),
Error::BranchNotFound => write!(fmt, "Repo doesn't have master branch"),
@ -76,12 +72,6 @@ impl From<git2::Error> for Error {
}
}
impl From<log::SetLoggerError> for Error {
fn from(err: log::SetLoggerError) -> Self {
Error::Log(err)
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::Io(err)
@ -100,12 +90,6 @@ impl From<reqwest::Error> for Error {
}
}
impl From<log4rs::config::Errors> for Error {
fn from(err: log4rs::config::Errors) -> Self {
Error::LogBuilder(err)
}
}
impl From<std::num::ParseIntError> for Error {
fn from(err: std::num::ParseIntError) -> Self {
Error::Parse(err)

View File

@ -4,10 +4,12 @@
extern crate actix_web;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
// #[macro_use]
// extern crate log;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate slog;
mod cache;
mod config;
@ -35,6 +37,7 @@ use actix_web::{
use badge::{Badge, BadgeOptions};
use git2::{BranchType, Repository};
use number_prefix::NumberPrefix;
use slog::Logger;
use std::{
borrow::Cow,
fs::create_dir_all,
@ -59,6 +62,7 @@ struct GeneratorForm<'a> {
pub(crate) struct State {
repos: String,
cache: String,
logger: Logger,
}
#[derive(Serialize)]
@ -81,7 +85,13 @@ fn pull(path: impl AsRef<Path>) -> Result<()> {
Ok(())
}
fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64, String, u64)> {
fn hoc(
repo: &str,
repo_dir: &str,
cache_dir: &str,
branch: &str,
logger: &Logger,
) -> Result<(u64, String, u64)> {
let repo_dir = format!("{}/{}", repo_dir, repo);
let cache_dir = format!("{}/{}.json", cache_dir, repo);
let cache_dir = Path::new(&cache_dir);
@ -108,16 +118,16 @@ fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64
let cache = CacheState::read_from_file(&cache_dir, branch, &head)?;
match &cache {
CacheState::Current { count, commits, .. } => {
info!("Using cache for {}", repo_dir);
info!(logger, "Using cache");
return Ok((*count, head, *commits));
}
CacheState::Old { head, .. } => {
info!("Updating cache for {}", repo_dir);
info!(logger, "Updating cache");
arg.push(format!("{}..{}", head, branch));
arg_commit_count.push(format!("{}..{}", head, branch));
}
CacheState::No | CacheState::NoneForBranch(..) => {
info!("Creating cache for {}", repo_dir);
info!(logger, "Creating cache");
arg.push(branch.to_string());
arg_commit_count.push(branch.to_string());
}
@ -180,13 +190,16 @@ where
T: Service,
{
let data = data.into_inner();
let logger = state
.logger
.new(o!("service" => T::domain(), "user" => data.0.clone(), "repo" => data.1.clone()));
let repo = format!(
"{}/{}/{}",
T::domain(),
data.0.to_lowercase(),
data.1.to_lowercase()
);
info!("Deleting cache and repository for {}", repo);
info!(logger, "Deleting cache and repository");
let cache_dir = format!("{}/{}.json", &state.cache, repo);
let repo_dir = format!("{}/{}", &state.repos, repo);
std::fs::remove_file(&cache_dir).or_else(|e| {
@ -223,6 +236,9 @@ where
F: Fn(HocResult) -> Result<HttpResponse>,
{
let data = data.into_inner();
let logger = state
.logger
.new(o!("service" => T::domain(), "user" => data.0.clone(), "repo" => data.1.clone(), "branch" => branch.to_string()));
let repo = format!("{}/{}", data.0.to_lowercase(), data.1.to_lowercase());
let service_path = format!("{}/{}", T::url_path(), repo);
let service_url = format!("{}/{}", T::domain(), repo);
@ -232,10 +248,10 @@ where
let file = Path::new(&path);
if !file.exists() {
if !remote_exists {
warn!("Repository does not exist: {}", url);
warn!(logger, "Repository does not exist");
return mapper(HocResult::NotFound);
}
info!("Cloning {} for the first time", url);
info!(logger, "Cloning for the first time");
create_dir_all(file)?;
let repo = Repository::init_bare(file)?;
repo.remote_add_fetch("origin", "refs/heads/*:refs/heads/*")?;
@ -243,7 +259,7 @@ where
REPO_COUNT.fetch_add(1, Ordering::Relaxed);
}
pull(&path)?;
let (hoc, head, commits) = hoc(&service_url, &state.repos, &state.cache, branch)?;
let (hoc, head, commits) = hoc(&service_url, &state.repos, &state.cache, branch, &logger)?;
let hoc_pretty = match NumberPrefix::decimal(hoc as f64) {
NumberPrefix::Standalone(hoc) => hoc.to_string(),
NumberPrefix::Prefixed(prefix, hoc) => format!("{:.1}{}", hoc, prefix),
@ -403,16 +419,19 @@ fn favicon32() -> HttpResponse {
HttpResponse::Ok().content_type("image/png").body(FAVICON)
}
async fn start_server() -> std::io::Result<()> {
async fn start_server(logger: Logger) -> std::io::Result<()> {
let interface = format!("{}:{}", OPT.host, OPT.port);
let state = Arc::new(State {
repos: OPT.outdir.display().to_string(),
cache: OPT.cachedir.display().to_string(),
logger,
});
HttpServer::new(move || {
App::new()
.data(state.clone())
.wrap(middleware::Logger::default())
.wrap(actix_slog::StructuredLogger::new(
state.logger.new(o!("log_type" => "access")),
))
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
.service(index)
.service(web::resource("/tacit-css.min.css").route(web::get().to(css)))
@ -450,6 +469,6 @@ async fn start_server() -> std::io::Result<()> {
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
config::init().await.unwrap();
start_server().await
let logger = config::init();
start_server(logger).await
}

View File

@ -23,7 +23,11 @@ macro_rules! test_service {
let cache_dir = dbg!(tempdir().unwrap());
let repos = format!("{}/", repo_dir.path().display());
let cache = format!("{}/", cache_dir.path().display());
let state = dbg!(State { repos, cache });
let state = dbg!(State {
repos,
cache,
logger: crate::config::init(),
});
let mut app = test_app!(state, web::resource($path).to($what::<T>));