Skip to content

Commit 27771e4

Browse files
committed
Merge branch 'build-queue-crates-io'
2 parents 0dfb64c + c0b853a commit 27771e4

File tree

6 files changed

+69
-102
lines changed

6 files changed

+69
-102
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ hyper = "0.9"
1818
semver = "0.5"
1919
slug = "=0.1.1"
2020
env_logger = "0.3"
21-
git2 = "0.4"
2221
magic = "0.12"
2322
iron = "0.3.1"
2423
router = "0.1.1"

src/docbuilder/queue.rs

Lines changed: 64 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,109 +2,55 @@
22
33

44
use super::DocBuilder;
5-
use rustc_serialize::json::Json;
6-
use git2;
5+
use rustc_serialize::json::{Json, Array};
6+
use hyper;
77
use db::connect_db;
88
use errors::*;
99

1010

1111
impl DocBuilder {
1212
/// Updates crates.io-index repository and adds new crates into build queue
13-
pub fn get_new_crates(&self) -> Result<()> {
14-
15-
let repo = try!(git2::Repository::open(&self.options.crates_io_index_path));
16-
17-
let old_tree = try!(self.head_tree(&repo));
18-
try!(self.update_repo(&repo));
19-
let new_tree = try!(self.head_tree(&repo));
20-
21-
let diff = try!(repo.diff_tree_to_tree(Some(&old_tree), Some(&new_tree), None));
22-
let conn = try!(connect_db());
23-
let mut line_n = 0;
24-
25-
try!(diff.print(git2::DiffFormat::Patch, |_, hunk, diffline| -> bool {
26-
let line = String::from_utf8_lossy(diffline.content()).into_owned();
27-
// crate strings starts with '{'
28-
// skip if line is not a crate string
29-
if line.chars().nth(0) != Some('{') {
30-
line_n = 0;
31-
return true;
32-
}
33-
34-
line_n += 1;
35-
36-
if match hunk {
37-
Some(hunk) => hunk.new_lines() != line_n,
38-
None => true,
39-
} {
40-
return true;
41-
}
42-
43-
let json = match Json::from_str(&line[..]) {
44-
Ok(j) => j,
45-
Err(err) => {
46-
error!("Failed to parse crate string: {}", err);
47-
// just continue even if we get an error for a crate
48-
return true;
13+
pub fn get_new_crates(&mut self) -> Result<()> {
14+
try!(self.load_database_cache());
15+
16+
let body = {
17+
use std::io::Read;
18+
let client = hyper::Client::new();
19+
let mut res = try!(client.get("https://crates.io/summary").send());
20+
let mut body = String::new();
21+
try!(res.read_to_string(&mut body));
22+
body
23+
};
24+
25+
let json = try!(Json::from_str(&body));
26+
27+
let crates = {
28+
let mut crates: Vec<(String, String)> = Vec::new();
29+
for section in ["just_updated", "new_crates"].iter() {
30+
match json.as_object()
31+
.and_then(|o| o.get(&section[..]))
32+
.and_then(|j| j.as_array())
33+
.map(get_crates_from_array) {
34+
Some(mut c) => crates.append(c.as_mut()),
35+
None => continue,
4936
}
50-
};
51-
52-
// check if a crate is yanked just in case
53-
if json.as_object()
54-
.and_then(|obj| obj.get("yanked"))
55-
.and_then(|y| y.as_boolean())
56-
.unwrap_or(true) {
57-
return true;
5837
}
38+
crates
39+
};
5940

60-
if let Some((krate, version)) = json.as_object()
61-
.map(|obj| {
62-
(obj.get("name")
63-
.and_then(|n| n.as_string()),
64-
obj.get("vers")
65-
.and_then(|n| n.as_string()))
66-
}) {
67-
68-
// Skip again if we can't get crate name and version
69-
if krate.is_none() || version.is_none() {
70-
return true;
71-
}
72-
73-
let _ = conn.execute("INSERT INTO queue (name, version) VALUES ($1, $2)",
74-
&[&krate.unwrap(), &version.unwrap()]);
41+
let conn = try!(connect_db());
42+
for (name, version) in crates {
43+
if self.db_cache.contains(&format!("{}-{}", name, version)[..]) {
44+
continue;
7545
}
76-
77-
true
78-
}));
79-
80-
Ok(())
81-
}
82-
83-
84-
fn update_repo(&self, repo: &git2::Repository) -> Result<()> {
85-
let mut remote = try!(repo.find_remote("origin"));
86-
try!(remote.fetch(&["refs/heads/*:refs/remotes/origin/*"], None, None));
87-
88-
// checkout master
89-
try!(repo.refname_to_id("refs/remotes/origin/master")
90-
.and_then(|oid| repo.find_object(oid, None))
91-
.and_then(|object| repo.reset(&object, git2::ResetType::Hard, None)));
46+
let _ = conn.execute("INSERT INTO queue (name, version) VALUES ($1, $2)",
47+
&[&name, &version]);
48+
}
9249

9350
Ok(())
9451
}
9552

9653

97-
fn head_tree<'a>(&'a self, repo: &'a git2::Repository) -> Result<git2::Tree> {
98-
repo.head()
99-
.ok()
100-
.and_then(|head| head.target())
101-
.ok_or(git2::Error::from_str("HEAD SHA1 not found"))
102-
.and_then(|oid| repo.find_commit(oid))
103-
.and_then(|commit| commit.tree())
104-
.or_else(|e| Err(ErrorKind::Git2Error(e).into()))
105-
}
106-
107-
10854
/// Builds packages from queue
10955
pub fn build_packages_queue(&mut self) -> Result<()> {
11056
let conn = try!(connect_db());
@@ -117,7 +63,7 @@ impl DocBuilder {
11763
match self.build_package(&name[..], &version[..]) {
11864
Ok(_) => {
11965
let _ = conn.execute("DELETE FROM queue WHERE id = $1", &[&id]);
120-
},
66+
}
12167
Err(e) => {
12268
error!("Failed to build package {}-{} from queue: {}",
12369
name,
@@ -132,6 +78,29 @@ impl DocBuilder {
13278
}
13379

13480

81+
/// Returns Vec<CRATE_NAME, CRATE_VERSION> from a summary array
82+
fn get_crates_from_array<'a>(crates: &'a Array) -> Vec<(String, String)> {
83+
let mut crates_vec: Vec<(String, String)> = Vec::new();
84+
for crte in crates {
85+
let name = match crte.as_object()
86+
.and_then(|o| o.get("id"))
87+
.and_then(|i| i.as_string())
88+
.map(|s| s.to_owned()) {
89+
Some(s) => s,
90+
None => continue,
91+
};
92+
let version = match crte.as_object()
93+
.and_then(|o| o.get("max_version"))
94+
.and_then(|v| v.as_string())
95+
.map(|s| s.to_owned()) {
96+
Some(s) => s,
97+
None => continue,
98+
};
99+
crates_vec.push((name, version));
100+
}
101+
crates_vec
102+
}
103+
135104

136105

137106

@@ -146,8 +115,12 @@ mod test {
146115
fn test_get_new_crates() {
147116
let _ = env_logger::init();
148117
let options = DocBuilderOptions::from_prefix(PathBuf::from("../cratesfyi-prefix"));
149-
let docbuilder = DocBuilder::new(options);
150-
assert!(docbuilder.get_new_crates().is_ok());
118+
let mut docbuilder = DocBuilder::new(options);
119+
let res = docbuilder.get_new_crates();
120+
if res.is_err() {
121+
error!("{:?}", res);
122+
}
123+
assert!(res.is_ok());
151124
}
152125

153126

src/errors.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_serialize::json;
55
use postgres;
66
use cargo;
77
use hyper;
8-
use git2;
98
use magic::MagicError;
109

1110

@@ -23,7 +22,6 @@ error_chain! {
2322
postgres::error::ConnectError, PostgresConnectError;
2423
postgres::error::Error, PostgresError;
2524
hyper::Error, HyperError;
26-
git2::Error, Git2Error;
2725
MagicError, MagicError;
2826
Box<cargo::CargoError>, CargoError;
2927
}

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ extern crate hyper;
1313
extern crate time;
1414
extern crate semver;
1515
extern crate slug;
16-
extern crate git2;
1716
extern crate magic;
1817
extern crate iron;
1918
extern crate router;

src/utils/daemon.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,23 @@ pub fn start_daemon() {
4545
}
4646

4747

48-
// check new crates every 15 minutes
48+
// check new crates every 5 minutes
4949
// FIXME: why not just check new crates and build them if there is any?
5050
thread::spawn(move || {
5151
loop {
52-
thread::sleep(Duration::from_secs(900));
52+
thread::sleep(Duration::from_secs(300));
5353
debug!("Checking new crates");
54-
let doc_builder = DocBuilder::new(opts());
55-
if let Err(e) = doc_builder.get_new_crates() {
54+
if let Err(e) = DocBuilder::new(opts()).get_new_crates() {
5655
error!("Failed to get new crates: {}", e);
5756
}
5857
}
5958
});
6059

6160

62-
// build crates in que every 12 minutes
61+
// build crates in que every 5 minutes
6362
thread::spawn(move || {
6463
loop {
65-
thread::sleep(Duration::from_secs(720));
64+
thread::sleep(Duration::from_secs(300));
6665

6766
let mut opts = opts();
6867
opts.skip_if_exists = true;

0 commit comments

Comments
 (0)