about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-09-17 18:23:34 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-09-18 22:48:37 -0700
commitd84a22addf09f6c7daba070732593c1e3313ed77 (patch)
treeab92ef37e1048ee0d99d3ca049d937db0a0f7f03
parent4dacd736510b2ae28a54489fe88571f1a6de019f (diff)
rustpkg: Register correct dependencies for built and installed files
as per #9112

Closes #9112
-rw-r--r--src/librustpkg/api.rs7
-rw-r--r--src/librustpkg/exit_codes.rs2
-rw-r--r--src/librustpkg/path_util.rs1
-rw-r--r--src/librustpkg/rustpkg.rs6
-rw-r--r--src/librustpkg/tests.rs53
-rw-r--r--src/librustpkg/util.rs23
6 files changed, 84 insertions, 8 deletions
diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs
index e1092458ffa..4f6848525c9 100644
--- a/src/librustpkg/api.rs
+++ b/src/librustpkg/api.rs
@@ -16,6 +16,7 @@ use target::*;
 use version::Version;
 use workcache_support::*;
 
+use std::os;
 use extra::arc::{Arc,RWArc};
 use extra::workcache;
 use extra::workcache::{Database, Logger, FreshnessMap};
@@ -40,11 +41,13 @@ pub fn new_default_context(c: workcache::Context, p: Path) -> BuildContext {
 }
 
 fn file_is_fresh(path: &str, in_hash: &str) -> bool {
-    in_hash == digest_file_with_date(&Path(path))
+    let path = Path(path);
+    os::path_exists(&path) && in_hash == digest_file_with_date(&path)
 }
 
 fn binary_is_fresh(path: &str, in_hash: &str) -> bool {
-    in_hash == digest_only_date(&Path(path))
+    let path = Path(path);
+    os::path_exists(&path) && in_hash == digest_only_date(&path)
 }
 
 pub fn new_workcache_context(p: &Path) -> workcache::Context {
diff --git a/src/librustpkg/exit_codes.rs b/src/librustpkg/exit_codes.rs
index 484f6bdcaec..56ee2033d14 100644
--- a/src/librustpkg/exit_codes.rs
+++ b/src/librustpkg/exit_codes.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub static copy_failed_code: int = 65;
+pub static COPY_FAILED_CODE: int = 65;
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index 92e5adf09f6..3ed1b7a3a9c 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -118,7 +118,6 @@ fn target_bin_dir(workspace: &Path) -> Path {
 /// directory is, and if the file exists, return it.
 pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
     let mut result = target_build_dir(workspace);
-    // should use a target-specific subdirectory
     result = mk_output_path(Main, Build, pkgid, result);
     debug!("built_executable_in_workspace: checking whether %s exists",
            result.to_str());
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
index 7cd30c7af9e..ccc3177739e 100644
--- a/src/librustpkg/rustpkg.rs
+++ b/src/librustpkg/rustpkg.rs
@@ -47,7 +47,7 @@ use package_source::PkgSrc;
 use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench};
 // use workcache_support::{discover_outputs, digest_only_date};
 use workcache_support::digest_only_date;
-use exit_codes::copy_failed_code;
+use exit_codes::COPY_FAILED_CODE;
 
 pub mod api;
 mod conditions;
@@ -789,10 +789,10 @@ pub fn main_args(args: &[~str]) {
         }.run(sub_cmd, rm_args.clone())
     };
     // FIXME #9262: This is using the same error code for all errors,
-    // and at least one test case succeeds if rustpkg returns copy_failed_code,
+    // and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
     // when actually, it might set the exit code for that even if a different
     // unhandled condition got raised.
-    if result.is_err() { os::set_exit_status(copy_failed_code); }
+    if result.is_err() { os::set_exit_status(COPY_FAILED_CODE); }
 
 }
 
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index 918cc366799..a0e9e49e507 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -355,6 +355,13 @@ fn executable_exists(repo: &Path, short_name: &str) -> bool {
     os::path_exists(&exec) && is_rwx(&exec)
 }
 
