Skip to content

Commit

Permalink
rustpkg: Implement RUST_PATH
Browse files Browse the repository at this point in the history
Unfortunately, the main test for this is ignored due to rust-lang#7071.

Closes rust-lang#5682
  • Loading branch information
catamorphism committed Jun 26, 2013
1 parent efd1438 commit 211d70e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 11 deletions.
31 changes: 28 additions & 3 deletions src/librustpkg/path_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,36 @@ 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 env_path_components: ~[&str] = env_path.split_str_iter(path_entry_separator).collect();
let mut env_rust_path: ~[Path] = env_path_components.map(|&s| Path(s));
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

This comment has been minimized.

Copy link
@brson

brson Jun 26, 2013

That's a handsome function. Good use of iterators and other library features. Tasteful type annotations.

This comment has been minimized.

Copy link
@catamorphism

catamorphism Jun 26, 2013

Author Owner

I couldn't get it to compile without the type annotations, and decided I had spent enough time trying to do so :-)

}

pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
Expand Down
58 changes: 50 additions & 8 deletions src/librustpkg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -547,13 +547,55 @@ fn rustpkg_local_pkg() {
}

#[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");

This comment has been minimized.

Copy link
@brson

brson Jun 26, 2013

I'll try to remember to apply expect. Seems like a good practice.

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));
});
}

#[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]
Expand Down
9 changes: 9 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down

1 comment on commit 211d70e

@brson
Copy link

@brson brson commented on 211d70e Jun 26, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

Please sign in to comment.