about summary refs log tree commit diff
path: root/src/librustpkg
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-06-26 17:42:24 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-07-18 17:28:40 -0700
commite39ea2a5c880b252abbf37dade7a9b7ce7b2cb40 (patch)
treec0fe8f89d4a7138494bf00f7c0ac007c4b9260a8 /src/librustpkg
parent78f8b407e3ab5590a57467fce1febd5289bf7fe5 (diff)
downloadrust-e39ea2a5c880b252abbf37dade7a9b7ce7b2cb40.tar.gz
rust-e39ea2a5c880b252abbf37dade7a9b7ce7b2cb40.zip
rustpkg: Make rustpkg commands work without a package ID
`rustpkg build`, if executed in a package source directory inside
a workspace, will now build that package. By "inside a workspace"
I mean that the parent directory has to be called `src`, and rustpkg
will create a `build` directory in .. if there isn't already one.

Same goes for `rustpkg install` and `rustpkg clean`.

For the time being, `rustpkg build` (etc.) will still error out if
you run it inside a directory whose parent isn't called `src`.
I'm not sure whether or not it's desirable to have it do something
in a non-workspace directory.
Diffstat (limited to 'src/librustpkg')
-rw-r--r--src/librustpkg/installed_packages.rs11
-rw-r--r--src/librustpkg/path_util.rs10
-rw-r--r--src/librustpkg/rustpkg.rs90
-rw-r--r--src/librustpkg/tests.rs96
-rw-r--r--src/librustpkg/usage.rs7
-rw-r--r--src/librustpkg/workspace.rs24
6 files changed, 169 insertions, 69 deletions
diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs
index 6b28b7ed6a1..5f1e0594c47 100644
--- a/src/librustpkg/installed_packages.rs
+++ b/src/librustpkg/installed_packages.rs
@@ -18,11 +18,18 @@ pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool  {
     for workspaces.iter().advance |p| {
         let binfiles = os::list_dir(&p.push("bin"));
         for binfiles.iter().advance() |exec| {
-            f(&PkgId::new(*exec, p));
+            let exec_path = Path(*exec).filestem();
+            do exec_path.iter().advance |s| {
+                f(&PkgId::new(*s, p))
+            };
         }
         let libfiles = os::list_dir(&p.push("lib"));
         for libfiles.iter().advance() |lib| {
-            f(&PkgId::new(*lib, p));
+            debug!("Full name: %s", *lib);
+            let lib_path = Path(*lib).filestem();
+            do lib_path.iter().advance |s| {
+                f(&PkgId::new(*s, p))
+            };
         }
     }
     true
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index a2cae3ab20e..ed5b1118a9c 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -54,11 +54,17 @@ pub fn rust_path() -> ~[Path] {
     };
     let cwd = os::getcwd();
     // now add in default entries
-    env_rust_path.push(cwd.push(".rust"));
     env_rust_path.push(cwd.clone());
     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); }
+    // Avoid adding duplicates
+    // could still add dups if someone puts one of these in the RUST_PATH
+    // manually, though...
+    for h.iter().advance |hdir| {
+        if !(cwd.is_ancestor_of(hdir) || hdir.is_ancestor_of(&cwd)) {
+            push_if_exists(&mut env_rust_path, hdir);
+        }
+    }
     env_rust_path
 }
 
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
index f2845c00ea6..f2e39a8e5ed 100644
--- a/src/librustpkg/rustpkg.rs
+++ b/src/librustpkg/rustpkg.rs
@@ -42,7 +42,7 @@ use path_util::{U_RWX, rust_path, in_rust_path};
 use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
 use path_util::{target_executable_in_workspace, target_library_in_workspace};
 use source_control::is_git_dir;
-use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces};
+use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces, in_workspace, cwd_to_workspace};
 use context::Ctx;
 use package_id::PkgId;
 use package_source::PkgSrc;
