Glue together git in manifest with Source
authorYehuda Katz + Carl Lerche <engineering@tilde.io>
Thu, 12 Jun 2014 00:38:50 +0000 (17:38 -0700)
committerTim Carey-Smith <tim@spork.in>
Thu, 12 Jun 2014 00:38:50 +0000 (17:38 -0700)
src/cargo/core/manifest.rs
src/cargo/core/package.rs
src/cargo/core/source.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_read_manifest.rs
src/cargo/util/toml.rs

index 8650a8d1facca865184f73537f42520bbb305a0e..ae8000d664af5d2386b8f956fba7d529bb17a25e 100644 (file)
@@ -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<String>,
     targets: Vec<Target>,
     target_dir: Path,
+    sources: Vec<SourceId>
 }
 
 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<SourceId>) -> 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 {
index 6c9ef6a7ef0e72c09f9e1933a2b0f0f3a1ac45fe..6cd9562a1438ef87a44e3150295add2bdd68cfcf 100644 (file)
@@ -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<E, S: Encoder<E>> Encodable<S, E> 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 {
index 63ee91e525c77b62343233bb51b1d82a857adf4d..936bb23e0391b288f9fa1b7384557dddd3623a2f 100644 (file)
@@ -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<Vec<Package>>;
 }
 
+#[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<Box<Source>>
 }
index e43200a16a4c4cda6d8185f90278f20112960ace..f82040d3953899d56a0d36bbdf2160291fec9b28 100644 (file)
  */
 
 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<SourceSet> {
-    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<Box<Source>> = 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<Source>)
+            }
+        }
+    })));
+
+    sources.push_all_move(git_sources);
+
     Ok(SourceSet::new(sources))
 }
 
index 1d0f8c4c42f969638619c39aebe9757b07499c5e..fb4d15f15d944407af17338e54f008ff3b895646 100644 (file)
@@ -14,5 +14,5 @@ pub fn read_package(path: &Path, namespace: &Url) -> CargoResult<Package> {
     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))
 }
index cfbe60147d8f5e78814aa7152aad498479d66cfc..1a1b273a9a7e842a4507dc2720d6698bb029c964 100644 (file)
@@ -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<Manifest> {
@@ -112,6 +114,7 @@ impl TomlProject {
 
 impl TomlManifest {
     pub fn to_manifest(&self, namespace: &Url) -> CargoResult<Manifest> {
+        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))
     }
 }