diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 8650a8d1f..ae8000d66 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -2,9 +2,11 @@ use std::fmt; use std::fmt::{Show,Formatter}; use semver::Version; use serialize::{Encoder,Encodable}; +use core::source::SourceId; use core::{ Dependency, PackageId, + Source, Summary }; use core::dependency::SerializedDependency; @@ -15,6 +17,7 @@ pub struct Manifest { authors: Vec, targets: Vec, target_dir: Path, + sources: Vec } impl Show for Manifest { @@ -88,12 +91,13 @@ impl Show for Target { } impl Manifest { - pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path) -> Manifest { + pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path, sources: Vec) -> Manifest { Manifest { summary: summary.clone(), authors: Vec::new(), targets: Vec::from_slice(targets), - target_dir: target_dir.clone() + target_dir: target_dir.clone(), + sources: sources } } @@ -128,6 +132,10 @@ impl Manifest { pub fn get_target_dir<'a>(&'a self) -> &'a Path { &self.target_dir } + + pub fn get_sources<'a>(&'a self) -> &'a [SourceId] { + self.sources.as_slice() + } } impl Target { diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index 6c9ef6a7e..6cd9562a1 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -14,6 +14,7 @@ use core::{ use core::dependency::SerializedDependency; use util::graph; use serialize::{Encoder,Encodable}; +use core::source::SourceId; #[deriving(Clone,PartialEq)] pub struct Package { @@ -51,9 +52,9 @@ impl> Encodable for Package { } impl Package { - pub fn new(manifest: &Manifest, manifest_path: &Path) -> Package { + pub fn new(manifest: Manifest, manifest_path: &Path) -> Package { Package { - manifest: manifest.clone(), + manifest: manifest, manifest_path: manifest_path.clone() } } @@ -105,6 +106,10 @@ impl Package { pub fn get_absolute_target_dir(&self) -> Path { self.get_root().join(self.get_target_dir()) } + + pub fn get_sources<'a>(&'a self) -> &'a [SourceId] { + self.manifest.get_sources() + } } impl Show for Package { diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index 63ee91e52..936bb23e0 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -1,5 +1,7 @@ +use url::Url; use core::{Summary,Package,PackageId}; use util::CargoResult; +use sources::GitSource; /** * A Source finds and downloads remote packages based on names and @@ -36,6 +38,23 @@ pub trait Source { fn get(&self, packages: &[PackageId]) -> CargoResult>; } +#[deriving(Clone,PartialEq)] +pub enum SourceKind { + GitKind(String) +} + +#[deriving(Clone,PartialEq)] +pub struct SourceId { + pub kind: SourceKind, + pub url: Url +} + +impl SourceId { + pub fn new(kind: SourceKind, url: Url) -> SourceId { + SourceId { kind: kind, url: url } + } +} + pub struct SourceSet { sources: Vec> } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index e43200a16..f82040d39 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -15,13 +15,16 @@ */ use std::os; +use std::result; use util::config; use util::config::{ConfigValue}; use core::{Package,PackageSet,Source,SourceSet}; use core::resolver::resolve; -use sources::path::PathSource; +use core::source::{GitKind,SourceId}; +use sources::{PathSource,GitSource}; +use sources::git::GitRemote; use ops; -use util::{other_error, CargoResult, Wrap}; +use util::{CargoResult, Wrap, Require, simple_human, other_error}; pub fn compile(manifest_path: &Path) -> CargoResult<()> { log!(4, "compile; manifest-path={}", manifest_path.display()); @@ -49,7 +52,25 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> { } fn sources_for(package: &Package) -> CargoResult { - let sources = try!(sources_from_config([package.get_manifest_path().dir_path()])); + let mut sources = try!(sources_from_config([package.get_manifest_path().dir_path()])); + + let git_sources: Vec> = try!(result::collect(package.get_sources().iter().map(|source_id: &SourceId| { + match source_id.kind { + GitKind(ref reference) => { + let remote = GitRemote::new(source_id.url.clone(), false); + let home = try!(os::homedir().require(simple_human("Cargo couldn't find a home directory"))); + let git = home.join(".cargo").join("git"); + // .cargo/git/db + // .cargo/git/checkouts + let db_path = git.join("db").join(source_id.url.to_str()); + let checkout_path = git.join("checkouts").join(source_id.url.to_str()).join(reference.as_slice()); + Ok(box GitSource::new(remote, reference.clone(), db_path, checkout_path, false) as Box) + } + } + }))); + + sources.push_all_move(git_sources); + Ok(SourceSet::new(sources)) } diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index 1d0f8c4c4..fb4d15f15 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -14,5 +14,5 @@ pub fn read_package(path: &Path, namespace: &Url) -> CargoResult { let data = try!(file.read_to_end().map_err(io_error)); let manifest = try!(read_manifest(data.as_slice(), namespace)); - Ok(Package::new(&manifest, path)) + Ok(Package::new(manifest, path)) } diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index cfbe60147..1a1b273a9 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -1,9 +1,11 @@ use toml; +use url; use url::Url; use std::collections::HashMap; use serialize::Decodable; -use core::{Summary,Manifest,Target,Dependency,PackageId}; +use core::source::{SourceId,GitKind}; +use core::{Summary,Manifest,Target,Dependency,PackageId,Source}; use util::{CargoResult,Require,simple_human,toml_error}; pub fn to_manifest(contents: &[u8], namespace: &Url) -> CargoResult { @@ -112,6 +114,7 @@ impl TomlProject { impl TomlManifest { pub fn to_manifest(&self, namespace: &Url) -> CargoResult { + let mut sources = vec!(); // Get targets let targets = normalize(self.lib.as_ref().map(|l| l.as_slice()), self.bin.as_ref().map(|b| b.as_slice())); @@ -128,7 +131,15 @@ impl TomlManifest { for (n, v) in dependencies.iter() { let version = match *v { SimpleDep(ref string) => string.clone(), - DetailedDep(ref details) => details.version.clone() + DetailedDep(ref details) => { + details.other.find_equiv(&"git").map(|git| { + // TODO: Don't unwrap here + let kind = GitKind("master".to_str()); + let url = url::from_str(git.as_slice()).unwrap(); + sources.push(SourceId::new(kind, url)); + }); + details.version.clone() + } }; deps.push(try!(Dependency::parse(n.as_slice(), version.as_slice()))) @@ -140,7 +151,8 @@ impl TomlManifest { Ok(Manifest::new( &Summary::new(&self.project.to_package_id(namespace), deps.as_slice()), targets.as_slice(), - &Path::new("target"))) + &Path::new("target"), + sources)) } }