Skip to content

Commit 70d9a59

Browse files
committed
Add index_metadata function for generating index files
1 parent 93d93d0 commit 70d9a59

File tree

3 files changed

+83
-10
lines changed

3 files changed

+83
-10
lines changed

src/controllers/krate/publish.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use flate2::read::GzDecoder;
44
use hex::ToHex;
55
use sha2::{Digest, Sha256};
6-
use std::collections::BTreeMap;
76
use std::io::Read;
87
use std::path::Path;
98
use std::sync::Arc;
@@ -217,16 +216,11 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
217216
.uploader()
218217
.upload_crate(app.http_client(), tarball, &krate, vers)?;
219218

220-
let (features, features2): (BTreeMap<_, _>, BTreeMap<_, _>) =
221-
features.into_iter().partition(|(_k, vals)| {
222-
!vals
223-
.iter()
224-
.any(|v| v.starts_with("dep:") || v.contains("?/"))
225-
});
226-
let (features2, v) = if features2.is_empty() {
227-
(None, None)
219+
let (features, features2) = Crate::partition_features(features);
220+
let (features, features2, v) = if features2.is_empty() {
221+
(features, None, None)
228222
} else {
229-
(Some(features2), Some(2))
223+
(features, Some(features2), Some(2))
230224
};
231225

232226
// Register this crate in our local git repo.

src/models/dependency.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ pub enum DependencyKind {
4444
// if you add a kind here, be sure to update `from_row` below.
4545
}
4646

47+
impl From<cargo_registry_index::DependencyKind> for DependencyKind {
48+
fn from(dk: cargo_registry_index::DependencyKind) -> Self {
49+
match dk {
50+
IndexDependencyKind::Normal => DependencyKind::Normal,
51+
IndexDependencyKind::Build => DependencyKind::Build,
52+
IndexDependencyKind::Dev => DependencyKind::Dev,
53+
}
54+
}
55+
}
56+
4757
impl From<DependencyKind> for IndexDependencyKind {
4858
fn from(dk: DependencyKind) -> Self {
4959
match dk {

src/models/krate.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::BTreeMap;
2+
13
use chrono::NaiveDateTime;
24
use diesel::associations::Identifiable;
35
use diesel::pg::Pg;
@@ -440,6 +442,73 @@ impl Crate {
440442

441443
Ok(rows.records_and_total())
442444
}
445+
446+
/// Partition the features list into (features, features2)
447+
pub fn partition_features(
448+
features: BTreeMap<String, Vec<String>>,
449+
) -> (BTreeMap<String, Vec<String>>, BTreeMap<String, Vec<String>>) {
450+
features.into_iter().partition(|(_k, vals)| {
451+
!vals
452+
.iter()
453+
.any(|v| v.starts_with("dep:") || v.contains("?/"))
454+
})
455+
}
456+
457+
/// Serialize the crate as an index metadata file
458+
pub fn index_metadata(&self, conn: &PgConnection) -> QueryResult<Vec<u8>> {
459+
let mut versions: Vec<Version> = self.all_versions().load(conn)?;
460+
versions.sort_by_cached_key(|version| semver::Version::parse(&version.num).ok());
461+
462+
let mut body = Vec::new();
463+
for version in versions {
464+
let mut deps: Vec<cargo_registry_index::Dependency> = version
465+
.dependencies(conn)?
466+
.into_iter()
467+
.map(|(dep, name)| {
468+
let (name, package) = match dep.explicit_name {
469+
Some(explicit_name) => (explicit_name, Some(name)),
470+
None => (name, None),
471+
};
472+
cargo_registry_index::Dependency {
473+
name,
474+
req: dep.req,
475+
features: dep.features,
476+
optional: dep.optional,
477+
default_features: dep.default_features,
478+
kind: Some(dep.kind.into()),
479+
package,
480+
target: dep.target,
481+
}
482+
})
483+
.collect();
484+
deps.sort();
485+
486+
let features: BTreeMap<String, Vec<String>> =
487+
serde_json::from_value(version.features).unwrap_or_default();
488+
let (features, features2) = Self::partition_features(features);
489+
let (features, features2, v) = if features2.is_empty() {
490+
(features, None, None)
491+
} else {
492+
(features, Some(features2), Some(2))
493+
};
494+
495+
let krate = cargo_registry_index::Crate {
496+
name: self.name.clone(),
497+
vers: version.num.to_string(),
498+
cksum: version.checksum.unwrap_or_default(),
499+
yanked: Some(version.yanked),
500+
deps,
501+
features,
502+
links: version.links,
503+
features2,
504+
v,
505+
};
506+
serde_json::to_writer(&mut body, &krate).unwrap();
507+
body.push(b'\n');
508+
}
509+
510+
Ok(body)
511+
}
443512
}
444513

445514
#[cfg(test)]

0 commit comments

Comments
 (0)