From 0d993947ee5a4c29451cf0ee40f47519e1c3c4d9 Mon Sep 17 00:00:00 2001
From: Todd Gamblin <tgamblin@llnl.gov>
Date: Wed, 4 Nov 2015 16:44:33 -0800
Subject: [PATCH] Fix SPACK-93, SPACK-94, GitHub #150

- `remove_prefix` was modified to remove from the DB, but the package
  may not have been added to the DB yet when `remove_prefix` is called
  from `cleanup`.

- Made `remove_prefix` a pure utility function (it just removes the prefix)

- Added `installed_db.remove()` call only after the `remove_prefix` in
  `uninstall`.
---
 lib/spack/spack/cmd/{fsck.py => reindex.py} |  5 ++---
 lib/spack/spack/database.py                 | 19 +++++--------------
 lib/spack/spack/package.py                  |  4 ++--
 lib/spack/spack/test/database.py            | 11 +++++++++--
 4 files changed, 18 insertions(+), 21 deletions(-)
 rename lib/spack/spack/cmd/{fsck.py => reindex.py} (92%)

diff --git a/lib/spack/spack/cmd/fsck.py b/lib/spack/spack/cmd/reindex.py
similarity index 92%
rename from lib/spack/spack/cmd/fsck.py
rename to lib/spack/spack/cmd/reindex.py
index 9a3c450dcf..b584729ea4 100644
--- a/lib/spack/spack/cmd/fsck.py
+++ b/lib/spack/spack/cmd/reindex.py
@@ -25,8 +25,7 @@
 from external import argparse
 import spack
 
-description = "Correct database irregularities"
+description = "Rebuild Spack's package database."
 
-# Very basic version of spack fsck
-def fsck(parser, args):
+def reindex(parser, args):
     spack.installed_db.reindex(spack.install_layout)
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 9ce00a45e9..e0c14a0455 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -93,8 +93,8 @@ class InstallRecord(object):
     """
     def __init__(self, spec, path, installed, ref_count=0):
         self.spec = spec
-        self.path = path
-        self.installed = installed
+        self.path = str(path)
+        self.installed = bool(installed)
         self.ref_count = ref_count
 
     def to_dict(self):
@@ -173,7 +173,7 @@ def _write_to_yaml(self, stream):
         # map from per-spec hash code to installation record.
         installs = dict((k, v.to_dict()) for k, v in self._data.items())
 
-        # databaes includes installation list and version.
+        # database includes installation list and version.
 
         # NOTE: this DB version does not handle multiple installs of
         # the same spec well.  If there are 2 identical specs with
@@ -336,15 +336,14 @@ def _write(self):
         Does no locking.
 
         """
-        temp_name = '%s.%s.temp' % (socket.getfqdn(), os.getpid())
-        temp_file = join_path(self._db_dir, temp_name)
+        temp_file = self._index_path + (
+            '.%s.%s.temp' % (socket.getfqdn(), os.getpid()))
 
         # Write a temporary database file them move it into place
         try:
             with open(temp_file, 'w') as f:
                 self._write_to_yaml(f)
             os.rename(temp_file, self._index_path)
-
         except:
             # Clean up temp file if something goes wrong.
             if os.path.exists(temp_file):
@@ -367,14 +366,6 @@ def _read(self):
             self.reindex(spack.install_layout)
 
 
-    def read(self):
-        with self.read_transaction(): pass
-
-
-    def write(self):
-        with self.write_transaction(): pass
-
-
     def _add(self, spec, path, directory_layout=None):
         """Add an install record for spec at path to the database.
 
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index b15d4b2040..c631a35bf3 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -611,7 +611,6 @@ def url_version(self, version):
     def remove_prefix(self):
         """Removes the prefix for a package along with any empty parent directories."""
         spack.install_layout.remove_install_directory(self.spec)
-        spack.installed_db.remove(self.spec)
 
 
     def do_fetch(self):
@@ -877,7 +876,7 @@ def build_log_path(self):
         if self.installed:
             return spack.install_layout.build_log_path(self.spec)
         else:
-            return join_path(self.stage.source_path, 'spack-build.out')   
+            return join_path(self.stage.source_path, 'spack-build.out')
 
 
     @property
@@ -934,6 +933,7 @@ def do_uninstall(self, force=False):
 
         # Uninstalling in Spack only requires removing the prefix.
         self.remove_prefix()
+        spack.installed_db.remove(self.spec)
         tty.msg("Successfully uninstalled %s." % self.spec.short_spec)
 
         # Once everything else is done, run post install hooks
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index 3c5926e840..8416143f2d 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -148,6 +148,15 @@ def tearDown(self):
         spack.installed_db = self.spack_installed_db
 
 
+    def test_005_db_exists(self):
+        """Make sure db cache file exists after creating."""
+        index_file = join_path(self.install_path, '.spack-db', 'index.yaml')
+        lock_file = join_path(self.install_path, '.spack-db', 'lock')
+
+        self.assertTrue(os.path.exists(index_file))
+        self.assertTrue(os.path.exists(lock_file))
+
+
     def test_010_all_install_sanity(self):
         """Ensure that the install layout reflects what we think it does."""
         all_specs = spack.install_layout.all_specs()
@@ -182,8 +191,6 @@ def test_015_write_and_read(self):
         with spack.installed_db.write_transaction():
             specs = spack.installed_db.query()
             recs = [spack.installed_db.get_record(s) for s in specs]
-            spack.installed_db.write()
-        spack.installed_db.read()
 
         for spec, rec in zip(specs, recs):
             new_rec = spack.installed_db.get_record(spec)
-- 
GitLab