|
1 |
| -use std::fs::File; |
2 | 1 | use std::io::prelude::*;
|
3 |
| -use std::path::Path; |
4 | 2 |
|
5 | 3 | use rustc_serialize::{Encodable, Decodable};
|
6 | 4 | use toml::{self, Encoder, Value};
|
7 | 5 |
|
8 | 6 | use core::{Resolve, resolver, Package};
|
9 |
| -use util::{CargoResult, ChainError, human, paths, Config}; |
| 7 | +use util::{CargoResult, ChainError, human, Config, Filesystem}; |
10 | 8 | use util::toml as cargo_toml;
|
11 | 9 |
|
12 | 10 | pub fn load_pkg_lockfile(pkg: &Package, config: &Config)
|
13 | 11 | -> CargoResult<Option<Resolve>> {
|
14 |
| - let lockfile = pkg.root().join("Cargo.lock"); |
15 |
| - load_lockfile(&lockfile, pkg, config).chain_error(|| { |
16 |
| - human(format!("failed to parse lock file at: {}", lockfile.display())) |
17 |
| - }) |
18 |
| -} |
| 12 | + if !pkg.root().join("Cargo.lock").exists() { |
| 13 | + return Ok(None) |
| 14 | + } |
19 | 15 |
|
20 |
| -pub fn load_lockfile(path: &Path, pkg: &Package, config: &Config) |
21 |
| - -> CargoResult<Option<Resolve>> { |
22 |
| - // If there is no lockfile, return none. |
23 |
| - let mut f = match File::open(path) { |
24 |
| - Ok(f) => f, |
25 |
| - Err(_) => return Ok(None) |
26 |
| - }; |
| 16 | + let root = Filesystem::new(pkg.root().to_path_buf()); |
| 17 | + let mut f = try!(root.open_ro("Cargo.lock", config, "Cargo.lock file")); |
27 | 18 |
|
28 | 19 | let mut s = String::new();
|
29 |
| - try!(f.read_to_string(&mut s)); |
30 |
| - |
31 |
| - let table = toml::Value::Table(try!(cargo_toml::parse(&s, path))); |
32 |
| - let mut d = toml::Decoder::new(table); |
33 |
| - let v: resolver::EncodableResolve = try!(Decodable::decode(&mut d)); |
34 |
| - Ok(Some(try!(v.to_resolve(pkg, config)))) |
35 |
| -} |
36 |
| - |
37 |
| -pub fn write_pkg_lockfile(pkg: &Package, resolve: &Resolve) -> CargoResult<()> { |
38 |
| - let loc = pkg.root().join("Cargo.lock"); |
39 |
| - write_lockfile(&loc, resolve) |
| 20 | + try!(f.read_to_string(&mut s).chain_error(|| { |
| 21 | + human(format!("failed to read file: {}", f.path().display())) |
| 22 | + })); |
| 23 | + |
| 24 | + (|| { |
| 25 | + let table = toml::Value::Table(try!(cargo_toml::parse(&s, f.path()))); |
| 26 | + let mut d = toml::Decoder::new(table); |
| 27 | + let v: resolver::EncodableResolve = try!(Decodable::decode(&mut d)); |
| 28 | + Ok(Some(try!(v.to_resolve(pkg, config)))) |
| 29 | + }).chain_error(|| { |
| 30 | + human(format!("failed to parse lock file at: {}", f.path().display())) |
| 31 | + }) |
40 | 32 | }
|
41 | 33 |
|
42 |
| -pub fn write_lockfile(dst: &Path, resolve: &Resolve) -> CargoResult<()> { |
| 34 | +pub fn write_pkg_lockfile(pkg: &Package, |
| 35 | + resolve: &Resolve, |
| 36 | + config: &Config) -> CargoResult<()> { |
43 | 37 | let mut e = Encoder::new();
|
44 | 38 | resolve.encode(&mut e).unwrap();
|
45 | 39 |
|
@@ -69,20 +63,36 @@ pub fn write_lockfile(dst: &Path, resolve: &Resolve) -> CargoResult<()> {
|
69 | 63 | None => {}
|
70 | 64 | }
|
71 | 65 |
|
| 66 | + let root = Filesystem::new(pkg.root().to_path_buf()); |
| 67 | + |
72 | 68 | // Load the original lockfile if it exists.
|
73 |
| - if let Ok(orig) = paths::read(dst) { |
| 69 | + // |
| 70 | + // If the lockfile contents haven't changed so don't rewrite it. This is |
| 71 | + // helpful on read-only filesystems. |
| 72 | + let orig = root.open_ro("Cargo.lock", config, "Cargo.lock file"); |
| 73 | + let orig = orig.and_then(|mut f| { |
| 74 | + let mut s = String::new(); |
| 75 | + try!(f.read_to_string(&mut s)); |
| 76 | + Ok(s) |
| 77 | + }); |
| 78 | + if let Ok(orig) = orig { |
74 | 79 | if has_crlf_line_endings(&orig) {
|
75 | 80 | out = out.replace("\n", "\r\n");
|
76 | 81 | }
|
77 | 82 | if out == orig {
|
78 |
| - // The lockfile contents haven't changed so don't rewrite it. |
79 |
| - // This is helpful on read-only filesystems. |
80 | 83 | return Ok(())
|
81 | 84 | }
|
82 | 85 | }
|
83 | 86 |
|
84 |
| - try!(paths::write(dst, out.as_bytes())); |
85 |
| - Ok(()) |
| 87 | + // Ok, if that didn't work just write it out |
| 88 | + root.open_rw("Cargo.lock", config, "Cargo.lock file").and_then(|mut f| { |
| 89 | + try!(f.file().set_len(0)); |
| 90 | + try!(f.write_all(out.as_bytes())); |
| 91 | + Ok(()) |
| 92 | + }).chain_error(|| { |
| 93 | + human(format!("failed to write {}", |
| 94 | + pkg.root().join("Cargo.lock").display())) |
| 95 | + }) |
86 | 96 | }
|
87 | 97 |
|
88 | 98 | fn has_crlf_line_endings(s: &str) -> bool {
|
|
0 commit comments