+fn remove_executable_file(p: &PkgId, workspace: &Path) {
+    let exec = target_executable_in_workspace(&PkgId::new(p.short_name), workspace);
+    if os::path_exists(&exec) {
+        assert!(os::remove_file(&exec));
+    }
+}
+
 fn assert_built_executable_exists(repo: &Path, short_name: &str) {
     assert!(built_executable_exists(repo, short_name));
 }
@@ -368,6 +375,14 @@ fn built_executable_exists(repo: &Path, short_name: &str) -> bool {
     }
 }
 
+fn remove_built_executable_file(p: &PkgId, workspace: &Path) {
+    let exec = built_executable_in_workspace(&PkgId::new(p.short_name), workspace);
+    match exec {
+        Some(r) => assert!(os::remove_file(&r)),
+        None    => ()
+    }
+}
+
 fn object_file_exists(repo: &Path, short_name: &str) -> bool {
     file_exists(repo, short_name, "o")
 }
@@ -1705,6 +1720,44 @@ fn test_dependencies_terminate() {
     command_line_test([~"install", ~"b"], &workspace);
 }
 
+#[test]
+fn install_after_build() {
+    let b_id = PkgId::new("b");
+    let workspace = create_local_package(&b_id);
+    command_line_test([~"build", ~"b"], &workspace);
+    command_line_test([~"install", ~"b"], &workspace);
+    assert_executable_exists(&workspace, b_id.short_name);
+    assert_lib_exists(&workspace, &b_id.path, NoVersion);
+}
+
+#[test]
+fn reinstall() {
+    let b = PkgId::new("b");
+    let workspace = create_local_package(&b);
+    // 1. Install, then remove executable file, then install again,
+    // and make sure executable was re-installed
+    command_line_test([~"install", ~"b"], &workspace);
+    assert_executable_exists(&workspace, b.short_name);
+    assert_lib_exists(&workspace, &b.path, NoVersion);
+    remove_executable_file(&b, &workspace);
+    command_line_test([~"install", ~"b"], &workspace);
+    assert_executable_exists(&workspace, b.short_name);
+    // 2. Build, then remove build executable file, then build again,
+    // and make sure executable was re-built.
+    command_line_test([~"build", ~"b"], &workspace);
+    remove_built_executable_file(&b, &workspace);
+    command_line_test([~"build", ~"b"], &workspace);
+    assert_built_executable_exists(&workspace, b.short_name);
+    // 3. Install, then remove both executable and built executable,
+    // then install again, make sure both were recreated
+    command_line_test([~"install", ~"b"], &workspace);
+    remove_executable_file(&b, &workspace);
+    remove_built_executable_file(&b, &workspace);
+    command_line_test([~"install", ~"b"], &workspace);
+    assert_executable_exists(&workspace, b.short_name);
+    assert_built_executable_exists(&workspace, b.short_name);
+}
+
 /// Returns true if p exists and is executable
 fn is_executable(p: &Path) -> bool {
     use std::libc::consts::os::posix88::{S_IXUSR};
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 64f76dcdc60..906bed2f234 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -283,7 +283,28 @@ pub fn compile_input(context: &BuildContext,
 
     debug!("calling compile_crate_from_input, workspace = %s,
            building_library = %?", out_dir.to_str(), sess.building_library);
-    compile_crate_from_input(in_file, exec, context.compile_upto(), &out_dir, sess, crate)
+    let result = compile_crate_from_input(in_file,
+                                          exec,
+                                          context.compile_upto(),
+                                          &out_dir,
+                                          sess,
+                                          crate);
+    // Discover the output
+    let discovered_output = if what == Lib  {
+        installed_library_in_workspace(&pkg_id.path, workspace)
+    }
+    else {
+        result
+    };
+    debug!("About to discover output %s", discovered_output.to_str());
+    for p in discovered_output.iter() {
+        if os::path_exists(p) {
+            exec.discover_output("binary", p.to_str(), digest_only_date(p));
+        }
+        // Nothing to do if it doesn't exist -- that could happen if we had the
+        // -S or -emit-llvm flags, etc.
+    }
+    discovered_output
 }
 
 // Should use workcache to avoid recompiling when not necessary