@@ -199,26 +199,41 @@ impl CtxMethods for Ctx {
         match cmd {
             "build" => {
                 if args.len() < 1 {
-                    return usage::build();
+                    if !in_workspace(|| { usage::build() } ) {
+                        return;
+                    }
+                    let (workspace, pkgid) = cwd_to_workspace();
+                    self.build(&workspace, &pkgid);
                 }
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
-                for each_pkg_parent_workspace(&pkgid) |workspace| {
-                    debug!("found pkg %s in workspace %s, trying to build",
-                           pkgid.to_str(), workspace.to_str());
-                    self.build(workspace, &pkgid);
+                else {
+                    // The package id is presumed to be the first command-line
+                    // argument
+                    let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
+                    for each_pkg_parent_workspace(&pkgid) |workspace| {
+                        debug!("found pkg %s in workspace %s, trying to build",
+                               pkgid.to_str(), workspace.to_str());
+                        self.build(workspace, &pkgid);
+                    }
                 }
             }
             "clean" => {
                 if args.len() < 1 {
-                    return usage::build();
+                    if !in_workspace(|| { usage::clean() } ) {
+                        return;
+                    }
+                    // tjc: Maybe clean should clean all the packages in the
+                    // current workspace, though?
+                    let (workspace, pkgid) = cwd_to_workspace();
+                    self.clean(&workspace, &pkgid);
+
+                }
+                else {
+                    // The package id is presumed to be the first command-line
+                    // argument
+                    let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
+                    let cwd = os::getcwd();
+                    self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
                 }
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
-                let cwd = os::getcwd();
-                self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
             }
             "do" => {
                 if args.len() < 2 {
@@ -232,37 +247,36 @@ impl CtxMethods for Ctx {
             }
             "install" => {
                 if args.len() < 1 {
-                    return usage::install();
-                }
-
-                // The package id is presumed to be the first command-line
-                // argument
-                let pkgid = PkgId::new(args[0], &os::getcwd());
-                let workspaces = pkg_parent_workspaces(&pkgid);
-                if workspaces.is_empty() {
-                    debug!("install! workspaces was empty");
-                    let rp = rust_path();
-                    assert!(!rp.is_empty());
-                    let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]),
-                                          &pkgid);
-                    src.fetch_git();
-                    self.install(&rp[0], &pkgid);
+                    if !in_workspace(|| { usage::install() }) {
+                        return;
+                    }
+                    let (workspace, pkgid) = cwd_to_workspace();
+                    self.install(&workspace, &pkgid);
                 }
                 else {
-                    for each_pkg_parent_workspace(&pkgid) |workspace| {
-                        debug!("install: found pkg %s in workspace %s, trying to build",
-                               pkgid.to_str(), workspace.to_str());
-
-                        self.install(workspace, &pkgid);
+                    // The package id is presumed to be the first command-line
+                    // argument
+                    let pkgid = PkgId::new(args[0], &os::getcwd());
+                    let workspaces = pkg_parent_workspaces(&pkgid);
+                    if workspaces.is_empty() {
+                        let rp = rust_path();
+                        assert!(!rp.is_empty());
+                        let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]),
+                                              &pkgid);
+                        src.fetch_git();
+                        self.install(&rp[0], &pkgid);
+                    }
+                    else {
+                        for each_pkg_parent_workspace(&pkgid) |workspace| {
+                            self.install(workspace, &pkgid);
+                        }
                     }
                 }
             }
             "list" => {
                 io::println("Installed packages:");
                 for installed_packages::list_installed_packages |pkg_id| {
-                    io::println(fmt!("%s-%s",
-                                     pkg_id.local_path.to_str(),
-                                     pkg_id.version.to_str()));
+                    io::println(pkg_id.local_path.to_str());
                 }
             }
             "prefer" => {
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index f6044cbf01f..7953d4545a8 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -218,7 +218,6 @@ fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
 fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
     -> ProcessOutput {
     let cmd = test_sysroot().push("bin").push("rustpkg").to_str();
-    let cwd = normalize(RemotePath((*cwd).clone()));
     debug!("About to run command: %? %? in %s", cmd, args, cwd.to_str());
     assert!(os::path_is_dir(&*cwd));
     let cwd = (*cwd).clone();
@@ -322,6 +321,14 @@ fn assert_executable_exists(repo: &Path, short_name: &str) {
     assert!(is_rwx(&exec));
 }
 
+fn assert_built_executable_exists(repo: &Path, short_name: &str) {
+    debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
+    let exec = built_executable_in_workspace(&PkgId::new(short_name, repo),
+                                             repo).expect("assert_built_executable_exists failed");
+    assert!(os::path_exists(&exec));
+    assert!(is_rwx(&exec));
+}
+
 fn command_line_test_output(args: &[~str]) -> ~[~str] {
     let mut result = ~[];
     let p_output = command_line_test(args, &os::getcwd());
@@ -490,30 +497,29 @@ fn test_install_git() {
     // should have test, bench, lib, and main
     command_line_test([~"install", temp_pkg_id.local_path.to_str()], &repo);
     // Check that all files exist
-    let ws = repo.push(".rust");
-    debug!("Checking for files in %s", ws.to_str());
-    let exec = target_executable_in_workspace(&temp_pkg_id, &ws);
+    debug!("Checking for files in %s", repo.to_str());
+    let exec = target_executable_in_workspace(&temp_pkg_id, &repo);
     debug!("exec = %s", exec.to_str());
     assert!(os::path_exists(&exec));
     assert!(is_rwx(&exec));
     let _built_lib =
         built_library_in_workspace(&temp_pkg_id,
-                                   &ws).expect("test_install_git: built lib should exist");
-    let lib = target_library_in_workspace(&temp_pkg_id, &ws);
+                                   &repo).expect("test_install_git: built lib should exist");
+    let lib = target_library_in_workspace(&temp_pkg_id, &repo);
     debug!("lib = %s", lib.to_str());
     assert!(os::path_exists(&lib));
     assert!(is_rwx(&lib));
     let built_test = built_test_in_workspace(&temp_pkg_id,
-                         &ws).expect("test_install_git: built test should exist");
+                         &repo).expect("test_install_git: built test should exist");
     assert!(os::path_exists(&built_test));
     let built_bench = built_bench_in_workspace(&temp_pkg_id,
-                          &ws).expect("test_install_git: built bench should exist");
+                          &repo).expect("test_install_git: built bench should exist");
     assert!(os::path_exists(&built_bench));
     // And that the test and bench executables aren't installed
-    let test = target_test_in_workspace(&temp_pkg_id, &ws);
+    let test = target_test_in_workspace(&temp_pkg_id, &repo);
     assert!(!os::path_exists(&test));
     debug!("test = %s", test.to_str());
-    let bench = target_bench_in_workspace(&temp_pkg_id, &ws);
+    let bench = target_bench_in_workspace(&temp_pkg_id, &repo);
     debug!("bench = %s", bench.to_str());
     assert!(!os::path_exists(&bench));
 }
