about summary refs log tree commit diff
path: root/src/librustpkg
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustpkg')
-rw-r--r--src/librustpkg/conditions.rs5
-rw-r--r--src/librustpkg/context.rs21
-rw-r--r--src/librustpkg/rustpkg.rc50
-rw-r--r--src/librustpkg/tests.rs93
-rw-r--r--src/librustpkg/util.rs2
-rw-r--r--src/librustpkg/workspace.rs34
6 files changed, 175 insertions, 30 deletions
diff --git a/src/librustpkg/conditions.rs b/src/librustpkg/conditions.rs
index 353995a816e..35e70af7914 100644
--- a/src/librustpkg/conditions.rs
+++ b/src/librustpkg/conditions.rs
@@ -11,7 +11,12 @@
 // Useful conditions
 
 pub use core::path::Path;
+pub use util::PkgId;
 
 condition! {
     bad_path: (super::Path, ~str) -> super::Path;
 }
+
+condition! {
+    nonexistent_package: (super::PkgId, ~str) -> super::Path;
+}
diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs
new file mode 100644
index 00000000000..db036f44a18
--- /dev/null
+++ b/src/librustpkg/context.rs
@@ -0,0 +1,21 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Context data structure used by rustpkg
+
+use core::hashmap::HashMap;
+
+pub struct Ctx {
+    // I'm not sure what this is for
+    json: bool,
+    // Cache of hashes of things already installed
+    // though I'm not sure why the value is a bool
+    dep_cache: @mut HashMap<~str, bool>,
+}
diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc
index 8381e6ad816..e1edce6ce5b 100644
--- a/src/librustpkg/rustpkg.rc
+++ b/src/librustpkg/rustpkg.rc
@@ -36,14 +36,19 @@ use rustc::metadata::filesearch;
 use std::{getopts};
 use syntax::{ast, diagnostic};
 use util::*;
-use path_util::{normalize, workspace_contains_package_id};
-use path_util::{build_pkg_id_in_workspace, pkgid_src_in_workspace, rust_path};
+use path_util::normalize;
+use path_util::{build_pkg_id_in_workspace, pkgid_src_in_workspace};
+use workspace::pkg_parent_workspaces;
 use rustc::driver::session::{lib_crate, bin_crate, crate_type};
+use context::Ctx;
 
 mod conditions;
+mod context;
 mod usage;
 mod path_util;
+mod tests;
 mod util;
+mod workspace;
 
 /// A PkgScript represents user-supplied custom logic for
 /// special build hooks. This only exists for packages with
@@ -154,14 +159,6 @@ impl PkgScript {
 
 }
 
