about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-06-25 19:49:01 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-06-27 21:41:03 -0700
commitea62fd1090fda26e1e4b68bdc7ef2e11864d80b6 (patch)
treef96628b6e5f499e6c55a27da069634cb8fbd8cea
parent9b6dfb85782a6ec50c39292626acf2c74b0ae754 (diff)
downloadrust-ea62fd1090fda26e1e4b68bdc7ef2e11864d80b6.tar.gz
rust-ea62fd1090fda26e1e4b68bdc7ef2e11864d80b6.zip
rustpkg: Implement RUST_PATH
Unfortunately, the main test for this is ignored due to #7071.

Closes #5682
-rw-r--r--src/librustpkg/path_util.rs35
-rw-r--r--src/librustpkg/tests.rs61
-rw-r--r--src/libstd/path.rs9
3 files changed, 94 insertions, 11 deletions
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index 6d146145f36..c0425b4d260 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -22,11 +22,40 @@ use core::iterator::IteratorUtil;
 use messages::*;
 use package_id::*;
 
+fn push_if_exists(vec: &mut ~[Path], p: &Path) {
+    let maybe_dir = p.push(".rust");
+    if os::path_exists(&maybe_dir) {
+        vec.push(maybe_dir);
+    }
+}
+
+#[cfg(windows)]
+static path_entry_separator: &'static str = ";";
+#[cfg(not(windows))]
+static path_entry_separator: &'static str = ":";
+
 /// Returns the value of RUST_PATH, as a list
-/// of Paths. In general this should be read from the
-/// environment; for now, it's hard-wired to just be "."
+/// of Paths. Includes default entries for, if they exist:
+/// $HOME/.rust
+/// DIR/.rust for any DIR that's the current working directory
+/// or an ancestor of it
 pub fn rust_path() -> ~[Path] {
-    ~[Path(".")]
+    let env_path: ~str = os::getenv("RUST_PATH").get_or_default(~"");
+    let mut env_rust_path: ~[Path] = match os::getenv("RUST_PATH") {
+        Some(env_path) => {
+            let env_path_components: ~[&str] =
+                env_path.split_str_iter(path_entry_separator).collect();
+            env_path_components.map(|&s| Path(s))
+        }
+        None => ~[]
+    };
+    let cwd = os::getcwd();
+    // now add in default entries
+    env_rust_path.push(copy cwd);
+    do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) };
+    let h = os::homedir();
+    for h.iter().advance |h| { push_if_exists(&mut env_rust_path, h); }
+    env_rust_path
 }
 
 pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index afeb6407533..8d8628c7718 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -12,7 +12,7 @@
 
 use context::Ctx;
 use core::hashmap::HashMap;
-use core::{io, libc, os, result, run, str};
+use core::{io, libc, os, result, run, str, vec};
 use core::prelude::*;
 use extra::tempfile::mkdtemp;
 use core::run::ProcessOutput;
@@ -25,7 +25,7 @@ use path_util::{target_executable_in_workspace, target_library_in_workspace,
                make_dir_rwx, u_rwx, library_in_workspace,
                built_bench_in_workspace, built_test_in_workspace,
                built_library_in_workspace, built_executable_in_workspace,
-                installed_library_in_workspace};
+                installed_library_in_workspace, rust_path};
 use target::*;
 
 /// Returns the last-modified date as an Option
@@ -562,13 +562,58 @@ fn package_script_with_default_build() {
 }
 
 #[test]
-#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
+#[ignore (reason = "Un-ignore when #7071 is fixed")]
 fn rust_path_test() {
-    let dir = mk_workspace(&Path("/home/more_rust"),
-                           &normalize(RemotePath(Path("foo"))),
-                           &NoVersion);
-  //  command_line_test("RUST_PATH=/home/rust:/home/more_rust rustpkg install foo");
-    command_line_test([~"install", ~"foo"], &dir);
+    let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
+    let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
+    debug!("dir = %s", dir.to_str());
+    writeFile(&Path("/Users/tjc/more_rust/src/foo-0.1/main.rs"),
+              "fn main() { let _x = (); }");
+
+    let cwd = os::getcwd();
+    debug!("cwd = %s", cwd.to_str());
+    let mut prog = run::Process::new("rustpkg",
+                                     [~"install", ~"foo"],
+                                     run::ProcessOptions { env: Some(&[(~"RUST_PATH",
+                                                                       dir_for_path.to_str())]),
+                                                          dir: Some(&cwd),
+                                                          in_fd: None,
+                                                          out_fd: None,
+                                                          err_fd: None
+                                                         });
+    prog.finish_with_output();
+    assert_executable_exists(&dir_for_path, "foo");
+}
+
+#[test]
+fn rust_path_contents() {
+    let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
+    let abc = &dir.push("A").push("B").push("C");
+    assert!(os::mkdir_recursive(&abc.push(".rust"), u_rwx));
+    assert!(os::mkdir_recursive(&abc.pop().push(".rust"), u_rwx));
+    assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), u_rwx));
+    assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
+        let p = rust_path();
+        let cwd = os::getcwd().push(".rust");
+        let parent = cwd.pop().pop().push(".rust");
+        let grandparent = cwd.pop().pop().pop().push(".rust");
+        assert!(vec::contains(p, &cwd));
+        assert!(vec::contains(p, &parent));
+        assert!(vec::contains(p, &grandparent));
+        for p.iter().advance() |a_path| {
+            assert!(!a_path.components.is_empty());
+        }
+    });
+}
+
+#[test]
+fn rust_path_parse() {
+    os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i");
+    let paths = rust_path();
+    assert!(vec::contains(paths, &Path("/g/h/i")));
+    assert!(vec::contains(paths, &Path("/d/e/f")));
+    assert!(vec::contains(paths, &Path("/a/b/c")));
+    os::unsetenv("RUST_PATH");
 }
 
 #[test]
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 700bfff3f5d..89792694011 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -382,6 +382,15 @@ impl Path {
             Some(ref st) => Some(st.st_mode as uint),
         }
     }
+
+    /// Execute a function on p as well as all of its ancestors
+    pub fn each_parent(&self, f: &fn(&Path)) {
+        if !self.components.is_empty() {
+            f(self);
+            self.pop().each_parent(f);
+        }
+    }
+
 }
 
 #[cfg(target_os = "freebsd")]