welcome to 2018

This commit is contained in:
Rob Ede 2020-09-28 23:48:26 +01:00
parent 67bb58710b
commit 1d5fdd5dc5
No known key found for this signature in database
GPG key ID: C2A3B36E841A91E6
21 changed files with 783 additions and 765 deletions

1213
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,7 @@
name = "shiny-robots" name = "shiny-robots"
version = "0.1.0" version = "0.1.0"
authors = ["Sam Rijs <srijs@airpost.net>"] authors = ["Sam Rijs <srijs@airpost.net>"]
edition = "2018"
[workspace] [workspace]
members = [ members = [
@ -35,6 +36,7 @@ tokio-core = "0.1.12"
tokio-service = "0.1.0" tokio-service = "0.1.0"
toml = "0.4.5" toml = "0.4.5"
try_future = "0.1.1" try_future = "0.1.1"
once_cell = "1.4"
[build-dependencies] [build-dependencies]

View file

@ -2,13 +2,13 @@ use failure::Error;
use futures::{Future, Poll, Stream}; use futures::{Future, Poll, Stream};
use futures::stream::futures_unordered; use futures::stream::futures_unordered;
use ::models::crates::{AnalyzedDependencies, CrateDeps}; use crate::models::crates::{AnalyzedDependencies, CrateDeps};
use super::super::Engine; use super::super::Engine;
use super::super::machines::analyzer::DependencyAnalyzer; use super::super::machines::analyzer::DependencyAnalyzer;
pub struct AnalyzeDependenciesFuture { pub struct AnalyzeDependenciesFuture {
inner: Box<Future<Item=AnalyzedDependencies, Error=Error>> inner: Box<dyn Future<Item=AnalyzedDependencies, Error=Error>>
} }
impl AnalyzeDependenciesFuture { impl AnalyzeDependenciesFuture {

View file

@ -1,11 +1,11 @@
use std::mem; use std::mem;
use failure::Error; use failure::Error;
use futures::{Async, Future, Poll, Stream}; use futures::{Async, Future, Poll, Stream, try_ready};
use futures::stream::FuturesOrdered; use futures::stream::FuturesOrdered;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use ::models::repo::RepoPath; use crate::models::repo::RepoPath;
use super::super::Engine; use super::super::Engine;
use super::super::machines::crawler::ManifestCrawler; use super::super::machines::crawler::ManifestCrawler;
@ -15,12 +15,12 @@ pub struct CrawlManifestFuture {
repo_path: RepoPath, repo_path: RepoPath,
engine: Engine, engine: Engine,
crawler: ManifestCrawler, crawler: ManifestCrawler,
futures: FuturesOrdered<Box<Future<Item=(RelativePathBuf, String), Error=Error>>> futures: FuturesOrdered<Box<dyn Future<Item=(RelativePathBuf, String), Error=Error>>>
} }
impl CrawlManifestFuture { impl CrawlManifestFuture {
pub fn new(engine: &Engine, repo_path: RepoPath, entry_point: RelativePathBuf) -> Self { pub fn new(engine: &Engine, repo_path: RepoPath, entry_point: RelativePathBuf) -> Self {
let future: Box<Future<Item=_, Error=_>> = Box::new(engine.retrieve_manifest_at_path(&repo_path, &entry_point) let future: Box<dyn Future<Item=_, Error=_>> = Box::new(engine.retrieve_manifest_at_path(&repo_path, &entry_point)
.map(move |contents| (entry_point, contents))); .map(move |contents| (entry_point, contents)));
let engine = engine.clone(); let engine = engine.clone();
let crawler = ManifestCrawler::new(); let crawler = ManifestCrawler::new();
@ -46,7 +46,7 @@ impl Future for CrawlManifestFuture {
Some((path, raw_manifest)) => { Some((path, raw_manifest)) => {
let output = self.crawler.step(path, raw_manifest)?; let output = self.crawler.step(path, raw_manifest)?;
for path in output.paths_of_interest.into_iter() { for path in output.paths_of_interest.into_iter() {
let future: Box<Future<Item=_, Error=_>> = Box::new(self.engine.retrieve_manifest_at_path(&self.repo_path, &path) let future: Box<dyn Future<Item=_, Error=_>> = Box::new(self.engine.retrieve_manifest_at_path(&self.repo_path, &path)
.map(move |contents| (path, contents))); .map(move |contents| (path, contents)));
self.futures.push(future); self.futures.push(future);
} }

View file

@ -3,7 +3,7 @@ use std::sync::Arc;
use rustsec::db::AdvisoryDatabase; use rustsec::db::AdvisoryDatabase;
use semver::Version; use semver::Version;
use ::models::crates::{CrateDeps, CrateRelease, CrateName, AnalyzedDependency, AnalyzedDependencies}; use crate::models::crates::{CrateDeps, CrateRelease, CrateName, AnalyzedDependency, AnalyzedDependencies};
pub struct DependencyAnalyzer { pub struct DependencyAnalyzer {
deps: AnalyzedDependencies, deps: AnalyzedDependencies,

View file

@ -4,8 +4,8 @@ use failure::Error;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use indexmap::IndexMap; use indexmap::IndexMap;
use ::parsers::manifest::parse_manifest_toml; use crate::parsers::manifest::parse_manifest_toml;
use ::models::crates::{CrateDep, CrateDeps, CrateName, CrateManifest}; use crate::models::crates::{CrateDep, CrateDeps, CrateName, CrateManifest};
pub struct ManifestCrawlerOutput { pub struct ManifestCrawlerOutput {
pub crates: IndexMap<CrateName, CrateDeps> pub crates: IndexMap<CrateName, CrateDeps>

View file

@ -5,32 +5,33 @@ use std::time::{Duration, Instant};
use cadence::prelude::*; use cadence::prelude::*;
use cadence::{MetricSink, NopMetricSink, StatsdClient}; use cadence::{MetricSink, NopMetricSink, StatsdClient};
use failure::Error; use failure::Error;
use futures::{Future, future};
use futures::future::join_all; use futures::future::join_all;
use hyper::Client; use futures::{future, Future};
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
use hyper::Client;
use hyper_tls::HttpsConnector; use hyper_tls::HttpsConnector;
use once_cell::sync::Lazy;
use relative_path::{RelativePath, RelativePathBuf}; use relative_path::{RelativePath, RelativePathBuf};
use rustsec::db::AdvisoryDatabase; use rustsec::db::AdvisoryDatabase;
use semver::VersionReq; use semver::VersionReq;
use slog::Logger; use slog::Logger;
use tokio_service::Service; use tokio_service::Service;
use crate::utils::cache::Cache;
use crate::models::crates::{AnalyzedDependencies, CrateName, CratePath, CrateRelease};
use crate::models::repo::{RepoPath, Repository};
use crate::interactors::crates::{GetPopularCrates, QueryCrate};
use crate::interactors::github::GetPopularRepos;
use crate::interactors::rustsec::FetchAdvisoryDatabase;
use crate::interactors::RetrieveFileAtPath;
mod fut;
mod machines; mod machines;
mod futures;
use ::utils::cache::Cache; use self::fut::AnalyzeDependenciesFuture;
use self::fut::CrawlManifestFuture;
use ::models::repo::{Repository, RepoPath};
use ::models::crates::{CrateName, CratePath, CrateRelease, AnalyzedDependencies};
use ::interactors::crates::{QueryCrate, GetPopularCrates};
use ::interactors::RetrieveFileAtPath;
use ::interactors::github::GetPopularRepos;
use ::interactors::rustsec::FetchAdvisoryDatabase;
use self::futures::AnalyzeDependenciesFuture;
use self::futures::CrawlManifestFuture;
type HttpClient = Client<HttpsConnector<HttpConnector>>; type HttpClient = Client<HttpsConnector<HttpConnector>>;
@ -44,7 +45,7 @@ pub struct Engine {
get_popular_crates: Arc<Cache<GetPopularCrates<HttpClient>>>, get_popular_crates: Arc<Cache<GetPopularCrates<HttpClient>>>,
get_popular_repos: Arc<Cache<GetPopularRepos<HttpClient>>>, get_popular_repos: Arc<Cache<GetPopularRepos<HttpClient>>>,
retrieve_file_at_path: Arc<RetrieveFileAtPath<HttpClient>>, retrieve_file_at_path: Arc<RetrieveFileAtPath<HttpClient>>,
fetch_advisory_db: Arc<Cache<FetchAdvisoryDatabase<HttpClient>>> fetch_advisory_db: Arc<Cache<FetchAdvisoryDatabase<HttpClient>>>,
} }
impl Engine { impl Engine {
@ -52,18 +53,26 @@ impl Engine {
let metrics = StatsdClient::from_sink("engine", NopMetricSink); let metrics = StatsdClient::from_sink("engine", NopMetricSink);
let query_crate = Cache::new(QueryCrate(client.clone()), Duration::from_secs(300), 500); let query_crate = Cache::new(QueryCrate(client.clone()), Duration::from_secs(300), 500);
let get_popular_crates = Cache::new(GetPopularCrates(client.clone()), Duration::from_secs(10), 1); let get_popular_crates =
let get_popular_repos = Cache::new(GetPopularRepos(client.clone()), Duration::from_secs(10), 1); Cache::new(GetPopularCrates(client.clone()), Duration::from_secs(10), 1);
let fetch_advisory_db = Cache::new(FetchAdvisoryDatabase(client.clone()), Duration::from_secs(300), 1); let get_popular_repos =
Cache::new(GetPopularRepos(client.clone()), Duration::from_secs(10), 1);
let fetch_advisory_db = Cache::new(
FetchAdvisoryDatabase(client.clone()),
Duration::from_secs(300),
1,
);
Engine { Engine {
client: client.clone(), logger, metrics, client: client.clone(),
logger,
metrics,
query_crate: Arc::new(query_crate), query_crate: Arc::new(query_crate),
get_popular_crates: Arc::new(get_popular_crates), get_popular_crates: Arc::new(get_popular_crates),
get_popular_repos: Arc::new(get_popular_repos), get_popular_repos: Arc::new(get_popular_repos),
retrieve_file_at_path: Arc::new(RetrieveFileAtPath(client)), retrieve_file_at_path: Arc::new(RetrieveFileAtPath(client)),
fetch_advisory_db: Arc::new(fetch_advisory_db) fetch_advisory_db: Arc::new(fetch_advisory_db),
} }
} }
@ -74,7 +83,7 @@ impl Engine {
pub struct AnalyzeDependenciesOutcome { pub struct AnalyzeDependenciesOutcome {
pub crates: Vec<(CrateName, AnalyzedDependencies)>, pub crates: Vec<(CrateName, AnalyzedDependencies)>,
pub duration: Duration pub duration: Duration,
} }
impl AnalyzeDependenciesOutcome { impl AnalyzeDependenciesOutcome {
@ -83,38 +92,42 @@ impl AnalyzeDependenciesOutcome {
} }
pub fn any_insecure(&self) -> bool { pub fn any_insecure(&self) -> bool {
self.crates.iter().any(|&(_, ref deps)| deps.count_insecure() > 0) self.crates
.iter()
.any(|&(_, ref deps)| deps.count_insecure() > 0)
} }
pub fn outdated_ratio(&self) -> (usize, usize) { pub fn outdated_ratio(&self) -> (usize, usize) {
self.crates.iter().fold((0, 0), |(outdated, total), &(_, ref deps)| { self.crates
(outdated + deps.count_outdated(), total + deps.count_total()) .iter()
}) .fold((0, 0), |(outdated, total), &(_, ref deps)| {
(outdated + deps.count_outdated(), total + deps.count_total())
})
} }
} }
impl Engine { impl Engine {
pub fn get_popular_repos(&self) -> pub fn get_popular_repos(&self) -> impl Future<Item = Vec<Repository>, Error = Error> {
impl Future<Item=Vec<Repository>, Error=Error> self.get_popular_repos.call(()).from_err().map(|repos| {
{ repos
self.get_popular_repos.call(()) .iter()
.from_err().map(|repos| { .filter(|repo| !POPULAR_REPO_BLOCK_LIST.contains(&repo.path))
repos.iter() .cloned()
.filter(|repo| !POPULAR_REPOS_BLACKLIST.contains(&repo.path)) .collect()
.cloned().collect() })
})
} }
pub fn get_popular_crates(&self) -> pub fn get_popular_crates(&self) -> impl Future<Item = Vec<CratePath>, Error = Error> {
impl Future<Item=Vec<CratePath>, Error=Error> self.get_popular_crates
{ .call(())
self.get_popular_crates.call(()) .from_err()
.from_err().map(|crates| crates.clone()) .map(|crates| crates.clone())
} }
pub fn analyze_repo_dependencies(&self, repo_path: RepoPath) -> pub fn analyze_repo_dependencies(
impl Future<Item=AnalyzeDependenciesOutcome, Error=Error> &self,
{ repo_path: RepoPath,
) -> impl Future<Item = AnalyzeDependenciesOutcome, Error = Error> {
let start = Instant::now(); let start = Instant::now();
let entry_point = RelativePath::new("/").to_relative_path_buf(); let entry_point = RelativePath::new("/").to_relative_path_buf();
@ -123,99 +136,125 @@ impl Engine {
let engine = self.clone(); let engine = self.clone();
manifest_future.and_then(move |manifest_output| { manifest_future.and_then(move |manifest_output| {
let engine_for_analyze = engine.clone(); let engine_for_analyze = engine.clone();
let futures = manifest_output.crates.into_iter().map(move |(crate_name, deps)| { let futures = manifest_output
let analyzed_deps_future = AnalyzeDependenciesFuture::new(engine_for_analyze.clone(), deps); .crates
.into_iter()
.map(move |(crate_name, deps)| {
let analyzed_deps_future =
AnalyzeDependenciesFuture::new(engine_for_analyze.clone(), deps);
analyzed_deps_future.map(move |analyzed_deps| (crate_name, analyzed_deps)) analyzed_deps_future.map(move |analyzed_deps| (crate_name, analyzed_deps))
}); });
join_all(futures).and_then(move |crates| { join_all(futures).and_then(move |crates| {
let duration = start.elapsed(); let duration = start.elapsed();
engine.metrics.time_duration_with_tags("analyze_duration", duration) engine
.metrics
.time_duration_with_tags("analyze_duration", duration)
.with_tag("repo_site", repo_path.site.as_ref()) .with_tag("repo_site", repo_path.site.as_ref())
.with_tag("repo_qual", repo_path.qual.as_ref()) .with_tag("repo_qual", repo_path.qual.as_ref())
.with_tag("repo_name", repo_path.name.as_ref()) .with_tag("repo_name", repo_path.name.as_ref())
.send()?; .send()?;
Ok(AnalyzeDependenciesOutcome { Ok(AnalyzeDependenciesOutcome { crates, duration })
crates, duration
})
}) })
}) })
} }
pub fn analyze_crate_dependencies(&self, crate_path: CratePath) -> pub fn analyze_crate_dependencies(
impl Future<Item=AnalyzeDependenciesOutcome, Error=Error> &self,
{ crate_path: CratePath,
) -> impl Future<Item = AnalyzeDependenciesOutcome, Error = Error> {
let start = Instant::now(); let start = Instant::now();
let query_future = self.query_crate.call(crate_path.name.clone()).from_err(); let query_future = self.query_crate.call(crate_path.name.clone()).from_err();
let engine = self.clone(); let engine = self.clone();
query_future.and_then(move |query_response| { query_future.and_then(move |query_response| {
match query_response.releases.iter().find(|release| release.version == crate_path.version) { match query_response
None => future::Either::A(future::err(format_err!("could not find crate release with version {}", crate_path.version))), .releases
.iter()
.find(|release| release.version == crate_path.version)
{
None => future::Either::A(future::err(format_err!(
"could not find crate release with version {}",
crate_path.version
))),
Some(release) => { Some(release) => {
let analyzed_deps_future = AnalyzeDependenciesFuture::new(engine.clone(), release.deps.clone()); let analyzed_deps_future =
AnalyzeDependenciesFuture::new(engine.clone(), release.deps.clone());
future::Either::B(analyzed_deps_future.map(move |analyzed_deps| { future::Either::B(analyzed_deps_future.map(move |analyzed_deps| {
let crates = vec![(crate_path.name, analyzed_deps)].into_iter().collect(); let crates = vec![(crate_path.name, analyzed_deps)].into_iter().collect();
let duration = start.elapsed(); let duration = start.elapsed();
AnalyzeDependenciesOutcome { AnalyzeDependenciesOutcome { crates, duration }
crates, duration
}
})) }))
} }
} }
}) })
} }
pub fn find_latest_crate_release(&self, name: CrateName, req: VersionReq) -> pub fn find_latest_crate_release(
impl Future<Item=Option<CrateRelease>, Error=Error> &self,
{ name: CrateName,
self.query_crate.call(name).from_err().map(move |query_response| { req: VersionReq,
query_response.releases.iter() ) -> impl Future<Item = Option<CrateRelease>, Error = Error> {
.filter(|release| req.matches(&release.version)) self.query_crate
.max_by(|r1, r2| r1.version.cmp(&r2.version)) .call(name)
.cloned() .from_err()
}) .map(move |query_response| {
query_response
.releases
.iter()
.filter(|release| req.matches(&release.version))
.max_by(|r1, r2| r1.version.cmp(&r2.version))
.cloned()
})
} }
fn fetch_releases<I: IntoIterator<Item=CrateName>>(&self, names: I) -> fn fetch_releases<I: IntoIterator<Item = CrateName>>(
impl Iterator<Item=impl Future<Item=Vec<CrateRelease>, Error=Error>> &self,
{ names: I,
) -> impl Iterator<Item = impl Future<Item = Vec<CrateRelease>, Error = Error>> {
let engine = self.clone(); let engine = self.clone();
names.into_iter().map(move |name| { names.into_iter().map(move |name| {
engine.query_crate.call(name) engine
.query_crate
.call(name)
.from_err() .from_err()
.map(|resp| resp.releases.clone()) .map(|resp| resp.releases.clone())
}) })
} }
fn retrieve_manifest_at_path(&self, repo_path: &RepoPath, path: &RelativePathBuf) -> fn retrieve_manifest_at_path(
impl Future<Item=String, Error=Error> &self,
{ repo_path: &RepoPath,
path: &RelativePathBuf,
) -> impl Future<Item = String, Error = Error> {
let manifest_path = path.join(RelativePath::new("Cargo.toml")); let manifest_path = path.join(RelativePath::new("Cargo.toml"));
self.retrieve_file_at_path.call((repo_path.clone(), manifest_path)) self.retrieve_file_at_path
.call((repo_path.clone(), manifest_path))
} }
fn fetch_advisory_db(&self) -> fn fetch_advisory_db(&self) -> impl Future<Item = Arc<AdvisoryDatabase>, Error = Error> {
impl Future<Item=Arc<AdvisoryDatabase>, Error=Error> self.fetch_advisory_db
{ .call(())
self.fetch_advisory_db.call(()).from_err().map(|db| db.clone()) .from_err()
.map(|db| db.clone())
} }
} }
lazy_static! { static POPULAR_REPO_BLOCK_LIST: Lazy<HashSet<RepoPath>> = Lazy::new(|| {
static ref POPULAR_REPOS_BLACKLIST: HashSet<RepoPath> = { vec![
vec![ RepoPath::from_parts("github", "rust-lang", "rust"),
RepoPath::from_parts("github", "rust-lang", "rust"), RepoPath::from_parts("github", "google", "xi-editor"),
RepoPath::from_parts("github", "google", "xi-editor"), RepoPath::from_parts("github", "lk-geimfari", "awesomo"),
RepoPath::from_parts("github", "lk-geimfari", "awesomo"), RepoPath::from_parts("github", "redox-os", "tfs"),
RepoPath::from_parts("github", "redox-os", "tfs"), RepoPath::from_parts("github", "carols10cents", "rustlings"),
RepoPath::from_parts("github", "carols10cents", "rustlings"), RepoPath::from_parts("github", "rust-unofficial", "awesome-rust"),
RepoPath::from_parts("github", "rust-unofficial", "awesome-rust") ]
].into_iter().collect::<Result<HashSet<_>, _>>().unwrap() .into_iter()
}; .collect::<Result<HashSet<_>, _>>()
} .unwrap()
});

View file

@ -2,7 +2,7 @@ use failure::Error;
use hyper::Uri; use hyper::Uri;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use ::models::repo::RepoPath; use crate::models::repo::RepoPath;
const BITBUCKET_USER_CONTENT_BASE_URI: &'static str = "https://bitbucket.org"; const BITBUCKET_USER_CONTENT_BASE_URI: &'static str = "https://bitbucket.org";
@ -15,4 +15,3 @@ pub fn get_manifest_uri(repo_path: &RepoPath, path: &RelativePathBuf) -> Result<
path_str path_str
).parse::<Uri>()?) ).parse::<Uri>()?)
} }

View file

@ -7,7 +7,7 @@ use tokio_service::Service;
use semver::{Version, VersionReq}; use semver::{Version, VersionReq};
use serde_json; use serde_json;
use ::models::crates::{CrateName, CrateRelease, CrateDeps, CrateDep, CratePath}; use crate::models::crates::{CrateName, CrateRelease, CrateDeps, CrateDep, CratePath};
const CRATES_INDEX_BASE_URI: &str = "https://raw.githubusercontent.com/rust-lang/crates.io-index"; const CRATES_INDEX_BASE_URI: &str = "https://raw.githubusercontent.com/rust-lang/crates.io-index";
const CRATES_API_BASE_URI: &str = "https://crates.io/api/v1"; const CRATES_API_BASE_URI: &str = "https://crates.io/api/v1";
@ -68,7 +68,7 @@ impl<S> Service for QueryCrate<S>
type Request = CrateName; type Request = CrateName;
type Response = QueryCrateResponse; type Response = QueryCrateResponse;
type Error = Error; type Error = Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; type Future = Box<dyn Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, crate_name: CrateName) -> Self::Future { fn call(&self, crate_name: CrateName) -> Self::Future {
let lower_name = crate_name.as_ref().to_lowercase(); let lower_name = crate_name.as_ref().to_lowercase();
@ -137,7 +137,7 @@ impl<S> Service for GetPopularCrates<S>
type Request = (); type Request = ();
type Response = Vec<CratePath>; type Response = Vec<CratePath>;
type Error = Error; type Error = Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; type Future = Box<dyn Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, _req: ()) -> Self::Future { fn call(&self, _req: ()) -> Self::Future {
let service = self.0.clone(); let service = self.0.clone();

View file

@ -6,7 +6,7 @@ use relative_path::RelativePathBuf;
use tokio_service::Service; use tokio_service::Service;
use serde_json; use serde_json;
use ::models::repo::{Repository, RepoPath}; use crate::models::repo::{Repository, RepoPath};
const GITHUB_API_BASE_URI: &'static str = "https://api.github.com"; const GITHUB_API_BASE_URI: &'static str = "https://api.github.com";
const GITHUB_USER_CONTENT_BASE_URI: &'static str = "https://raw.githubusercontent.com"; const GITHUB_USER_CONTENT_BASE_URI: &'static str = "https://raw.githubusercontent.com";
@ -48,7 +48,7 @@ impl<S> Service for GetPopularRepos<S>
type Request = (); type Request = ();
type Response = Vec<Repository>; type Response = Vec<Repository>;
type Error = Error; type Error = Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; type Future = Box<dyn Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, _req: ()) -> Self::Future { fn call(&self, _req: ()) -> Self::Future {
let uri = try_future_box!(format!("{}/search/repositories?q=language:rust&sort=stars", GITHUB_API_BASE_URI) let uri = try_future_box!(format!("{}/search/repositories?q=language:rust&sort=stars", GITHUB_API_BASE_URI)

View file

@ -2,7 +2,7 @@ use hyper::Uri;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use failure::Error; use failure::Error;
use ::models::repo::RepoPath; use crate::models::repo::RepoPath;
const GITLAB_USER_CONTENT_BASE_URI: &'static str = "https://gitlab.com"; const GITLAB_USER_CONTENT_BASE_URI: &'static str = "https://gitlab.com";

View file

@ -4,7 +4,7 @@ use hyper::{Error as HyperError, Method, Request, Response};
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use tokio_service::Service; use tokio_service::Service;
use ::models::repo::{RepoSite, RepoPath}; use crate::models::repo::{RepoSite, RepoPath};
pub mod bitbucket; pub mod bitbucket;
pub mod crates; pub mod crates;
@ -22,7 +22,7 @@ impl<S> Service for RetrieveFileAtPath<S>
type Request = (RepoPath, RelativePathBuf); type Request = (RepoPath, RelativePathBuf);
type Response = String; type Response = String;
type Error = Error; type Error = Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; type Future = Box<dyn Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, req: Self::Request) -> Self::Future { fn call(&self, req: Self::Request) -> Self::Future {
let (repo_path, path) = req; let (repo_path, path) = req;
@ -54,5 +54,3 @@ impl<S> Service for RetrieveFileAtPath<S>
})) }))
} }
} }

View file

@ -18,7 +18,7 @@ impl<S> Service for FetchAdvisoryDatabase<S>
type Request = (); type Request = ();
type Response = Arc<AdvisoryDatabase>; type Response = Arc<AdvisoryDatabase>;
type Error = Error; type Error = Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; type Future = Box<dyn Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, _req: ()) -> Self::Future { fn call(&self, _req: ()) -> Self::Future {
let service = self.0.clone(); let service = self.0.clone();

View file

@ -1,43 +1,17 @@
#![allow(bare_trait_objects)] #![deny(bare_trait_objects)]
#![allow(unused)]
extern crate badge;
extern crate cadence;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
#[macro_use] #[macro_use]
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate indexmap;
#[macro_use]
extern crate lazy_static; extern crate lazy_static;
extern crate lru_cache;
extern crate maud;
extern crate relative_path;
extern crate route_recognizer;
extern crate rustsec;
extern crate semver;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate shared_failure;
#[macro_use] #[macro_use]
extern crate slog; extern crate slog;
extern crate slog_json;
extern crate tokio_core;
extern crate tokio_service;
extern crate toml;
#[macro_use] #[macro_use]
extern crate try_future; extern crate try_future;
mod engine;
mod interactors;
mod models;
mod parsers;
mod server;
mod utils;
use std::env; use std::env;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use std::sync::Mutex; use std::sync::Mutex;
@ -50,6 +24,13 @@ use hyper_tls::HttpsConnector;
use slog::Drain; use slog::Drain;
use tokio_core::reactor::Core; use tokio_core::reactor::Core;
mod engine;
mod interactors;
mod models;
mod parsers;
mod server;
mod utils;
use self::engine::Engine; use self::engine::Engine;
use self::server::Server; use self::server::Server;

View file

@ -4,7 +4,7 @@ use relative_path::RelativePathBuf;
use semver::VersionReq; use semver::VersionReq;
use toml; use toml;
use ::models::crates::{CrateName, CrateDep, CrateDeps, CrateManifest}; use crate::models::crates::{CrateName, CrateDep, CrateDeps, CrateManifest};
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct CargoTomlComplexDependency { struct CargoTomlComplexDependency {

View file

@ -12,10 +12,10 @@ use tokio_service::Service;
mod assets; mod assets;
mod views; mod views;
use ::engine::{Engine, AnalyzeDependenciesOutcome}; use crate::engine::{Engine, AnalyzeDependenciesOutcome};
use ::models::crates::{CrateName, CratePath}; use crate::models::crates::{CrateName, CratePath};
use ::models::repo::RepoPath; use crate::models::repo::RepoPath;
use ::models::SubjectPath; use crate::models::SubjectPath;
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
enum StatusFormat { enum StatusFormat {
@ -68,7 +68,7 @@ impl Service for Server {
type Request = Request; type Request = Request;
type Response = Response; type Response = Response;
type Error = HyperError; type Error = HyperError;
type Future = Box<Future<Item=Response, Error=HyperError>>; type Future = Box<dyn Future<Item=Response, Error=HyperError>>;
fn call(&self, req: Request) -> Self::Future { fn call(&self, req: Request) -> Self::Future {
let logger = self.logger.new(o!("http_path" => req.uri().path().to_owned())); let logger = self.logger.new(o!("http_path" => req.uri().path().to_owned()));

View file

@ -2,7 +2,7 @@ use badge::{Badge, BadgeOptions};
use hyper::Response; use hyper::Response;
use hyper::header::ContentType; use hyper::header::ContentType;
use ::engine::AnalyzeDependenciesOutcome; use crate::engine::AnalyzeDependenciesOutcome;
pub fn badge(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Badge { pub fn badge(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Badge {
let opts = match analysis_outcome { let opts = match analysis_outcome {

View file

@ -1,8 +1,8 @@
use hyper::Response; use hyper::Response;
use maud::{Markup, html}; use maud::{Markup, html};
use ::models::repo::Repository; use crate::models::repo::Repository;
use ::models::crates::CratePath; use crate::models::crates::CratePath;
fn popular_table(popular_repos: Vec<Repository>, popular_crates: Vec<CratePath>) -> Markup { fn popular_table(popular_repos: Vec<Repository>, popular_crates: Vec<CratePath>) -> Markup {
html! { html! {

View file

@ -2,10 +2,10 @@ use hyper::Response;
use maud::{Markup, html}; use maud::{Markup, html};
use indexmap::IndexMap; use indexmap::IndexMap;
use ::engine::AnalyzeDependenciesOutcome; use crate::engine::AnalyzeDependenciesOutcome;
use ::models::crates::{CrateName, AnalyzedDependency, AnalyzedDependencies}; use crate::models::crates::{CrateName, AnalyzedDependency, AnalyzedDependencies};
use ::models::SubjectPath; use crate::models::SubjectPath;
use ::models::repo::RepoSite; use crate::models::repo::RepoSite;
use super::super::badge; use super::super::badge;

View file

@ -88,7 +88,7 @@ impl<F: Future<Error=Error>> Future for Cached<F> {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.0.poll() self.0.poll()
.map_err(|err| (*err).clone()) .map_err(|err| (*err).clone())
.map(|async| async.map(CachedItem)) .map(|_async| _async.map(CachedItem))
} }
} }