diff --git a/src/deps/raw_dep.rs b/src/deps/raw_dep.rs index d3cbdff..86760ef 100644 --- a/src/deps/raw_dep.rs +++ b/src/deps/raw_dep.rs @@ -1,9 +1,10 @@ use std::str::FromStr; -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct RawDep { pub name: String, pub ver: String, + pub source: String, pub children: Option>, pub parent: Option } @@ -18,6 +19,7 @@ impl FromStr for RawDep { Ok(RawDep { name: raw_dep_vec[0].to_owned(), ver: raw_dep_vec[1].to_owned(), + source: raw_dep_vec.get(2).map(|v| (*v).to_owned()).unwrap_or(String::new()), children: None, parent: None }) diff --git a/src/lockfile.rs b/src/lockfile.rs index 231a6af..9ee8809 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -158,7 +158,8 @@ impl Lockfile { .arg("update") .arg("--manifest-path") .arg(tmp_manifest.to_str().expect("failed to convert temp Cargo.toml path to string")) - .output() { + .output() + .and_then(|v| if v.status.success() { Ok(v) } else { Err(io::Error::new(io::ErrorKind::Other, "did not exit successfully")) }) { return Err(CliError::Generic(format!("Failed to run 'cargo update' with error '{}'", e.description()))); } @@ -172,7 +173,7 @@ impl Lockfile { debugln!("parsing semver results"); for (d_name, d) in self.deps.iter() { debugln!("iter; name={}; ver={}", d_name, d.ver); - if let Some(semver_dep) = updated_lf.deps.get(d_name) { + if let Some(semver_dep) = updated_lf.deps.get(&d.name) { if semver_dep.ver != d.ver { res.insert(d_name.to_owned(), Dep { name: d_name.to_owned(), @@ -231,7 +232,8 @@ impl Lockfile { .arg("update") .arg("--manifest-path") .arg(tmp_manifest.to_str().expect("failed to convert temp Cargo.toml path to string")) - .output() { + .output() + .and_then(|v| if v.status.success() { Ok(v) } else { Err(io::Error::new(io::ErrorKind::Other, "did not exit successfully")) }) { return Err(CliError::Generic(format!("Failed to run 'cargo update' with error '{}'", e.description()))); } @@ -242,10 +244,22 @@ impl Lockfile { try!(updated_lf.parse_deps_to_depth(0)); for (d_name, d) in self.deps.iter() { debugln!("iter; name={}", d_name); - if let Some(latest_dep) = updated_lf.deps.get(d_name) { + if let Some(latest_dep) = updated_lf.deps.get(&d.name) { if latest_dep.ver != d.ver { - if let Some(d) = res.get_mut(&latest_dep.name) { + let exists = if let Some(d) = res.get_mut(d_name) { d.latest_ver = Some(latest_dep.ver.clone()); + true + } else { + false + }; + + if !exists { + res.insert(d_name.to_owned(), Dep { + name: d_name.to_owned(), + project_ver: d.ver.clone(), + semver_ver: None, + latest_ver: Some(latest_dep.ver.clone()) + }); } } } @@ -309,6 +323,9 @@ impl Lockfile { Ok(val) => val, Err(e) => return Err(CliError::Generic(e)) }; + if !child.source.starts_with("(registry+") { + continue + } child.parent = Some(name.to_owned()); children.push(child.name.clone()); if all_deps || depth > 1 { @@ -355,7 +372,9 @@ impl Lockfile { Ok(val) => val, Err(e) => return Err(CliError::Generic(e)) }; - self.deps.insert(raw_dep.name.clone(), raw_dep); + if raw_dep.source.starts_with("(registry+") { + self.deps.insert(raw_dep.name.clone(), raw_dep); + } } }, Some(_) => unreachable!(), @@ -377,11 +396,15 @@ impl Lockfile { Ok(()) } + fn unique_deps(&self) -> HashMap { + self.deps.iter().map(|(_, ref dep)| (dep.name.clone(), (**dep).clone())).collect() + } + pub fn write_semver_manifest(&self, w: &mut W) -> CliResult<()> where W: Write { debugln!("executing; write_semver_manifest;"); try!(self.write_manifest_pretext(w)); - for dep in self.deps.values() { + for dep in self.unique_deps().values() { debugln!("iter; name={}; ver=~{}", dep.name, dep.ver); if let Err(e) = write!(w, "{} = \"~{}\"\n", dep.name, dep.ver) { return Err(CliError::Generic(format!("Failed to write Cargo.toml with error '{}'", e.description()))); @@ -394,12 +417,10 @@ impl Lockfile { debugln!("executing; write_latest_manifest;"); try!(self.write_manifest_pretext(w)); - for dep in self.deps.values() { + for dep in self.unique_deps().values() { debugln!("iter; name={}; ver=*", dep.name); - if dep.parent.is_none() { - if let Err(e) = write!(w, "{} = \"*\"\n", dep.name) { - return Err(CliError::Generic(format!("Failed to write Cargo.toml with error '{}'", e.description()))); - } + if let Err(e) = write!(w, "{} = \"*\"\n", dep.name) { + return Err(CliError::Generic(format!("Failed to write Cargo.toml with error '{}'", e.description()))); } } diff --git a/src/main.rs b/src/main.rs index 87a09e9..95d31ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,21 +73,25 @@ fn execute(cfg: Config) -> CliResult<()> { let mut lf = try!(Lockfile::new()); verboseln!(cfg, "{}", Format::Good("Done")); - if let Ok(Some(res)) = lf.get_updates(&cfg) { - println!("The following dependencies have newer versions available:\n"); - let mut tw = TabWriter::new(vec![]); - write!(&mut tw, "\tName\tProject Ver\tSemVer Compat\tLatest Ver\n").unwrap_or_else(|e| {panic!("write! error: {}", e)}); - for (d_name, d) in res.iter() { - write!(&mut tw, "\t{}\t {}\t {}\t {}\n", d_name, d.project_ver, d.semver_ver.as_ref().unwrap_or(&String::from(" -- ")), d.latest_ver.as_ref().unwrap_or(&String::from(" -- "))).unwrap(); - } - tw.flush().unwrap_or_else(|e| {panic!("failed to flush TabWriter: {}", e)}); - write!(stdout(), "{}", String::from_utf8(tw.unwrap()).unwrap_or_else(|e| {panic!("from_utf8 error: {}", e)}) - ).unwrap_or_else(|e| {panic!("write! error: {}", e)}) - } else { - println!("All dependencies are up to date, yay!") + match lf.get_updates(&cfg) { + Ok(Some(res)) => { + println!("The following dependencies have newer versions available:\n"); + let mut tw = TabWriter::new(vec![]); + write!(&mut tw, "\tName\tProject Ver\tSemVer Compat\tLatest Ver\n").unwrap_or_else(|e| {panic!("write! error: {}", e)}); + for (d_name, d) in res.iter() { + write!(&mut tw, "\t{}\t {}\t {}\t {}\n", d_name, d.project_ver, d.semver_ver.as_ref().unwrap_or(&String::from(" -- ")), d.latest_ver.as_ref().unwrap_or(&String::from(" -- "))).unwrap(); + } + tw.flush().unwrap_or_else(|e| {panic!("failed to flush TabWriter: {}", e)}); + write!(stdout(), "{}", String::from_utf8(tw.unwrap()).unwrap_or_else(|e| {panic!("from_utf8 error: {}", e)}) + ).unwrap_or_else(|e| {panic!("write! error: {}", e)}); + Ok(()) + }, + Ok(None) => { + println!("All dependencies are up to date, yay!"); + Ok(()) + }, + Err(e) => Err(e), } - - Ok(()) }