'List packages in the repo and check whether index is up to date.
Both of these opreations require checking all `package.py`
files so we do them at the same time.  We list the repo
directory and look at package.py files, and we compare the
index modification date with the ost recently modified package
file, storing the result.
The implementation here should try to minimize filesystem
calls.  At the moment, it is O(number of packages) and makes
about one stat call per package.  This is resonably fast, and
avoids actually importing packages in Spack, which is slow.'

def _fast_package_check(self):

    if (self._all_package_names is None):
        self._all_package_names = []
        index_mtime = spack.misc_cache.mtime(self._cache_file)
        for pkg_name in os.listdir(self.packages_path):
            pkg_dir = join_path(self.packages_path, pkg_name)
            if (not valid_module_name(pkg_name)):
                msg = "Skipping    package    at    %s.    '%s'    is    not    a    valid    Spack    module    name."
                tty.warn((msg % (pkg_dir, pkg_name)))
                continue
            pkg_file = join_path(self.packages_path, pkg_name, package_file_name)
            try:
                sinfo = os.stat(pkg_file)
            except OSError as e:
                if (e.errno == errno.ENOENT):
                    continue
                elif (e.errno == errno.EACCES):
                    tty.warn(("Can't    read    package    file    %s." % pkg_file))
                    continue
                raise e
            if stat.S_ISDIR(sinfo.st_mode):
                continue
            self._all_package_names.append(pkg_name)
            if (sinfo.st_mtime > index_mtime):
                self._needs_update.append(pkg_name)
        self._all_package_names.sort()
    return self._all_package_names