-struct Ctx {
-    // I'm not sure what this is for
-    json: bool,
-    // Cache of hashes of things already installed
-    // though I'm not sure why the value is a bool
-    dep_cache: @mut HashMap<~str, bool>,
-}
-
 impl Ctx {
 
     fn run(&self, cmd: ~str, args: ~[~str]) {
@@ -194,17 +191,7 @@ impl Ctx {
                 // The package id is presumed to be the first command-line
                 // argument
                 let pkgid = PkgId::new(args[0]);
-                // Using the RUST_PATH, find workspaces that contain
-                // this package ID
-                let workspaces = rust_path().filtered(|ws|
-                    workspace_contains_package_id(pkgid, ws));
-                if workspaces.is_empty() {
-                    fail!(fmt!("Package %s not found in any of \
-                        the following workspaces: %s",
-                               pkgid.path.to_str(),
-                               rust_path().to_str()));
-                }
-                for workspaces.each |workspace| {
+                for pkg_parent_workspaces(pkgid) |workspace| {
                     let src_dir   = pkgid_src_in_workspace(pkgid, workspace);
                     let build_dir = build_pkg_id_in_workspace(pkgid, workspace);
                     debug!("Destination dir = %s", build_dir.to_str());
@@ -271,10 +258,16 @@ impl Ctx {
                 self.info();
             }
             ~"install" => {
-                self.install(if args.len() >= 1 { Some(args[0]) }
-                             else { None },
-                             if args.len() >= 2 { Some(args[1]) }
-                             else { None }, false);
+                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]);
+                for pkg_parent_workspaces(pkgid) |workspace| {
+                    self.install(workspace, pkgid);
+                }
             }
             ~"prefer" => {
                 if args.len() < 1 {
@@ -310,9 +303,9 @@ impl Ctx {
         }
     }
 
-    fn do_cmd(&self, cmd: ~str, pkgname: ~str)  {
+    fn do_cmd(&self, _cmd: ~str, _pkgname: ~str)  {
         // stub
-        fail!("`do` not yet implemented");
+        fail!(~"`do` not yet implemented");
     }
 
     fn clean(&self, workspace: &Path, id: PkgId)  {
@@ -336,8 +329,7 @@ impl Ctx {
         fail!(~"info not yet implemented");
     }
 
-    fn install(&self, _url: Option<~str>,
-               _target: Option<~str>, _cache: bool)  {
+    fn install(&self, _workspace: &Path, _id: PkgId)  {
         // stub
         fail!(~"install not yet implemented");
     }
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index f5948606072..70c03c845ce 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -9,3 +9,96 @@
 // except according to those terms.
 
 // rustpkg unit tests
+
+use context::Ctx;
+use core::hashmap::HashMap;
+use core::path::Path;
+use core::os;
+use core::io;
+use core::option::*;
+use std::tempfile::mkdtemp;
+use util::{PkgId, default_version};
+use path_util::{target_executable_in_workspace, target_library_in_workspace,
+               target_test_in_workspace, target_bench_in_workspace,
+               make_dir_rwx};
+
+fn fake_ctxt() -> Ctx {
+    Ctx {
+        json: false,
+        dep_cache: @mut HashMap::new()
+    }
+}
+
+fn fake_pkg() -> PkgId {
+    PkgId {
+        path: Path(~"bogus"),
+        version: default_version()
+    }
+}
+
+fn mk_temp_workspace() -> Path {
+    mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir")
+}
+
+fn is_rwx(p: &Path) -> bool {
+    use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
+
+    match p.get_mode() {
+        None => return false,
+        Some(m) => {
+            ((m & S_IRUSR as uint) == S_IRUSR as uint
+            && (m & S_IWUSR as uint) == S_IWUSR as uint
+            && (m & S_IXUSR as uint) == S_IXUSR as uint)
+        }
+    }
+}
+
+#[test]
+fn test_make_dir_rwx() {
+    let temp = &os::tmpdir();
+    let dir = temp.push(~"quux");
+    let _ = os::remove_dir(&dir);
+    assert!(make_dir_rwx(&dir));
+    assert!(os::path_is_dir(&dir));
+    assert!(is_rwx(&dir));
+    assert!(os::remove_dir(&dir));
+}
+
+#[test]
+#[ignore(reason = "install not yet implemented")]
+fn test_install_valid() {
+    let ctxt = fake_ctxt();
+    let temp_pkg_id = fake_pkg();
+    let temp_workspace() = mk_temp_workspace();
+    // should have test, bench, lib, and main
+    ctxt.install(&temp_workspace, temp_pkg_id);
+    // Check that all files exist
+    let exec = target_executable_in_workspace(temp_pkg_id, &temp_workspace);
+    assert!(os::path_exists(&exec));
+    assert!(is_rwx(&exec));
+    let lib = target_library_in_workspace(temp_pkg_id, &temp_workspace);
+    assert!(os::path_exists(&lib));
+    assert!(is_rwx(&lib));
+    // And that the test and bench executables aren't installed
+    assert!(!os::path_exists(&target_test_in_workspace(temp_pkg_id, &temp_workspace)));
+    assert!(!os::path_exists(&target_bench_in_workspace(temp_pkg_id, &temp_workspace)));
+}
+
+#[test]
+#[ignore(reason = "install not yet implemented")]
+fn test_install_invalid() {
+    use conditions::nonexistent_package::cond;
+
+    let ctxt = fake_ctxt();
+    let pkgid = fake_pkg();
+    let temp_workspace = mk_temp_workspace();
+    let expected_path = Path(~"quux");
+    let substituted: Path = do cond.trap(|_| {
+        expected_path
+    }).in {
+        ctxt.install(&temp_workspace, pkgid);
+        // ok
+        fail!(~"test_install_invalid failed, should have raised a condition");
+    };
+    assert!(substituted == expected_path);
+}
\ No newline at end of file
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 36d409adcd2..28198e59f86 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -78,7 +78,7 @@ impl ToStr for Version {
 }
 
 /// Placeholder
-fn default_version() -> Version { ExactRevision(0.1) }
+pub fn default_version() -> Version { ExactRevision(0.1) }
 
 // Path-fragment identifier of a package such as
 // 'github.com/graydon/test'; path must be a relative
diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs
new file mode 100644
index 00000000000..15e2166b24a
--- /dev/null
+++ b/src/librustpkg/workspace.rs
@@ -0,0 +1,34 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// rustpkg utilities having to do with workspaces
+
+use path_util::{rust_path, workspace_contains_package_id};
+use util::PkgId;
+use core::path::Path;
+
+pub fn pkg_parent_workspaces(pkgid: PkgId, action: &fn(&Path) -> bool) {
+    // Using the RUST_PATH, find workspaces that contain
+    // this package ID
+    let workspaces = rust_path().filtered(|ws|
+        workspace_contains_package_id(pkgid, ws));
+    if workspaces.is_empty() {
+        // tjc: make this a condition
+        fail!(fmt!("Package %s not found in any of \
+                    the following workspaces: %s",
+                   pkgid.path.to_str(),
+                   rust_path().to_str()));
+    }
+    for workspaces.each |ws| {
+        if action(ws) {
+            break;
+        }
+    }
+}
\ No newline at end of file