mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-22 10:26:30 +00:00
prepare for multi-crate repos
This commit is contained in:
parent
28f5cf7ba2
commit
eb1bd1b698
4 changed files with 43 additions and 14 deletions
24
src/api.rs
24
src/api.rs
|
@ -26,7 +26,7 @@ pub struct Api {
|
||||||
impl Api {
|
impl Api {
|
||||||
pub fn new(engine: Engine) -> Api {
|
pub fn new(engine: Engine) -> Api {
|
||||||
let mut router = Router::new();
|
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) }
|
Api { engine, router: Arc::new(router) }
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ struct AnalyzeDependenciesResponseDetail {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct AnalyzeDependenciesResponse {
|
struct AnalyzeDependenciesResponseSingle {
|
||||||
dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>,
|
dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>,
|
||||||
#[serde(rename="dev-dependencies")]
|
#[serde(rename="dev-dependencies")]
|
||||||
dev_dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>,
|
dev_dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>,
|
||||||
|
@ -48,6 +48,11 @@ struct AnalyzeDependenciesResponse {
|
||||||
build_dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>
|
build_dependencies: BTreeMap<String, AnalyzeDependenciesResponseDetail>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct AnalyzeDependenciesResponse {
|
||||||
|
crates: BTreeMap<String, AnalyzeDependenciesResponseSingle>
|
||||||
|
}
|
||||||
|
|
||||||
impl Service for Api {
|
impl Service for Api {
|
||||||
type Request = Request;
|
type Request = Request;
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
|
@ -96,30 +101,33 @@ impl Api {
|
||||||
response.set_body(format!("{:?}", err));
|
response.set_body(format!("{:?}", err));
|
||||||
future::Either::A(future::ok(response))
|
future::Either::A(future::ok(response))
|
||||||
},
|
},
|
||||||
Ok(dependencies) => {
|
Ok(analysis_outcome) => {
|
||||||
let response_struct = AnalyzeDependenciesResponse {
|
let single = AnalyzeDependenciesResponseSingle {
|
||||||
dependencies: dependencies.main.into_iter()
|
dependencies: analysis_outcome.deps.main.into_iter()
|
||||||
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
||||||
outdated: analyzed.is_outdated(),
|
outdated: analyzed.is_outdated(),
|
||||||
required: analyzed.required,
|
required: analyzed.required,
|
||||||
latest: analyzed.latest
|
latest: analyzed.latest
|
||||||
})).collect(),
|
})).collect(),
|
||||||
dev_dependencies: dependencies.dev.into_iter()
|
dev_dependencies: analysis_outcome.deps.dev.into_iter()
|
||||||
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
||||||
outdated: analyzed.is_outdated(),
|
outdated: analyzed.is_outdated(),
|
||||||
required: analyzed.required,
|
required: analyzed.required,
|
||||||
latest: analyzed.latest
|
latest: analyzed.latest
|
||||||
})).collect(),
|
})).collect(),
|
||||||
build_dependencies: dependencies.build.into_iter()
|
build_dependencies: analysis_outcome.deps.build.into_iter()
|
||||||
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
.map(|(name, analyzed)| (name.into(), AnalyzeDependenciesResponseDetail {
|
||||||
outdated: analyzed.is_outdated(),
|
outdated: analyzed.is_outdated(),
|
||||||
required: analyzed.required,
|
required: analyzed.required,
|
||||||
latest: analyzed.latest
|
latest: analyzed.latest
|
||||||
})).collect()
|
})).collect()
|
||||||
};
|
};
|
||||||
|
let multi = AnalyzeDependenciesResponse {
|
||||||
|
crates: vec![(analysis_outcome.name.into(), single)].into_iter().collect()
|
||||||
|
};
|
||||||
let mut response = Response::new()
|
let mut response = Response::new()
|
||||||
.with_header(ContentType::json())
|
.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))
|
future::Either::B(future::ok(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,15 +31,20 @@ pub enum AnalyzeDependenciesError {
|
||||||
|
|
||||||
const FETCH_RELEASES_CONCURRENCY: usize = 10;
|
const FETCH_RELEASES_CONCURRENCY: usize = 10;
|
||||||
|
|
||||||
|
pub struct AnalyzeDependenciesOutcome {
|
||||||
|
pub name: CrateName,
|
||||||
|
pub deps: AnalyzedDependencies
|
||||||
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn analyze_dependencies(&self, repo_path: RepoPath) ->
|
pub fn analyze_dependencies(&self, repo_path: RepoPath) ->
|
||||||
impl Future<Item=AnalyzedDependencies, Error=AnalyzeDependenciesError>
|
impl Future<Item=AnalyzeDependenciesOutcome, Error=AnalyzeDependenciesError>
|
||||||
{
|
{
|
||||||
let manifest_future = self.retrieve_manifest(&repo_path);
|
let manifest_future = self.retrieve_manifest(&repo_path);
|
||||||
|
|
||||||
let engine = self.clone();
|
let engine = self.clone();
|
||||||
manifest_future.and_then(move |manifest| {
|
manifest_future.and_then(move |manifest| {
|
||||||
let CrateManifest::Crate(deps) = manifest;
|
let CrateManifest::Crate(crate_name, deps) = manifest;
|
||||||
let analyzer = DependencyAnalyzer::new(&deps);
|
let analyzer = DependencyAnalyzer::new(&deps);
|
||||||
|
|
||||||
let main_deps = deps.main.into_iter().map(|(name, _)| name);
|
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));
|
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)
|
.buffer_unordered(FETCH_RELEASES_CONCURRENCY)
|
||||||
.fold(analyzer, |mut analyzer, releases| { analyzer.process(releases); Ok(analyzer) })
|
.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
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,5 +96,5 @@ impl AnalyzedDependencies {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CrateManifest {
|
pub enum CrateManifest {
|
||||||
Crate(CrateDeps)
|
Crate(CrateName, CrateDeps)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,14 @@ enum CargoTomlDependency {
|
||||||
Complex(CargoTomlComplexDependency)
|
Complex(CargoTomlComplexDependency)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
struct CargoTomlPackage {
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
struct CargoToml {
|
struct CargoToml {
|
||||||
|
package: CargoTomlPackage,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
dependencies: BTreeMap<String, CargoTomlDependency>,
|
dependencies: BTreeMap<String, CargoTomlDependency>,
|
||||||
#[serde(rename = "dev-dependencies")]
|
#[serde(rename = "dev-dependencies")]
|
||||||
|
@ -65,6 +71,9 @@ pub fn parse_manifest_toml(input: &str) -> Result<CrateManifest, ManifestParseEr
|
||||||
let cargo_toml = toml::de::from_str::<CargoToml>(input)
|
let cargo_toml = toml::de::from_str::<CargoToml>(input)
|
||||||
.map_err(ManifestParseError::Serde)?;
|
.map_err(ManifestParseError::Serde)?;
|
||||||
|
|
||||||
|
let crate_name = cargo_toml.package.name.parse()
|
||||||
|
.map_err(ManifestParseError::Name)?;
|
||||||
|
|
||||||
let dependencies = cargo_toml.dependencies
|
let dependencies = cargo_toml.dependencies
|
||||||
.into_iter().filter_map(convert_dependency).collect::<Result<BTreeMap<_, _>, _>>()?;
|
.into_iter().filter_map(convert_dependency).collect::<Result<BTreeMap<_, _>, _>>()?;
|
||||||
let dev_dependencies = cargo_toml.dev_dependencies
|
let dev_dependencies = cargo_toml.dev_dependencies
|
||||||
|
@ -78,5 +87,5 @@ pub fn parse_manifest_toml(input: &str) -> Result<CrateManifest, ManifestParseEr
|
||||||
build: build_dependencies
|
build: build_dependencies
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(CrateManifest::Crate(deps))
|
Ok(CrateManifest::Crate(crate_name, deps))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue