Support nested paths in git and path sources
authorYehuda Katz + Carl Lerche <engineering@tilde.io>
Wed, 18 Jun 2014 00:40:22 +0000 (17:40 -0700)
committerTim Carey-Smith <tim@spork.in>
Wed, 18 Jun 2014 00:40:22 +0000 (17:40 -0700)
src/cargo/core/source.rs
src/cargo/ops/cargo_read_manifest.rs
src/cargo/ops/mod.rs
src/cargo/sources/git/source.rs
src/cargo/sources/path.rs
tests/test_cargo_compile_git_deps.rs
tests/test_cargo_compile_path_deps.rs

index dec82d5013197cbe002638cb995a27a6ef6c0086..bd9e67898c217f9570f5cc1852023b51c2283793 100644 (file)
@@ -89,29 +89,9 @@ impl SourceId {
         }
     }
 
-    /*
-    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");
-                let ident = url_to_path_ident(&source_id.url);
-
-                // .cargo/git/db
-                // .cargo/git/checkouts
-                let db_path = git.join("db").join(ident.as_slice());
-                let checkout_path = git.join("checkouts").join(ident.as_slice()).join(reference.as_slice());
-                Ok(box GitSource::new(remote, reference.clone(), db_path, checkout_path) as Box<Source>)
-            },
-            ref PathKind => fail!("Cannot occur")
-        }
-    })));
-     */
-
     pub fn load(&self, config: &Config) -> Box<Source> {
         match self.kind {
-            GitKind(ref reference) => {
+            GitKind(..) => {
                 box GitSource::new(self, config) as Box<Source>
             },
             PathKind => box PathSource::new(self) as Box<Source>,
index 2265e28b4b001343a7132a0e46582276396e08fa..c1f723bd342054b17438206887a2770b9d55a17e 100644 (file)
@@ -1,6 +1,5 @@
 use std::io::File;
 use util;
-use url::Url;
 use core::{Package,Manifest,SourceId};
 use util::{CargoResult,io_error};
 
@@ -16,3 +15,14 @@ pub fn read_package(path: &Path, source_id: &SourceId) -> CargoResult<(Package,
 
     Ok((Package::new(manifest, path), nested))
 }
+
+pub fn read_packages(path: &Path, source_id: &SourceId) -> CargoResult<Vec<Package>> {
+    let (pkg, nested) = try!(read_package(&path.join("Cargo.toml"), source_id));
+    let mut ret = vec!(pkg);
+
+    for p in nested.iter() {
+        ret.push_all(try!(read_packages(&path.join(p), source_id)).as_slice());
+    }
+
+    Ok(ret)
+}
index f5b6356ff17808a662106a5301a440f2a2e5af87..456a56ee7daffb369ff5861ad5e9293aa72c723a 100644 (file)
@@ -1,5 +1,5 @@
 pub use self::cargo_compile::compile;
-pub use self::cargo_read_manifest::{read_manifest,read_package};
+pub use self::cargo_read_manifest::{read_manifest,read_package,read_packages};
 pub use self::cargo_rustc::compile_packages;
 
 mod cargo_compile;
index b1693326f7da191ec3cec08a71cffeb092649624..21affc5e24f8a2196fc76a1eb97c436417cccee0 100644 (file)
@@ -13,6 +13,8 @@ use core::{Package,PackageId,Summary};
 use util::{CargoResult,Config};
 use sources::git::utils::{GitReference,GitRemote,Master,Other};
 
+/* TODO: Refactor GitSource to delegate to a PathSource
+ */
 pub struct GitSource {
     id: SourceId,
     remote: GitRemote,
@@ -52,6 +54,9 @@ impl GitSource {
         self.remote.get_url()
     }
 
+    fn packages(&self) -> CargoResult<Vec<Package>> {
+        ops::read_packages(&self.checkout_path, &self.id)
+    }
 }
 
 fn ident(url: &Url) -> String {
@@ -97,34 +102,27 @@ impl Source for GitSource {
 
     fn list(&self) -> CargoResult<Vec<Summary>> {
         log!(5, "listing summaries in git source `{}`", self.remote);
-        let pkg = try!(read_manifest(&self.checkout_path, &self.id));
-        Ok(vec!(pkg.get_summary().clone()))
+        let pkgs = try!(self.packages());
+        Ok(pkgs.iter().map(|p| p.get_summary().clone()).collect())
     }
 
     fn download(&self, _: &[PackageId]) -> CargoResult<()> {
         Ok(())
     }
 
-    fn get(&self, package_ids: &[PackageId]) -> CargoResult<Vec<Package>> {
-        log!(5, "getting packages for package ids `{}` from `{}`", package_ids, self.remote);
+    fn get(&self, ids: &[PackageId]) -> CargoResult<Vec<Package>> {
+        log!(5, "getting packages for package ids `{}` from `{}`", ids, self.remote);
+
         // TODO: Support multiple manifests per repo
-        let pkg = try!(read_manifest(&self.checkout_path, &self.id));
+        let pkgs = try!(self.packages());
 
-        if package_ids.iter().any(|pkg_id| pkg_id == pkg.get_package_id()) {
-            Ok(vec!(pkg))
-        } else {
-            Ok(vec!())
-        }
+        Ok(pkgs.iter()
+           .filter(|pkg| ids.iter().any(|id| pkg.get_package_id() == id))
+           .map(|pkg| pkg.clone())
+           .collect())
     }
 }
 
-fn read_manifest(path: &Path, source_id: &SourceId) -> CargoResult<Package> {
-    let path = path.join("Cargo.toml");
-    // TODO: recurse
-    let (pkg, _) = try!(ops::read_package(&path, source_id));
-    Ok(pkg)
-}
-
 #[cfg(test)]
 mod test {
     use url;
index a4fd3744810a6872e702772d6a22663843f4f379..36b40588776a252f9d0aa3fbf269c518e4682b5a 100644 (file)
@@ -2,8 +2,7 @@ use std::fmt;
 use std::fmt::{Show,Formatter};
 use core::{Package,PackageId,Summary,SourceId,Source};
 use ops;
-use url;
-use util::{CargoResult,simple_human,io_error,realpath};
+use util::{CargoResult,simple_human};
 
 pub struct PathSource {
     id: SourceId,
@@ -33,12 +32,6 @@ impl PathSource {
         }
     }
 
-    /*
-    pub fn get_path<'a>(&'a self) -> &'a Path {
-        &self.path
-    }
-    */
-
     pub fn get_root_package(&self) -> CargoResult<Package> {
         log!(5, "get_root_package; source={}", self);
 
@@ -49,14 +42,8 @@ impl PathSource {
     }
 
     fn packages(&self) -> CargoResult<Vec<Package>> {
-        find_packages(&self.path, &self.id)
-    }
-
-    /*
-    fn get_root_manifest_path(&self) -> Path {
-        self.path.join("Cargo.toml")
+        ops::read_packages(&self.path, &self.id)
     }
-    */
 }
 
 impl Show for PathSource {
@@ -91,20 +78,3 @@ impl Source for PathSource {
            .collect())
     }
 }
-
-fn find_packages(path: &Path, source_id: &SourceId) -> CargoResult<Vec<Package>> {
-    let (pkg, nested) = try!(ops::read_package(&path.join("Cargo.toml"), source_id));
-    let mut ret = vec!(pkg);
-
-    for path in nested.iter() {
-        ret.push_all(try!(find_packages(path, source_id)).as_slice());
-    }
-
-    Ok(ret)
-}
-
-fn namespace(path: &Path) -> CargoResult<url::Url> {
-    let real = try!(realpath(path).map_err(io_error));
-    url::from_str(format!("file://{}", real.display()).as_slice()).map_err(|err|
-        simple_human(err.as_slice()))
-}
index 03675ac567a5a0005d6d0eecd1fdc836507951fe..94bcbede13dcb5ceaede7ef24daef0c2a62f564d 100644 (file)
@@ -77,3 +77,77 @@ test!(cargo_compile_simple_git_dep {
       cargo::util::process("foo").extra_path(project.root().join("target")),
       execs().with_stdout("hello world\n"));
 })
+
+test!(cargo_compile_with_nested_paths {
+    let git_project = git_repo("dep1", |project| {
+        project
+            .file("Cargo.toml", r#"
+                [project]
+
+                name = "dep1"
+                version = "0.5.0"
+                authors = ["carlhuda@example.com"]
+
+                [dependencies.dep2]
+
+                version = "0.5.0"
+                path = "vendor/dep2"
+
+                [[lib]]
+
+                name = "dep1"
+            "#)
+            .file("src/dep1.rs", r#"
+                extern crate dep2;
+
+                pub fn hello() -> &'static str {
+                    dep2::hello()
+                }
+            "#)
+            .file("vendor/dep2/Cargo.toml", r#"
+                [project]
+
+                name = "dep2"
+                version = "0.5.0"
+                authors = ["carlhuda@example.com"]
+
+                [[lib]]
+
+                name = "dep2"
+            "#)
+            .file("vendor/dep2/src/dep2.rs", r#"
+                pub fn hello() -> &'static str {
+                    "hello world"
+                }
+            "#)
+    }).assert();
+
+    let p = project("parent")
+        .file("Cargo.toml", format!(r#"
+            [project]
+
+            name = "parent"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [dependencies.dep1]
+
+            version = "0.5.0"
+            git = "file://{}"
+
+            [[bin]]
+
+            name = "parent"
+        "#, git_project.root().display()))
+        .file("src/parent.rs", main_file(r#""{}", dep1::hello()"#, ["dep1"]).as_slice());
+
+    p.cargo_process("cargo-compile")
+        .exec_with_output()
+        .assert();
+
+    assert_that(&p.root().join("target/parent"), existing_file());
+
+    assert_that(
+      cargo::util::process("parent").extra_path(p.root().join("target")),
+      execs().with_stdout("hello world\n"));
+})
index b4481e054f36d84ed2c37a7c8d0d67c27aa789fb..3428eb218ec412578c2f0745065ed9133c60a4de 100644 (file)
@@ -1,17 +1,13 @@
-use support::{ProjectBuilder,ResultTest,project,execs,main_file};
+use support::{ResultTest,project,execs,main_file};
 use hamcrest::{assert_that,existing_file};
 use cargo;
-use cargo::util::{CargoResult,process};
+use cargo::util::{process};
 
 fn setup() {
 }
 
 test!(cargo_compile_with_nested_deps_shorthand {
-    let mut p = project("foo");
-    let bar = p.root().join("bar");
-    let baz = p.root().join("baz");
-
-    p = p
+    let p = project("foo")
         .file("Cargo.toml", r#"
             [project]
 
@@ -52,7 +48,7 @@ test!(cargo_compile_with_nested_deps_shorthand {
                 baz::gimme()
             }
         "#)
-        .file("baz/Cargo.toml", r#"
+        .file("bar/baz/Cargo.toml", r#"
             [project]
 
             name = "baz"
@@ -63,7 +59,7 @@ test!(cargo_compile_with_nested_deps_shorthand {
 
             name = "baz"
         "#)
-        .file("baz/src/baz.rs", r#"
+        .file("bar/baz/src/baz.rs", r#"
             pub fn gimme() -> String {
                 "test passed".to_str()
             }