Start integrating VersionReq
authorCarl Lerche <me@carllerche.com>
Tue, 13 May 2014 19:52:13 +0000 (12:52 -0700)
committerCarl Lerche <me@carllerche.com>
Tue, 13 May 2014 19:52:20 +0000 (12:52 -0700)
src/cargo/core/dependency.rs
src/cargo/core/manifest.rs
src/cargo/core/package.rs
src/cargo/core/resolver.rs
src/cargo/core/summary.rs
src/cargo/core/version_req.rs
src/cargo/ops/cargo_read_manifest.rs

index 3e4b7c75c233e46596664079d4478cd6894c4d54..fcffed66d3d7d1f819aff391edfdf7360d796628 100644 (file)
@@ -1,38 +1,55 @@
-use core::NameVer;
+use semver::Version;
+use core::{NameVer,VersionReq};
+use util::CargoResult;
 
-#[deriving(Eq,Clone,Show,Encodable,Decodable)]
+#[deriving(Eq,Clone,Show)]
 pub struct Dependency {
-    name: NameVer
+    name: ~str,
+    req: VersionReq
 }
 
 impl Dependency {
-    pub fn new(name: &str) -> Dependency {
-        Dependency { name: NameVer::new(name.to_owned(), "1.0.0") }
+    pub fn new(name: &str, req: &VersionReq) -> Dependency {
+        Dependency {
+            name: name.to_owned(),
+            req: req.clone()
+        }
     }
 
-    pub fn with_namever(name: &NameVer) -> Dependency {
-        Dependency { name: name.clone() }
+    pub fn parse(name: &str, version: &str) -> CargoResult<Dependency> {
+        Ok(Dependency {
+            name: name.to_owned(),
+            req: try!(VersionReq::parse(version))
+        })
     }
 
-    pub fn with_name_and_version(name: &str, version: &str) -> Dependency {
-        Dependency { name: NameVer::new(name, version) }
+    pub fn exact(name: &str, version: &Version) -> Dependency {
+        Dependency {
+            name: name.to_owned(),
+            req: VersionReq::exact(version)
+        }
     }
 
-    pub fn get_namever<'a>(&'a self) -> &'a NameVer {
-        &self.name
+    pub fn get_version_req<'a>(&'a self) -> &'a VersionReq {
+        &self.req
     }
 
     pub fn get_name<'a>(&'a self) -> &'a str {
-        self.name.get_name()
+        self.name.as_slice()
     }
 }
 
