mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-22 10:26:30 +00:00
welcome to 2018
This commit is contained in:
parent
67bb58710b
commit
1d5fdd5dc5
21 changed files with 783 additions and 765 deletions
1213
Cargo.lock
generated
1213
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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]
|
||||||
|
|
|
@ -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 {
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
.iter()
|
||||||
|
.fold((0, 0), |(outdated, total), &(_, ref deps)| {
|
||||||
(outdated + deps.count_outdated(), total + deps.count_total())
|
(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> {
|
||||||
|
self.query_crate
|
||||||
|
.call(name)
|
||||||
|
.from_err()
|
||||||
|
.map(move |query_response| {
|
||||||
|
query_response
|
||||||
|
.releases
|
||||||
|
.iter()
|
||||||
.filter(|release| req.matches(&release.version))
|
.filter(|release| req.matches(&release.version))
|
||||||
.max_by(|r1, r2| r1.version.cmp(&r2.version))
|
.max_by(|r1, r2| r1.version.cmp(&r2.version))
|
||||||
.cloned()
|
.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()
|
||||||
|
});
|
||||||
|
|
|
@ -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>()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
37
src/main.rs
37
src/main.rs
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue