Skip to content

Commit 4814a84

Browse files
committed
Addressing review comments
1 parent 7fd5243 commit 4814a84

File tree

9 files changed

+89
-57
lines changed

9 files changed

+89
-57
lines changed

src/cargo/core/resolver/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ this could be indicative of a few possible situations:
169169
but was replaced with one that doesn't
170170
* the lock file is corrupt
171171
172-
unable to verify that `{0}` was the same as before in either situation
172+
unable to verify that `{0}` is the same as when the lockfile was generated
173173
", id, id.source_id())
174174

175175
// If the checksums aren't equal, and neither is None, then they
@@ -185,7 +185,7 @@ this could be indicative of a few possible errors:
185185
* a replacement source in use (e.g. a mirror) returned a different checksum
186186
* the source itself may be corrupt in one way or another
187187
188-
unable to verify that `{0}` was the same as before in any situation
188+
unable to verify that `{0}` is the same as when the lockfile was generated
189189
", id);
190190
}
191191
}

src/cargo/ops/cargo_rustc/fingerprint.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ pub fn prepare_target<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
5757
let compare = compare_old_fingerprint(&loc, &*fingerprint);
5858
log_compare(unit, &compare);
5959

60+
// If our comparison failed (e.g. we're going to trigger a rebuild of this
61+
// crate), then we also ensure the source of the crate passes all
62+
// verification checks before we build it.
63+
//
64+
// The `Source::verify` method is intended to allow sources to execute
65+
// pre-build checks to ensure that the relevant source code is all
66+
// up-to-date and as expected. This is currently used primarily for
67+
// directory sources which will use this hook to perform an integrity check
68+
// on all files in the source to ensure they haven't changed. If they have
69+
// changed then an error is issued.
6070
if compare.is_err() {
6171
let source_id = unit.pkg.package_id().source_id();
6272
let sources = cx.packages.sources();

src/cargo/sources/registry/index.rs

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
11
use std::collections::HashMap;
22
use std::io::prelude::*;
3-
use std::fs::{File, OpenOptions};
3+
use std::fs::File;
44
use std::path::Path;
55

66
use rustc_serialize::json;
77

88
use core::dependency::{Dependency, DependencyInner, Kind};
99
use core::{SourceId, Summary, PackageId, Registry};
1010
use sources::registry::{RegistryPackage, RegistryDependency, INDEX_LOCK};
11-
use util::{CargoResult, ChainError, internal, Filesystem, human, Config};
11+
use util::{CargoResult, ChainError, internal, Filesystem, Config};
1212

1313
pub struct RegistryIndex<'cfg> {
1414
source_id: SourceId,
1515
path: Filesystem,
1616
cache: HashMap<String, Vec<(Summary, bool)>>,
1717
hashes: HashMap<(String, String), String>, // (name, vers) => cksum
1818
config: &'cfg Config,
19+
locked: bool,
1920
}
2021

2122
impl<'cfg> RegistryIndex<'cfg> {
2223
pub fn new(id: &SourceId,
2324
path: &Filesystem,
24-
config: &'cfg Config) -> RegistryIndex<'cfg> {
25+
config: &'cfg Config,
26+
locked: bool) -> RegistryIndex<'cfg> {
2527
RegistryIndex {
2628
source_id: id.clone(),
2729
path: path.clone(),
2830
cache: HashMap::new(),
2931
hashes: HashMap::new(),
3032
config: config,
33+
locked: locked,
3134
}
3235
}
3336

@@ -52,53 +55,57 @@ impl<'cfg> RegistryIndex<'cfg> {
5255
if self.cache.contains_key(name) {
5356
return Ok(self.cache.get(name).unwrap());
5457
}
55-
// If the lock file doesn't already exist then this'll cause *someone*
56-
// to create it. We don't actually care who creates it, and if it's
57-
// already there this should have no effect.
58-
drop(OpenOptions::new()
59-
.write(true)
60-
.create(true)
61-
.open(self.path.join(INDEX_LOCK).into_path_unlocked()));
62-
let lock = self.path.open_ro(Path::new(INDEX_LOCK),
63-
self.config,
64-
"the registry index");
65-
let file = lock.and_then(|lock| {
66-
let path = lock.path().parent().unwrap();
67-
let fs_name = name.chars().flat_map(|c| {
68-
c.to_lowercase()
69-
}).collect::<String>();
70-
71-
// see module comment for why this is structured the way it is
72-
let path = match fs_name.len() {
73-
1 => path.join("1").join(&fs_name),
74-
2 => path.join("2").join(&fs_name),
75-
3 => path.join("3").join(&fs_name[..1]).join(&fs_name),
76-
_ => path.join(&fs_name[0..2])
77-
.join(&fs_name[2..4])
78-
.join(&fs_name),
79-
};
80-
File::open(&path).map_err(human)
81-
});
82-
let summaries = match file {
58+
let summaries = try!(self.load_summaries(name));
59+
let summaries = summaries.into_iter().filter(|summary| {
60+
summary.0.package_id().name() == name
61+
}).collect();
62+
self.cache.insert(name.to_string(), summaries);
63+
Ok(self.cache.get(name).unwrap())
64+
}
65+
66+
fn load_summaries(&mut self, name: &str) -> CargoResult<Vec<(Summary, bool)>> {
67+
let (path, _lock) = if self.locked {
68+
let lock = self.path.open_ro(Path::new(INDEX_LOCK),
69+
self.config,
70+
"the registry index");
71+
match lock {
72+
Ok(lock) => {
73+
(lock.path().parent().unwrap().to_path_buf(), Some(lock))
74+
}
75+
Err(_) => return Ok(Vec::new()),
76+
}
77+
} else {
78+
(self.path.clone().into_path_unlocked(), None)
79+
};
80+
81+
let fs_name = name.chars().flat_map(|c| {
82+
c.to_lowercase()
83+
}).collect::<String>();
84+
85+
// see module comment for why this is structured the way it is
86+
let path = match fs_name.len() {
87+
1 => path.join("1").join(&fs_name),
88+
2 => path.join("2").join(&fs_name),
89+
3 => path.join("3").join(&fs_name[..1]).join(&fs_name),
90+
_ => path.join(&fs_name[0..2])
91+
.join(&fs_name[2..4])
92+
.join(&fs_name),
93+
};
94+
match File::open(&path) {
8395
Ok(mut f) => {
8496
let mut contents = String::new();
8597
try!(f.read_to_string(&mut contents));
8698
let ret: CargoResult<Vec<(Summary, bool)>>;
8799
ret = contents.lines().filter(|l| l.trim().len() > 0)
88100
.map(|l| self.parse_registry_package(l))
89101
.collect();
90-
try!(ret.chain_error(|| {
102+
ret.chain_error(|| {
91103
internal(format!("failed to parse registry's information \
92104
for: {}", name))
93-
}))
105+
})
94106
}
95-
Err(..) => Vec::new(),
96-
};
97-
let summaries = summaries.into_iter().filter(|summary| {
98-
summary.0.package_id().name() == name
99-
}).collect();
100-
self.cache.insert(name.to_string(), summaries);
101-
Ok(self.cache.get(name).unwrap())
107+
Err(..) => Ok(Vec::new()),
108+
}
102109
}
103110

104111
/// Parse a line from the registry's index file into a Summary for a

src/cargo/sources/registry/local.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,17 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
7575

7676
// We don't actually need to download anything per-se, we just need to
7777
// verify the checksum matches the .crate file itself.
78-
let mut data = Vec::new();
79-
try!(crate_file.read_to_end(&mut data).chain_error(|| {
80-
human(format!("failed to read `{}`", crate_file.path().display()))
81-
}));
8278
let mut state = Sha256::new();
83-
state.update(&data);
79+
let mut buf = [0; 64 * 1024];
80+
loop {
81+
let n = try!(crate_file.read(&mut buf).chain_error(|| {
82+
human(format!("failed to read `{}`", crate_file.path().display()))
83+
}));
84+
if n == 0 {
85+
break
86+
}
87+
state.update(&buf[..n]);
88+
}
8489
if state.finish().to_hex() != checksum {
8590
bail!("failed to verify the checksum of `{}`", pkg)
8691
}

src/cargo/sources/registry/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ pub struct RegistrySource<'cfg> {
181181
updated: bool,
182182
ops: Box<RegistryData + 'cfg>,
183183
index: index::RegistryIndex<'cfg>,
184+
index_locked: bool,
184185
}
185186

186187
#[derive(RustcDecodable)]
@@ -240,29 +241,32 @@ impl<'cfg> RegistrySource<'cfg> {
240241
config: &'cfg Config) -> RegistrySource<'cfg> {
241242
let name = short_name(source_id);
242243
let ops = remote::RemoteRegistry::new(source_id, config, &name);
243-
RegistrySource::new(source_id, config, &name, Box::new(ops))
244+
RegistrySource::new(source_id, config, &name, Box::new(ops), true)
244245
}
245246

246247
pub fn local(source_id: &SourceId,
247248
path: &Path,
248249
config: &'cfg Config) -> RegistrySource<'cfg> {
249250
let name = short_name(source_id);
250251
let ops = local::LocalRegistry::new(path, config, &name);
251-
RegistrySource::new(source_id, config, &name, Box::new(ops))
252+
RegistrySource::new(source_id, config, &name, Box::new(ops), false)
252253
}
253254

254255
fn new(source_id: &SourceId,
255256
config: &'cfg Config,
256257
name: &str,
257-
ops: Box<RegistryData + 'cfg>) -> RegistrySource<'cfg> {
258+
ops: Box<RegistryData + 'cfg>,
259+
index_locked: bool) -> RegistrySource<'cfg> {
258260
RegistrySource {
259261
src_path: config.registry_source_path().join(name),
260262
config: config,
261263
source_id: source_id.clone(),
262264
updated: false,
263265
index: index::RegistryIndex::new(source_id,
264266
ops.index_path(),
265-
config),
267+
config,
268+
index_locked),
269+
index_locked: index_locked,
266270
ops: ops,
267271
}
268272
}
@@ -306,7 +310,8 @@ impl<'cfg> RegistrySource<'cfg> {
306310
let path = self.ops.index_path();
307311
self.index = index::RegistryIndex::new(&self.source_id,
308312
path,
309-
self.config);
313+
self.config,
314+
self.index_locked);
310315
Ok(())
311316
}
312317
}

src/cargo/sources/registry/remote.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
5353
}
5454

5555
fn update_index(&mut self) -> CargoResult<()> {
56-
// Ensure that this'll actually succeed later on.
56+
// Ensure that we'll actually be able to acquire an HTTP handle later on
57+
// once we start trying to download crates. This will weed out any
58+
// problems with `.cargo/config` configuration related to HTTP.
59+
//
60+
// This way if there's a problem the error gets printed before we even
61+
// hit the index, which may not actually read this configuration.
5762
try!(ops::http_handle(self.config));
5863

5964
// Then we actually update the index

tests/directory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ this could be indicative of a few possible errors:
287287
* a replacement source in use (e.g. a mirror) returned a different checksum
288288
* the source itself may be corrupt in one way or another
289289
290-
unable to verify that `foo v0.1.0` was the same as before in any situation
290+
unable to verify that `foo v0.1.0` is the same as when the lockfile was generated
291291
292292
"));
293293
}

tests/local-registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ this could be indicative of a few possible errors:
344344
* a replacement source in use (e.g. a mirror) returned a different checksum
345345
* the source itself may be corrupt in one way or another
346346
347-
unable to verify that `foo v0.0.1` was the same as before in any situation
347+
unable to verify that `foo v0.0.1` is the same as when the lockfile was generated
348348
349349
"));
350350
}

tests/lockfile-compat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ this could be indicative of a few possible errors:
155155
* a replacement source in use (e.g. a mirror) returned a different checksum
156156
* the source itself may be corrupt in one way or another
157157
158-
unable to verify that `foo v0.1.0` was the same as before in any situation
158+
unable to verify that `foo v0.1.0` is the same as when the lockfile was generated
159159
160160
"));
161161
}
@@ -272,7 +272,7 @@ this could be indicative of a few possible situations:
272272
but was replaced with one that doesn't
273273
* the lock file is corrupt
274274
275-
unable to verify that `foo v0.1.0 ([..])` was the same as before in either situation
275+
unable to verify that `foo v0.1.0 ([..])` is the same as when the lockfile was generated
276276
277277
"));
278278
}

0 commit comments

Comments
 (0)