-pub trait DependencyNameVers {
-    fn namevers(&self) -> Vec<NameVer>;
+#[deriving(Eq,Clone,Encodable)]
+pub struct SerializedDependency {
+    name: ~str,
+    req: ~str
 }
 
-impl DependencyNameVers for Vec<Dependency> {
-    fn namevers(&self) -> Vec<NameVer> {
-        self.iter().map(|dep| dep.get_namever().clone()).collect()
+impl SerializedDependency {
+    pub fn from_dependency(dep: &Dependency) -> SerializedDependency {
+        SerializedDependency {
+            name: dep.get_name().to_owned(),
+            req: dep.get_version_req().to_str()
+        }
     }
 }
index 1bdd71d648be9db61262e1f40d4adf4b8546e282..159483fc2024bf14887974132e26e86b543cdbf6 100644 (file)
@@ -1,6 +1,7 @@
 use std::fmt;
 use std::fmt::{Show,Formatter};
 use collections::HashMap;
+use semver::Version;
 use serialize::{Encoder,Encodable};
 use core::{
     Dependency,
@@ -8,6 +9,8 @@ use core::{
     Package,
     Summary
 };
+use core::dependency::SerializedDependency;
+use util::CargoResult;
 
 #[deriving(Eq,Clone)]
 pub struct Manifest {
@@ -25,7 +28,9 @@ impl Show for Manifest {
 
 #[deriving(Eq,Clone,Encodable)]
 pub struct SerializedManifest {
-    summary: Summary,
+    name: ~str,
+    version: ~str,
+    dependencies: Vec<SerializedDependency>,
     authors: Vec<~str>,
     targets: Vec<Target>,
     target_dir: ~str
@@ -34,7 +39,9 @@ pub struct SerializedManifest {
 impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
     fn encode(&self, s: &mut S) -> Result<(), E> {
         SerializedManifest {
-            summary: self.summary.clone(),
+            name: self.summary.get_name().to_owned(),
+            version: self.summary.get_version().to_str(),
+            dependencies: self.summary.get_dependencies().iter().map(|d| SerializedDependency::from_dependency(d)).collect(),
             authors: self.authors.clone(),
             targets: self.targets.clone(),
             target_dir: self.target_dir.as_str().unwrap().to_owned()
@@ -101,6 +108,10 @@ impl Manifest {
         self.get_summary().get_name_ver().get_name()
     }
 
+    pub fn get_version<'a>(&'a self) -> &'a Version {
+        self.get_summary().get_name_ver().get_version()
+    }
+
     pub fn get_authors<'a>(&'a self) -> &'a [~str] {
         self.authors.as_slice()
     }
@@ -176,30 +187,34 @@ pub struct TomlManifest {
 }
 
 impl TomlManifest {
-    pub fn to_package(&self, path: &str) -> Package {
+    pub fn to_package(&self, path: &str) -> CargoResult<Package> {
         // TODO: Convert hte argument to take a Path
         let path = Path::new(path);
 
         // Get targets
         let targets = normalize(&self.lib, &self.bin);
-        // Get deps
-        let deps = self.dependencies.clone().map(|deps| {
-            deps.iter().map(|(k,v)| {
-                // This can produce an invalid version, but it's temporary because this needs
-                // to be replaced with Dependency, not NameVer
-                Dependency::with_namever(&NameVer::new(k.clone(), v.clone()))
-            }).collect()
-        }).unwrap_or_else(|| vec!());
+
+        let mut deps = Vec::new();
+
+        // Collect the deps
+        match self.dependencies {
+            Some(ref dependencies) => {
+                for (n, v) in dependencies.iter() {
+                    deps.push(try!(Dependency::parse(*n, *v)));
+                }
+            }
+            None => ()
+        }
 
         // TODO: https://github.com/mozilla/rust/issues/14049
         let root = Path::new(path.dirname());
 
-        Package::new(
+        Ok(Package::new(
             &Manifest::new(
                 &Summary::new(&self.project.to_name_ver(), deps.as_slice()),
                 targets.as_slice(),
                 &Path::new("target")),
-            &root)
+            &root))
     }
 }
 
index a208517f6a98134f97d9b1b0064e601dde6a2024..4e1834679b94b6a83814db71205db706c5ea98d3 100644 (file)
@@ -9,6 +9,7 @@ use core::{
     Target,
     Summary
 };
+use core::dependency::SerializedDependency;
 use util::graph;
 use serialize::{Encoder,Encodable};
 
@@ -24,7 +25,7 @@ pub struct Package {
 struct SerializedPackage {
     name: ~str,
     version: ~str,
-    dependencies: Vec<Dependency>,
+    dependencies: Vec<SerializedDependency>,
     authors: Vec<~str>,
     targets: Vec<Target>,
     root: ~str
@@ -39,7 +40,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Package {
         SerializedPackage {
             name: name_ver.get_name().to_owned(),
             version: name_ver.get_version().to_str(),
-            dependencies: Vec::from_slice(summary.get_dependencies()),
+            dependencies: summary.get_dependencies().iter().map(|d| SerializedDependency::from_dependency(d)).collect(),
             authors: Vec::from_slice(manifest.get_authors()),
             targets: Vec::from_slice(manifest.get_targets()),
             root: self.root.as_str().unwrap().to_owned()
@@ -56,7 +57,7 @@ impl Package {
     }
 
     pub fn to_dependency(&self) -> Dependency {
-        Dependency::with_namever(self.manifest.get_summary().get_name_ver())
+        Dependency::exact(self.manifest.get_name(), self.manifest.get_version())
     }
 
     pub fn get_manifest<'a>(&'a self) -> &'a Manifest {
index 7e4a747d2a43b4117a80b8fcad2c7f32801969c2..6523913c968680a2a08532f619ac3a3be88a4ddb 100644 (file)
@@ -62,7 +62,7 @@ mod test {
     macro_rules! pkg(
         ($name:expr => $($deps:expr),+) => (
             {
-            let d: Vec<Dependency> = vec!($($deps),+).iter().map(|s| Dependency::new(*s)).collect();
+            let d: Vec<Dependency> = vec!($($deps),+).iter().map(|s| Dependency::parse(*s, "1.0.0").unwrap()).collect();
             Summary::new(&NameVer::new($name, "1.0.0"), d.as_slice())
             }
         );
@@ -77,7 +77,7 @@ mod test {
     }
 
     fn dep(name: &str) -> Dependency {
-        Dependency::new(name)
+        Dependency::parse(name, "1.0.0").unwrap()
     }
 
     fn registry(pkgs: Vec<Summary>) -> Vec<Summary> {
index dd85444284b498bde752306cf0576e6937c00fcf..78059427c0cd2ee5db1fecac7bdd184b290c3974 100644 (file)
@@ -1,9 +1,10 @@
+use semver::Version;
 use core::{
     Dependency,
     NameVer
 };
 
-#[deriving(Show,Clone,Eq,Encodable)]
+#[deriving(Show,Clone,Eq)]
 pub struct Summary {
     name_ver: NameVer,
     dependencies: Vec<Dependency>
@@ -25,6 +26,10 @@ impl Summary {
         self.get_name_ver().get_name()
     }
 
+    pub fn get_version<'a>(&'a self) -> &'a Version {
+        self.get_name_ver().get_version()
+    }
+
     pub fn get_dependencies<'a>(&'a self) -> &'a [Dependency] {
         self.dependencies.as_slice()
     }
@@ -43,6 +48,6 @@ impl SummaryVec for Vec<Summary> {
 
     // TODO: Delete
     fn deps(&self) -> Vec<Dependency> {
-        self.iter().map(|summary| Dependency::with_namever(summary.get_name_ver())).collect()
+        self.iter().map(|summary| Dependency::exact(summary.get_name(), summary.get_version())).collect()
     }
 }
index 8d984da972b0fd5ba1247020d2472c4cc995b728..11739a0c54c40d8a853d9a0d673f5043bb584f68 100644 (file)
@@ -6,11 +6,12 @@ use std::str::CharOffsets;
 use semver::Version;
 use util::{other_error,CargoResult};
 
+#[deriving(Eq,Clone)]
 pub struct VersionReq {
     predicates: Vec<Predicate>
 }
 
-#[deriving(Eq)]
+#[deriving(Eq,Clone)]
 enum Op {
     Ex,   // Exact
     Gt,   // Greater than
@@ -19,6 +20,7 @@ enum Op {
     LtEq  // Less than or equal to
 }
 
+#[deriving(Eq,Clone)]
 struct Predicate {
     op: Op,
     major: uint,
@@ -58,12 +60,25 @@ impl VersionReq {
         Ok(VersionReq { predicates: predicates })
     }
 
+    pub fn exact(version: &Version) -> VersionReq {
+        VersionReq { predicates: vec!(Predicate::exact(version)) }
+    }
+
     pub fn matches(&self, version: &Version) -> bool {
         self.predicates.iter().all(|p| p.matches(version))
     }
 }
 
 impl Predicate {
+    pub fn exact(version: &Version) -> Predicate {
+        Predicate {
+            op: Ex,
+            major: version.major,
+            minor: Some(version.minor),
+            patch: Some(version.patch)
+        }
+    }
+
     pub fn matches(&self, ver: &Version) -> bool {
         match self.op {
             Ex => self.is_exact(ver),
index 1bb26cdf9d407e419da8ba23a984c4e082455577..0fae527c1320096fec5711eef1f3e43b9a542f37 100644 (file)
@@ -11,7 +11,7 @@ pub fn read_manifest(path: &str) -> CargoResult<Package> {
     let toml = try!(load_toml(root).map_err(|err: CargoError|
         human_error(format!("Cargo.toml is not a valid Cargo manifest"), format!("path={}", path), err)));
 
-    Ok(toml.to_package(path))
+    toml.to_package(path)
 }
 
 fn parse_from_file(path: &str) -> CargoResult<toml::Value> {