Skip to content

Commit 211d70e

Browse files
committed
rustpkg: Implement RUST_PATH
Unfortunately, the main test for this is ignored due to rust-lang#7071. Closes rust-lang#5682
1 parent efd1438 commit 211d70e

File tree

3 files changed

+87
-11
lines changed

3 files changed

+87
-11
lines changed

src/librustpkg/path_util.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,36 @@ use core::iterator::IteratorUtil;
2222
use messages::*;
2323
use package_id::*;
2424

25+
fn push_if_exists(vec: &mut ~[Path], p: &Path) {
26+
let maybe_dir = p.push(".rust");
27+
if os::path_exists(&maybe_dir) {
28+
vec.push(maybe_dir);
29+
}
30+
}
31+
32+
#[cfg(windows)]
33+
static path_entry_separator: &'static str = ";";
34+
#[cfg(not(windows))]
35+
static path_entry_separator: &'static str = ":";
36+
2537
/// Returns the value of RUST_PATH, as a list
26-
/// of Paths. In general this should be read from the
27-
/// environment; for now, it's hard-wired to just be "."
38+
/// of Paths. Includes default entries for, if they exist:
39+
/// $HOME/.rust
40+
/// DIR/.rust for any DIR that's the current working directory
41+
/// or an ancestor of it
2842
pub fn rust_path() -> ~[Path] {
29-
~[Path(".")]
43+
let env_path: ~str = os::getenv("RUST_PATH").get_or_default(~"");
44+
let env_path_components: ~[&str] = env_path.split_str_iter(path_entry_separator).collect();
45+
let mut env_rust_path: ~[Path] = env_path_components.map(|&s| Path(s));
46+
let cwd = os::getcwd();
47+
// now add in default entries
48+
env_rust_path.push(copy cwd);
49+
do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) };
50+
let h = os::homedir();
51+
for h.iter().advance |h| {
52+
push_if_exists(&mut env_rust_path, h);
53+
}
54+
env_rust_path
3055
}
3156

3257
pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;

src/librustpkg/tests.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
use context::Ctx;
1414
use core::hashmap::HashMap;
15-
use core::{io, libc, os, result, run, str};
15+
use core::{io, libc, os, result, run, str, vec};
1616
use core::prelude::*;
1717
use extra::tempfile::mkdtemp;
1818
use core::run::ProcessOutput;
@@ -25,7 +25,7 @@ use path_util::{target_executable_in_workspace, target_library_in_workspace,
2525
make_dir_rwx, u_rwx, library_in_workspace,
2626
built_bench_in_workspace, built_test_in_workspace,
2727
built_library_in_workspace, built_executable_in_workspace,
28-
installed_library_in_workspace};
28+
installed_library_in_workspace, rust_path};
2929
use target::*;
3030

3131
/// Returns the last-modified date as an Option
@@ -547,13 +547,55 @@ fn rustpkg_local_pkg() {
547547
}
548548
549549
#[test]
550-
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
550+
#[ignore (reason = "Un-ignore when #7071 is fixed")]
551551
fn rust_path_test() {
552-
let dir = mk_workspace(&Path("/home/more_rust"),
553-
&normalize(RemotePath(Path("foo"))),
554-
&NoVersion);
555-
// command_line_test("RUST_PATH=/home/rust:/home/more_rust rustpkg install foo");
556-
command_line_test([~"install", ~"foo"], &dir);
552+
let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
553+
let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
554+
debug!("dir = %s", dir.to_str());
555+
writeFile(&Path("/Users/tjc/more_rust/src/foo-0.1/main.rs"),
556+
"fn main() { let _x = (); }");
557+
558+
let cwd = os::getcwd();
559+
debug!("cwd = %s", cwd.to_str());
560+
let mut prog = run::Process::new("rustpkg",
561+
[~"install", ~"foo"],
562+
run::ProcessOptions { env: Some(&[(~"RUST_PATH",
563+
dir_for_path.to_str())]),
564+
dir: Some(&cwd),
565+
in_fd: None,
566+
out_fd: None,
567+
err_fd: None
568+
});
569+
prog.finish_with_output();
570+
assert_executable_exists(&dir_for_path, "foo");
571+
}
572+
573+
#[test]
574+
fn rust_path_contents() {
575+
let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
576+
let abc = &dir.push("A").push("B").push("C");
577+
assert!(os::mkdir_recursive(&abc.push(".rust"), u_rwx));
578+
assert!(os::mkdir_recursive(&abc.pop().push(".rust"), u_rwx));
579+
assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), u_rwx));
580+
assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
581+
let p = rust_path();
582+
let cwd = os::getcwd().push(".rust");
583+
let parent = cwd.pop().pop().push(".rust");
584+
let grandparent = cwd.pop().pop().pop().push(".rust");
585+
assert!(vec::contains(p, &cwd));
586+
assert!(vec::contains(p, &parent));
587+
assert!(vec::contains(p, &grandparent));
588+
});
589+
}
590+
591+
#[test]
592+
fn rust_path_parse() {
593+
os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i");
594+
let paths = rust_path();
595+
assert!(vec::contains(paths, &Path("/g/h/i")));
596+
assert!(vec::contains(paths, &Path("/d/e/f")));
597+
assert!(vec::contains(paths, &Path("/a/b/c")));
598+
os::unsetenv("RUST_PATH");
557599
}
558600
559601
#[test]

src/libstd/path.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,15 @@ impl Path {
382382
Some(ref st) => Some(st.st_mode as uint),
383383
}
384384
}
385+
386+
/// Execute a function on p as well as all of its ancestors
387+
pub fn each_parent(&self, f: &fn(&Path)) {
388+
if !self.components.is_empty() {
389+
f(self);
390+
self.pop().each_parent(f);
391+
}
392+
}
393+
385394
}
386395

387396
#[cfg(target_os = "freebsd")]

0 commit comments

Comments
 (0)