From eb1bd1b698ad4f5cab02933f245292a24dc524ca Mon Sep 17 00:00:00 2001 From: Sam Rijs Date: Sat, 27 Jan 2018 12:17:50 +1100 Subject: [PATCH] prepare for multi-crate repos --- src/api.rs | 24 ++++++++++++++++-------- src/engine/mod.rs | 20 ++++++++++++++++---- src/models/crates.rs | 2 +- src/parsers/manifest.rs | 11 ++++++++++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/api.rs b/src/api.rs index f41fbc1..75bc957 100644 --- a/src/api.rs +++ b/src/api.rs @@ -26,7 +26,7 @@ pub struct Api { impl Api { pub fn new(engine: Engine) -> Api { let mut router = Router::new(); - router.add("/api/v1/analyze/:site/:qual/:name", Route::AnalyzeDependencies); + router.add("/repo/:site/:qual/:name/dependencies.json", Route::AnalyzeDependencies); Api { engine, router: Arc::new(router) } } @@ -40,7 +40,7 @@ struct AnalyzeDependenciesResponseDetail { } #[derive(Debug, Serialize)] -struct AnalyzeDependenciesResponse { +struct AnalyzeDependenciesResponseSingle { dependencies: BTreeMap, #[serde(rename="dev-dependencies")] dev_dependencies: BTreeMap, @@ -48,6 +48,11 @@ struct AnalyzeDependenciesResponse { build_dependencies: BTreeMap } +#[derive(Debug, Serialize)] +struct AnalyzeDependenciesResponse { + crates: BTreeMap +} + impl Service for Api { type Request = Request; type Response = Response; @@ -96,30 +101,33 @@ impl Api { response.set_body(format!("{:?}", err)); future::Either::A(future::ok(response)) }, - Ok(dependencies) => { - let response_struct = AnalyzeDependenciesResponse { - dependencies: dependencies.main.into_iter() + Ok(analysis_outcome) => { + let single = AnalyzeDependenciesResponseSingle { + dependencies: analysis_outcome.deps.main.into_iter() .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { outdated: analyzed.is_outdated(), required: analyzed.required, latest: analyzed.latest })).collect(), - dev_dependencies: dependencies.dev.into_iter() + dev_dependencies: analysis_outcome.deps.dev.into_iter() .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { outdated: analyzed.is_outdated(), required: analyzed.required, latest: analyzed.latest })).collect(), - build_dependencies: dependencies.build.into_iter() + build_dependencies: analysis_outcome.deps.build.into_iter() .map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail { outdated: analyzed.is_outdated(), required: analyzed.required, latest: analyzed.latest })).collect() }; + let multi = AnalyzeDependenciesResponse { + crates: vec![(analysis_outcome.name.into(), single)].into_iter().collect() + }; let mut response = Response::new() .with_header(ContentType::json()) - .with_body(serde_json::to_string(&response_struct).unwrap()); + .with_body(serde_json::to_string(&multi).unwrap()); future::Either::B(future::ok(response)) } } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index a0eaacb..f559f0a 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -31,15 +31,20 @@ pub enum AnalyzeDependenciesError { const FETCH_RELEASES_CONCURRENCY: usize = 10; +pub struct AnalyzeDependenciesOutcome { + pub name: CrateName, + pub deps: AnalyzedDependencies +} + impl Engine { pub fn analyze_dependencies(&self, repo_path: RepoPath) -> - impl Future + impl Future { let manifest_future = self.retrieve_manifest(&repo_path); let engine = self.clone(); manifest_future.and_then(move |manifest| { - let CrateManifest::Crate(deps) = manifest; + let CrateManifest::Crate(crate_name, deps) = manifest; let analyzer = DependencyAnalyzer::new(&deps); let main_deps = deps.main.into_iter().map(|(name, _)| name); @@ -48,10 +53,17 @@ impl Engine { let release_futures = engine.fetch_releases(main_deps.chain(dev_deps).chain(build_deps)); - stream::iter_ok(release_futures) + let analyzed_deps_future = stream::iter_ok(release_futures) .buffer_unordered(FETCH_RELEASES_CONCURRENCY) .fold(analyzer, |mut analyzer, releases| { analyzer.process(releases); Ok(analyzer) }) - .map(|analyzer| analyzer.finalize()) + .map(|analyzer| analyzer.finalize()); + + analyzed_deps_future.map(move |analyzed_deps| { + AnalyzeDependenciesOutcome { + name: crate_name, + deps: analyzed_deps + } + }) }) } diff --git a/src/models/crates.rs b/src/models/crates.rs index c2dfc5c..03a4a37 100644 --- a/src/models/crates.rs +++ b/src/models/crates.rs @@ -96,5 +96,5 @@ impl AnalyzedDependencies { #[derive(Debug)] pub enum CrateManifest { - Crate(CrateDeps) + Crate(CrateName, CrateDeps) } diff --git a/src/parsers/manifest.rs b/src/parsers/manifest.rs index 125402b..cd1b813 100644 --- a/src/parsers/manifest.rs +++ b/src/parsers/manifest.rs @@ -26,8 +26,14 @@ enum CargoTomlDependency { Complex(CargoTomlComplexDependency) } +#[derive(Serialize, Deserialize, Debug)] +struct CargoTomlPackage { + name: String +} + #[derive(Serialize, Deserialize, Debug)] struct CargoToml { + package: CargoTomlPackage, #[serde(default)] dependencies: BTreeMap, #[serde(rename = "dev-dependencies")] @@ -65,6 +71,9 @@ pub fn parse_manifest_toml(input: &str) -> Result(input) .map_err(ManifestParseError::Serde)?; + let crate_name = cargo_toml.package.name.parse() + .map_err(ManifestParseError::Name)?; + let dependencies = cargo_toml.dependencies .into_iter().filter_map(convert_dependency).collect::, _>>()?; let dev_dependencies = cargo_toml.dev_dependencies @@ -78,5 +87,5 @@ pub fn parse_manifest_toml(input: &str) -> Result