Skip to content

Commit a58e035

Browse files
committed
Add index_metadata function for generating index files
1 parent 53e6087 commit a58e035

File tree

3 files changed

+86
-10
lines changed

3 files changed

+86
-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+
cargo_registry_index::DependencyKind::Normal => DependencyKind::Normal,
51+
cargo_registry_index::DependencyKind::Build => DependencyKind::Build,
52+
cargo_registry_index::DependencyKind::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: 72 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,76 @@ 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(|k| {
461+
semver::Version::parse(&k.num)
462+
.expect("version was valid semver when inserted into the database")
463+
});
464+
465+
let mut body = Vec::new();
466+
for version in versions {
467+
let mut deps: Vec<cargo_registry_index::Dependency> = version
468+
.dependencies(conn)?
469+
.into_iter()
470+
.map(|(dep, name)| {
471+
let (name, package) = match dep.explicit_name {
472+
Some(explicit_name) => (explicit_name, Some(name)),
473+
None => (name, None),
474+
};
475+
cargo_registry_index::Dependency {
476+
name,
477+
req: dep.req,
478+
features: dep.features,
479+
optional: dep.optional,
480+
default_features: dep.default_features,
481+
kind: Some(dep.kind.into()),
482+
package,
483+
target: dep.target,
484+
}
485+
})
486+
.collect();
487+
deps.sort();
488+
489+
let features: BTreeMap<String, Vec<String>> =
490+
serde_json::from_value(version.features).unwrap_or_default();
491+
let (features, features2) = Self::partition_features(features);
492+
let (features, features2, v) = if features2.is_empty() {
493+
(features, None, None)
494+
} else {
495+
(features, Some(features2), Some(2))
496+
};
497+
498+
let krate = cargo_registry_index::Crate {
499+
name: self.name.clone(),
500+
vers: version.num.to_string(),
501+
cksum: version.checksum.unwrap_or_default(),
502+
yanked: Some(version.yanked),
503+
deps,
504+
features,
505+
links: version.links,
506+
features2,
507+
v,
508+
};
509+
serde_json::to_writer(&mut body, &krate).unwrap();
510+
body.push(b'\n');
511+
}
512+
513+
Ok(body)
514+
}
443515
}
444516

445517
#[cfg(test)]

0 commit comments

Comments
 (0)