Start integrating VersionReq

This commit is contained in:
Carl Lerche 2014-05-13 12:52:13 -07:00
parent 21322f07b4
commit c96d936b99
7 changed files with 92 additions and 39 deletions

View 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 { pub struct Dependency {
name: NameVer name: ~str,
req: VersionReq
} }
impl Dependency { impl Dependency {
pub fn new(name: &str) -> Dependency { pub fn new(name: &str, req: &VersionReq) -> Dependency {
Dependency { name: NameVer::new(name.to_owned(), "1.0.0") } Dependency {
name: name.to_owned(),
req: req.clone()
}
} }
pub fn with_namever(name: &NameVer) -> Dependency { pub fn parse(name: &str, version: &str) -> CargoResult<Dependency> {
Dependency { name: name.clone() } Ok(Dependency {
name: name.to_owned(),
req: try!(VersionReq::parse(version))
})
} }
pub fn with_name_and_version(name: &str, version: &str) -> Dependency { pub fn exact(name: &str, version: &Version) -> Dependency {
Dependency { name: NameVer::new(name, version) } Dependency {
name: name.to_owned(),
req: VersionReq::exact(version)
}
} }
pub fn get_namever<'a>(&'a self) -> &'a NameVer { pub fn get_version_req<'a>(&'a self) -> &'a VersionReq {
&self.name &self.req
} }
pub fn get_name<'a>(&'a self) -> &'a str { pub fn get_name<'a>(&'a self) -> &'a str {
self.name.get_name() self.name.as_slice()
} }
} }
pub trait DependencyNameVers { #[deriving(Eq,Clone,Encodable)]
fn namevers(&self) -> Vec<NameVer>; pub struct SerializedDependency {
name: ~str,
req: ~str
} }
impl DependencyNameVers for Vec<Dependency> { impl SerializedDependency {
fn namevers(&self) -> Vec<NameVer> { pub fn from_dependency(dep: &Dependency) -> SerializedDependency {
self.iter().map(|dep| dep.get_namever().clone()).collect() SerializedDependency {
name: dep.get_name().to_owned(),
req: dep.get_version_req().to_str()
}
} }
} }

View File

@ -1,6 +1,7 @@
use std::fmt; use std::fmt;
use std::fmt::{Show,Formatter}; use std::fmt::{Show,Formatter};
use collections::HashMap; use collections::HashMap;
use semver::Version;
use serialize::{Encoder,Encodable}; use serialize::{Encoder,Encodable};
use core::{ use core::{
Dependency, Dependency,
@ -8,6 +9,8 @@ use core::{
Package, Package,
Summary Summary
}; };
use core::dependency::SerializedDependency;
use util::CargoResult;
#[deriving(Eq,Clone)] #[deriving(Eq,Clone)]
pub struct Manifest { pub struct Manifest {
@ -25,7 +28,9 @@ impl Show for Manifest {
#[deriving(Eq,Clone,Encodable)] #[deriving(Eq,Clone,Encodable)]
pub struct SerializedManifest { pub struct SerializedManifest {
summary: Summary, name: ~str,
version: ~str,
dependencies: Vec<SerializedDependency>,
authors: Vec<~str>, authors: Vec<~str>,
targets: Vec<Target>, targets: Vec<Target>,
target_dir: ~str target_dir: ~str
@ -34,7 +39,9 @@ pub struct SerializedManifest {
impl<E, S: Encoder<E>> Encodable<S, E> for Manifest { impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
fn encode(&self, s: &mut S) -> Result<(), E> { fn encode(&self, s: &mut S) -> Result<(), E> {
SerializedManifest { 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(), authors: self.authors.clone(),
targets: self.targets.clone(), targets: self.targets.clone(),
target_dir: self.target_dir.as_str().unwrap().to_owned() target_dir: self.target_dir.as_str().unwrap().to_owned()
@ -101,6 +108,10 @@ impl Manifest {
self.get_summary().get_name_ver().get_name() 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] { pub fn get_authors<'a>(&'a self) -> &'a [~str] {
self.authors.as_slice() self.authors.as_slice()
} }
@ -176,30 +187,34 @@ pub struct TomlManifest {
} }
impl 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 // TODO: Convert hte argument to take a Path
let path = Path::new(path); let path = Path::new(path);
// Get targets // Get targets
let targets = normalize(&self.lib, &self.bin); let targets = normalize(&self.lib, &self.bin);
// Get deps
let deps = self.dependencies.clone().map(|deps| { let mut deps = Vec::new();
deps.iter().map(|(k,v)| {
// This can produce an invalid version, but it's temporary because this needs // Collect the deps
// to be replaced with Dependency, not NameVer match self.dependencies {
Dependency::with_namever(&NameVer::new(k.clone(), v.clone())) Some(ref dependencies) => {
}).collect() for (n, v) in dependencies.iter() {
}).unwrap_or_else(|| vec!()); deps.push(try!(Dependency::parse(*n, *v)));
}
}
None => ()
}
// TODO: https://github.com/mozilla/rust/issues/14049 // TODO: https://github.com/mozilla/rust/issues/14049
let root = Path::new(path.dirname()); let root = Path::new(path.dirname());
Package::new( Ok(Package::new(
&Manifest::new( &Manifest::new(
&Summary::new(&self.project.to_name_ver(), deps.as_slice()), &Summary::new(&self.project.to_name_ver(), deps.as_slice()),
targets.as_slice(), targets.as_slice(),
&Path::new("target")), &Path::new("target")),
&root) &root))
} }
} }

View File

@ -9,6 +9,7 @@ use core::{
Target, Target,
Summary Summary
}; };
use core::dependency::SerializedDependency;
use util::graph; use util::graph;
use serialize::{Encoder,Encodable}; use serialize::{Encoder,Encodable};
@ -24,7 +25,7 @@ pub struct Package {
struct SerializedPackage { struct SerializedPackage {
name: ~str, name: ~str,
version: ~str, version: ~str,
dependencies: Vec<Dependency>, dependencies: Vec<SerializedDependency>,
authors: Vec<~str>, authors: Vec<~str>,
targets: Vec<Target>, targets: Vec<Target>,
root: ~str root: ~str
@ -39,7 +40,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Package {
SerializedPackage { SerializedPackage {
name: name_ver.get_name().to_owned(), name: name_ver.get_name().to_owned(),
version: name_ver.get_version().to_str(), 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()), authors: Vec::from_slice(manifest.get_authors()),
targets: Vec::from_slice(manifest.get_targets()), targets: Vec::from_slice(manifest.get_targets()),
root: self.root.as_str().unwrap().to_owned() root: self.root.as_str().unwrap().to_owned()
@ -56,7 +57,7 @@ impl Package {
} }
pub fn to_dependency(&self) -> Dependency { 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 { pub fn get_manifest<'a>(&'a self) -> &'a Manifest {

View File

@ -62,7 +62,7 @@ mod test {
macro_rules! pkg( macro_rules! pkg(
($name:expr => $($deps:expr),+) => ( ($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()) Summary::new(&NameVer::new($name, "1.0.0"), d.as_slice())
} }
); );
@ -77,7 +77,7 @@ mod test {
} }
fn dep(name: &str) -> Dependency { fn dep(name: &str) -> Dependency {
Dependency::new(name) Dependency::parse(name, "1.0.0").unwrap()
} }
fn registry(pkgs: Vec<Summary>) -> Vec<Summary> { fn registry(pkgs: Vec<Summary>) -> Vec<Summary> {

View File

@ -1,9 +1,10 @@
use semver::Version;
use core::{ use core::{
Dependency, Dependency,
NameVer NameVer
}; };
#[deriving(Show,Clone,Eq,Encodable)] #[deriving(Show,Clone,Eq)]
pub struct Summary { pub struct Summary {
name_ver: NameVer, name_ver: NameVer,
dependencies: Vec<Dependency> dependencies: Vec<Dependency>
@ -25,6 +26,10 @@ impl Summary {
self.get_name_ver().get_name() 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] { pub fn get_dependencies<'a>(&'a self) -> &'a [Dependency] {
self.dependencies.as_slice() self.dependencies.as_slice()
} }
@ -43,6 +48,6 @@ impl SummaryVec for Vec<Summary> {
// TODO: Delete // TODO: Delete
fn deps(&self) -> Vec<Dependency> { 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()
} }
} }

View File

@ -6,11 +6,12 @@ use std::str::CharOffsets;
use semver::Version; use semver::Version;
use util::{other_error,CargoResult}; use util::{other_error,CargoResult};
#[deriving(Eq,Clone)]
pub struct VersionReq { pub struct VersionReq {
predicates: Vec<Predicate> predicates: Vec<Predicate>
} }
#[deriving(Eq)] #[deriving(Eq,Clone)]
enum Op { enum Op {
Ex, // Exact Ex, // Exact
Gt, // Greater than Gt, // Greater than
@ -19,6 +20,7 @@ enum Op {
LtEq // Less than or equal to LtEq // Less than or equal to
} }
#[deriving(Eq,Clone)]
struct Predicate { struct Predicate {
op: Op, op: Op,
major: uint, major: uint,
@ -58,12 +60,25 @@ impl VersionReq {
Ok(VersionReq { predicates: predicates }) Ok(VersionReq { predicates: predicates })
} }
pub fn exact(version: &Version) -> VersionReq {
VersionReq { predicates: vec!(Predicate::exact(version)) }
}
pub fn matches(&self, version: &Version) -> bool { pub fn matches(&self, version: &Version) -> bool {
self.predicates.iter().all(|p| p.matches(version)) self.predicates.iter().all(|p| p.matches(version))
} }
} }
impl Predicate { 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 { pub fn matches(&self, ver: &Version) -> bool {
match self.op { match self.op {
Ex => self.is_exact(ver), Ex => self.is_exact(ver),

View File

@ -11,7 +11,7 @@ pub fn read_manifest(path: &str) -> CargoResult<Package> {
let toml = try!(load_toml(root).map_err(|err: CargoError| 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))); 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> { fn parse_from_file(path: &str) -> CargoResult<toml::Value> {