forked from rust-lang/docs.rs
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic db <-> index consistency check
Checks just whether any crates/versions don't exist, but can easily be expanded with validation of other details.
- Loading branch information
Showing
12 changed files
with
434 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use crates_index::Crate; | ||
use failure::ResultExt; | ||
use std::io::{Seek, SeekFrom, Write}; | ||
|
||
pub(crate) struct Crates { | ||
repo: git2::Repository, | ||
} | ||
|
||
impl Crates { | ||
pub(super) fn new(repo: git2::Repository) -> Self { | ||
Self { repo } | ||
} | ||
|
||
pub(crate) fn walk(&self, mut f: impl FnMut(Crate)) -> Result<(), failure::Error> { | ||
log::debug!("Walking crates in index"); | ||
let tree = self | ||
.repo | ||
.find_commit(self.repo.refname_to_id("refs/remotes/origin/master")?)? | ||
.tree()?; | ||
|
||
// crates_index doesn't publicly expose their slice constructor, so need to write each blob | ||
// to a file before loading it as a `Crate`. | ||
let mut tmp = tempfile::NamedTempFile::new()?; | ||
|
||
let mut result = Ok(()); | ||
|
||
tree.walk(git2::TreeWalkMode::PreOrder, |_, entry| { | ||
result = (|| { | ||
if let Some(blob) = entry.to_object(&self.repo)?.as_blob() { | ||
tmp.write_all(blob.content())?; | ||
if let Ok(krate) = Crate::new(tmp.path()) { | ||
f(krate); | ||
} else { | ||
log::warn!("Not a crate {}", entry.name().unwrap()); | ||
} | ||
tmp.as_file().set_len(0)?; | ||
tmp.seek(SeekFrom::Start(0))?; | ||
} | ||
Result::<(), failure::Error>::Ok(()) | ||
})() | ||
.with_context(|_| { | ||
format!( | ||
"Loading crate details from {}", | ||
entry.name().unwrap_or_default() | ||
) | ||
}); | ||
match result { | ||
Ok(_) => git2::TreeWalkResult::Ok, | ||
Err(_) => git2::TreeWalkResult::Abort, | ||
} | ||
})?; | ||
|
||
Ok(result?) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use std::{collections::BTreeMap, fmt::Debug}; | ||
|
||
#[derive(Default, Debug)] | ||
pub(crate) struct Data { | ||
pub(crate) crates: BTreeMap<CrateId, Crate>, | ||
} | ||
|
||
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Default, Debug)] | ||
pub(crate) struct CrateId(pub(crate) String); | ||
|
||
#[derive(Default, Debug)] | ||
pub(crate) struct Crate { | ||
pub(crate) releases: BTreeMap<Version, Release>, | ||
} | ||
|
||
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Default, Debug)] | ||
pub(crate) struct Version(pub(crate) String); | ||
|
||
#[derive(Default, Debug)] | ||
pub(crate) struct Release {} | ||
|
||
impl std::fmt::Display for CrateId { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
impl std::fmt::Display for Version { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&self.0, f) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use super::data::{Crate, CrateId, Data, Release, Version}; | ||
use std::collections::BTreeMap; | ||
|
||
pub(crate) fn load(conn: &mut postgres::Client) -> Result<Data, failure::Error> { | ||
let rows = conn.query( | ||
" | ||
SELECT | ||
crates.name, | ||
releases.version | ||
FROM crates | ||
INNER JOIN releases ON releases.crate_id = crates.id | ||
ORDER BY crates.id, releases.id | ||
", | ||
&[], | ||
)?; | ||
|
||
let mut data = Data { | ||
crates: BTreeMap::new(), | ||
}; | ||
|
||
let mut rows = rows.iter(); | ||
|
||
struct Current { | ||
id: CrateId, | ||
krate: Crate, | ||
} | ||
|
||
let mut current = if let Some(row) = rows.next() { | ||
Current { | ||
id: CrateId(row.get("name")), | ||
krate: Crate { | ||
releases: { | ||
let mut releases = BTreeMap::new(); | ||
releases.insert(Version(row.get("version")), Release {}); | ||
releases | ||
}, | ||
}, | ||
} | ||
} else { | ||
return Ok(data); | ||
}; | ||
|
||
for row in rows { | ||
if row.get::<_, String>("name") != current.id.0 { | ||
data.crates.insert( | ||
std::mem::replace(&mut current.id, CrateId(row.get("name"))), | ||
std::mem::take(&mut current.krate), | ||
); | ||
} | ||
current | ||
.krate | ||
.releases | ||
.insert(Version(row.get("version")), Release::default()); | ||
} | ||
|
||
data.crates.insert(current.id, current.krate); | ||
|
||
Ok(data) | ||
} |
Oops, something went wrong.