diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/docs/config_yaml.rst | 13 | ||||
-rw-r--r-- | lib/spack/llnl/util/tty/log.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/installer.py | 29 |
3 files changed, 43 insertions, 1 deletions
diff --git a/lib/spack/docs/config_yaml.rst b/lib/spack/docs/config_yaml.rst index 631b8f6b1b..8173e8a0a9 100644 --- a/lib/spack/docs/config_yaml.rst +++ b/lib/spack/docs/config_yaml.rst @@ -259,3 +259,16 @@ and ld.so will ONLY search for dependencies in the ``RUNPATH`` of the loading object. DO NOT MIX the two options within the same install tree. + +---------------------- +``terminal_title`` +---------------------- + +By setting this option to ``true``, Spack will update the terminal's title to +provide information about its current progress as well as the current and +total package numbers. + +To work properly, this requires your terminal to reset its title after +Spack has finished its work, otherwise Spack's status information will +remain in the terminal's title indefinitely. Most terminals should already +be set up this way and clear Spack's status information. diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py index bc79b32335..7003f58f8d 100644 --- a/lib/spack/llnl/util/tty/log.py +++ b/lib/spack/llnl/util/tty/log.py @@ -33,7 +33,7 @@ except ImportError: # Use this to strip escape sequences -_escape = re.compile(r'\x1b[^m]*m|\x1b\[?1034h') +_escape = re.compile(r'\x1b[^m]*m|\x1b\[?1034h|\x1b\][0-9]+;[^\x07]*\x07') # control characters for enabling/disabling echo # diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py index 11430bfc94..d7a6ca0a67 100644 --- a/lib/spack/spack/installer.py +++ b/lib/spack/spack/installer.py @@ -627,6 +627,27 @@ def package_id(pkg): return "{0}-{1}-{2}".format(pkg.name, pkg.version, pkg.spec.dag_hash()) +class TermTitle(object): + def __init__(self, pkg_count): + # Counters used for showing status information in the terminal title + self.pkg_num = 0 + self.pkg_count = pkg_count + + def next_pkg(self): + self.pkg_num += 1 + + def set(self, text): + if not spack.config.get('config:terminal_title', False): + return + + if not sys.stdout.isatty(): + return + + status = '{0} [{1}/{2}]'.format(text, self.pkg_num, self.pkg_count) + sys.stdout.write('\033]0;Spack: {0}\007'.format(status)) + sys.stdout.flush() + + class PackageInstaller(object): ''' Class for managing the install process for a Spack instance based on a @@ -1476,7 +1497,11 @@ class PackageInstaller(object): failed_explicits = [] exists_errors = [] + term_title = TermTitle(len(self.build_pq)) + while self.build_pq: + term_title.next_pkg() + task = self._pop_task() if task is None: continue @@ -1486,6 +1511,7 @@ class PackageInstaller(object): keep_prefix = install_args.get('keep_prefix') pkg, pkg_id, spec = task.pkg, task.pkg_id, task.pkg.spec + term_title.set('Processing {0}'.format(pkg.name)) tty.verbose('Processing {0}: task={1}'.format(pkg_id, task)) # Ensure that the current spec has NO uninstalled dependencies, # which is assumed to be reflected directly in its priority. @@ -1541,6 +1567,7 @@ class PackageInstaller(object): # another process is likely (un)installing the spec or has # determined the spec has already been installed (though the # other process may be hung). + term_title.set('Acquiring lock for {0}'.format(pkg.name)) ltype, lock = self._ensure_locked('write', pkg) if lock is None: # Attempt to get a read lock instead. If this fails then @@ -1561,6 +1588,7 @@ class PackageInstaller(object): task.request.overwrite_time = time.time() # Determine state of installation artifacts and adjust accordingly. + term_title.set('Preparing {0}'.format(pkg.name)) self._prepare_for_install(task) # Flag an already installed package @@ -1605,6 +1633,7 @@ class PackageInstaller(object): # Proceed with the installation since we have an exclusive write # lock on the package. + term_title.set('Installing {0}'.format(pkg.name)) try: action = self._install_action(task) |