Skip to content

Commit 887ae82

Browse files
committed
auto merge of #7397 : catamorphism/rust/rustpkg_path, r=catamorphism
r? @brson Unfortunately, the main test for this is ignored due to #7071. Closes #5682
2 parents 8600c18 + ea62fd1 commit 887ae82

File tree

3 files changed

+94
-11
lines changed

3 files changed

+94
-11
lines changed

src/librustpkg/path_util.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,40 @@ 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 mut env_rust_path: ~[Path] = match os::getenv("RUST_PATH") {
45+
Some(env_path) => {
46+
let env_path_components: ~[&str] =
47+
env_path.split_str_iter(path_entry_separator).collect();
48+
env_path_components.map(|&s| Path(s))
49+
}
50+
None => ~[]
51+
};
52+
let cwd = os::getcwd();
53+
// now add in default entries
54+
env_rust_path.push(copy cwd);
55+
do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) };
56+
let h = os::homedir();
57+
for h.iter().advance |h| { push_if_exists(&mut env_rust_path, h); }
58+
env_rust_path
3059
}
3160

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

src/librustpkg/tests.rs

+53-8
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
@@ -562,13 +562,58 @@ fn package_script_with_default_build() {
562562
}
563563
564564
#[test]
565-
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
565+
#[ignore (reason = "Un-ignore when #7071 is fixed")]
566566
fn rust_path_test() {
567-
let dir = mk_workspace(&Path("/home/more_rust"),
568-
&normalize(RemotePath(Path("foo"))),
569-
&NoVersion);
570-
// command_line_test("RUST_PATH=/home/rust:/home/more_rust rustpkg install foo");
571-
command_line_test([~"install", ~"foo"], &dir);
567+
let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
568+
let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
569+
debug!("dir = %s", dir.to_str());
570+
writeFile(&Path("/Users/tjc/more_rust/src/foo-0.1/main.rs"),
571+
"fn main() { let _x = (); }");
572+
573+
let cwd = os::getcwd();
574+
debug!("cwd = %s", cwd.to_str());
575+
let mut prog = run::Process::new("rustpkg",
576+
[~"install", ~"foo"],
577+
run::ProcessOptions { env: Some(&[(~"RUST_PATH",
578+
dir_for_path.to_str())]),
579+
dir: Some(&cwd),
580+
in_fd: None,
581+
out_fd: None,
582+
err_fd: None
583+
});
584+
prog.finish_with_output();
585+
assert_executable_exists(&dir_for_path, "foo");
586+
}
587+
588+
#[test]
589+
fn rust_path_contents() {
590+
let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
591+
let abc = &dir.push("A").push("B").push("C");
592+
assert!(os::mkdir_recursive(&abc.push(".rust"), u_rwx));
593+
assert!(os::mkdir_recursive(&abc.pop().push(".rust"), u_rwx));
594+
assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), u_rwx));
595+
assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
596+
let p = rust_path();
597+
let cwd = os::getcwd().push(".rust");
598+
let parent = cwd.pop().pop().push(".rust");
599+
let grandparent = cwd.pop().pop().pop().push(".rust");
600+
assert!(vec::contains(p, &cwd));
601+
assert!(vec::contains(p, &parent));
602+
assert!(vec::contains(p, &grandparent));
603+
for p.iter().advance() |a_path| {
604+
assert!(!a_path.components.is_empty());
605+
}
606+
});
607+
}
608+
609+
#[test]
610+
fn rust_path_parse() {
611+
os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i");
612+
let paths = rust_path();
613+
assert!(vec::contains(paths, &Path("/g/h/i")));
614+
assert!(vec::contains(paths, &Path("/d/e/f")));
615+
assert!(vec::contains(paths, &Path("/a/b/c")));
616+
os::unsetenv("RUST_PATH");
572617
}
573618
574619
#[test]

src/libstd/path.rs

+9
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)