@@ -586,12 +592,12 @@ fn test_package_version() {
     command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg_version"],
                       &repo);
     assert!(match built_library_in_workspace(&temp_pkg_id,
-                                             &repo.push(".rust")) {
+                                             &repo) {
         Some(p) => p.to_str().ends_with(fmt!("0.4%s", os::consts::DLL_SUFFIX)),
         None    => false
     });
-    assert!(built_executable_in_workspace(&temp_pkg_id, &repo.push(".rust"))
-            == Some(repo.push(".rust").push("build").
+    assert!(built_executable_in_workspace(&temp_pkg_id, &repo)
+            == Some(repo.push("build").
                     push("mockgithub.com").
                     push("catamorphism").
                     push("test_pkg_version").
@@ -689,7 +695,7 @@ fn rustpkg_library_target() {
 
     add_git_tag(&package_dir, ~"1.0");
     command_line_test([~"install", ~"foo"], &foo_repo);
-    assert_lib_exists(&foo_repo.push(".rust"), "foo", ExactRevision(~"1.0"));
+    assert_lib_exists(&foo_repo, "foo", ExactRevision(~"1.0"));
 }
 
 #[test]
@@ -717,13 +723,54 @@ fn package_script_with_default_build() {
 }
 
 #[test]
+fn rustpkg_build_no_arg() {
+    let tmp = mkdtemp(&os::tmpdir(), "rustpkg_build_no_arg").expect("rustpkg_build_no_arg failed");
+    let package_dir = tmp.push("src").push("foo");
+    assert!(os::mkdir_recursive(&package_dir, U_RWX));
+
+    writeFile(&package_dir.push("main.rs"),
+              "fn main() { let _x = (); }");
+    debug!("build_no_arg: dir = %s", package_dir.to_str());
+    command_line_test([~"build"], &package_dir);
+    assert_built_executable_exists(&tmp, "foo");
+}
+
+#[test]
+fn rustpkg_install_no_arg() {
+    let tmp = mkdtemp(&os::tmpdir(),
+                      "rustpkg_install_no_arg").expect("rustpkg_build_no_arg failed");
+    let package_dir = tmp.push("src").push("foo");
+    assert!(os::mkdir_recursive(&package_dir, U_RWX));
+    writeFile(&package_dir.push("lib.rs"),
+              "fn main() { let _x = (); }");
+    debug!("install_no_arg: dir = %s", package_dir.to_str());
+    command_line_test([~"install"], &package_dir);
+    assert_lib_exists(&tmp, "foo", NoVersion);
+}
+
+#[test]
+fn rustpkg_clean_no_arg() {
+    let tmp = mkdtemp(&os::tmpdir(), "rustpkg_clean_no_arg").expect("rustpkg_clean_no_arg failed");
+    let package_dir = tmp.push("src").push("foo");
+    assert!(os::mkdir_recursive(&package_dir, U_RWX));
+
+    writeFile(&package_dir.push("main.rs"),
+              "fn main() { let _x = (); }");
+    debug!("clean_no_arg: dir = %s", package_dir.to_str());
+    command_line_test([~"build"], &package_dir);
+    assert_built_executable_exists(&tmp, "foo");
+    command_line_test([~"clean"], &package_dir);
+    assert!(!built_executable_in_workspace(&PkgId::new("foo", &package_dir),
+                &tmp).map_default(false, |m| { os::path_exists(m) }));
+}
+
+#[test]
 #[ignore (reason = "Un-ignore when #7071 is fixed")]
 fn rust_path_test() {
     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 = (); }");
+    writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
 
     let cwd = os::getcwd();
     debug!("cwd = %s", cwd.to_str());
@@ -781,21 +828,24 @@ fn test_list() {
     let quux = PkgId::new("quux", &dir);
     create_local_package_in(&quux, &dir);
 
+// NOTE Not really great output, though...
+// NOTE do any tests need to be unignored?
     command_line_test([~"install", ~"foo"], &dir);
     let env_arg = ~[(~"RUST_PATH", dir.to_str())];
+    debug!("RUST_PATH = %s", dir.to_str());
     let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
-    assert!(list_output.iter().any(|x| x.starts_with("foo-")));
+    assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
 
     command_line_test([~"install", ~"bar"], &dir);
     let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
-    assert!(list_output.iter().any(|x| x.starts_with("foo-")));
-    assert!(list_output.iter().any(|x| x.starts_with("bar-")));
+    assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
+    assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
 
     command_line_test([~"install", ~"quux"], &dir);
     let list_output = command_line_test_output_with_env([~"list"], env_arg);
-    assert!(list_output.iter().any(|x| x.starts_with("foo-")));
-    assert!(list_output.iter().any(|x| x.starts_with("bar-")));
-    assert!(list_output.iter().any(|x| x.starts_with("quux-")));
+    assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
+    assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
+    assert!(list_output.iter().any(|x| x.starts_with("libquux_")));
 }
 
 #[test]
@@ -836,7 +886,7 @@ fn install_check_duplicates() {
     let mut contents = ~[];
     let check_dups = |p: &PkgId| {
         if contents.contains(p) {
-            fail!("package database contains duplicate ID");
+            fail!("package %s appears in `list` output more than once", p.local_path.to_str());
         }
         else {
             contents.push((*p).clone());
diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs
index 59e9e57d643..87ab3882df1 100644
--- a/src/librustpkg/usage.rs
+++ b/src/librustpkg/usage.rs
@@ -23,10 +23,11 @@ Options:
 }
 
 pub fn build() {
-    io::println("rustpkg [options..] build
+    io::println("rustpkg [options..] build [package-ID]
 
-Build all targets described in the package script in the current
-directory.
+Build the given package ID if specified. With no package ID argument,
+build the package in the current directory. In that case, the current
+directory must be a direct child of an `src` directory in a workspace.
 
 Options:
     -c, --cfg      Pass a cfg flag to the package script");
diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs
index 5876dbdc9de..952352a02a5 100644
--- a/src/librustpkg/workspace.rs
+++ b/src/librustpkg/workspace.rs
@@ -10,9 +10,10 @@
 
 // rustpkg utilities having to do with workspaces
 
+use std::os;
+use std::path::Path;
 use path_util::{rust_path, workspace_contains_package_id};
 use package_id::PkgId;
-use std::path::Path;
 
 pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool {
     // Using the RUST_PATH, find workspaces that contain
@@ -38,3 +39,24 @@ pub fn pkg_parent_workspaces(pkgid: &PkgId) -> ~[Path] {
         .filter(|ws| workspace_contains_package_id(pkgid, ws))
         .collect()
 }
+
+pub fn in_workspace(complain: &fn()) -> bool {
+    let dir_part = os::getcwd().pop().components.clone();
+    if  *(dir_part.last()) != ~"src" {
+        complain();
+        false
+    }
+    else {
+        true
+    }
+}
+
+/// Construct a workspace and package-ID name based on the current directory.
+/// This gets used when rustpkg gets invoked without a package-ID argument.
+pub fn cwd_to_workspace() -> (Path, PkgId) {
+    let cwd = os::getcwd();
+    let ws = cwd.pop().pop();
+    let cwd_ = cwd.clone();
+    let pkgid = cwd_.components.last().to_str();
+    (ws, PkgId::new(pkgid, &cwd))
+}