New command flag: spack install --dependencies-only (#1603)

* 1. Renamed ignore_deps variable to install_deps (use positive logic).  UI remains the same.

2. install_self kwarg added to do_install().  Enables installation of a package's dependencies without installing the package itself.

3. Added `spack install --dependencies-only <package>` command.

* Flak8 fixes

* Indentation problem
This commit is contained in:
Elizabeth Fischer 2016-10-05 14:23:06 -04:00 committed by Todd Gamblin
parent 6ee020cea4
commit abc9412f23
5 changed files with 40 additions and 23 deletions

View file

@ -101,7 +101,7 @@ def diy(self, args):
package.do_install( package.do_install(
keep_prefix=args.keep_prefix, keep_prefix=args.keep_prefix,
ignore_deps=args.ignore_deps, install_deps=not args.ignore_deps,
verbose=not args.quiet, verbose=not args.quiet,
keep_stage=True, # don't remove source dir for DIY. keep_stage=True, # don't remove source dir for DIY.
dirty=args.dirty) dirty=args.dirty)

View file

@ -22,6 +22,7 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
from __future__ import print_function
import argparse import argparse
import llnl.util.tty as tty import llnl.util.tty as tty
@ -36,6 +37,10 @@ def setup_parser(subparser):
subparser.add_argument( subparser.add_argument(
'-i', '--ignore-dependencies', action='store_true', dest='ignore_deps', '-i', '--ignore-dependencies', action='store_true', dest='ignore_deps',
help="Do not try to install dependencies of requested packages.") help="Do not try to install dependencies of requested packages.")
subparser.add_argument(
'-d', '--dependencies-only', action='store_true', dest='deps_only',
help='Install dependencies of this package, ' +
'but not the package itself.')
subparser.add_argument( subparser.add_argument(
'-j', '--jobs', action='store', type=int, '-j', '--jobs', action='store', type=int,
help="Explicitly set number of make jobs. Default is #cpus.") help="Explicitly set number of make jobs. Default is #cpus.")
@ -83,7 +88,8 @@ def install(parser, args):
package.do_install( package.do_install(
keep_prefix=args.keep_prefix, keep_prefix=args.keep_prefix,
keep_stage=args.keep_stage, keep_stage=args.keep_stage,
ignore_deps=args.ignore_deps, install_deps=not args.ignore_deps,
install_self=not args.deps_only,
make_jobs=args.jobs, make_jobs=args.jobs,
run_tests=args.run_tests, run_tests=args.run_tests,
verbose=args.verbose, verbose=args.verbose,

View file

@ -91,7 +91,8 @@ def setup(self, args):
package.do_install( package.do_install(
keep_prefix=True, # Don't remove install directory keep_prefix=True, # Don't remove install directory
ignore_deps=args.ignore_deps, install_deps=not args.ignore_deps,
install_self=True,
verbose=args.verbose, verbose=args.verbose,
keep_stage=True, # don't remove source dir for SETUP. keep_stage=True, # don't remove source dir for SETUP.
install_phases=set(['setup', 'provenance']), install_phases=set(['setup', 'provenance']),

View file

@ -180,7 +180,8 @@ def install_single_spec(spec, number_of_jobs):
start_time = time.time() start_time = time.time()
package.do_install(keep_prefix=False, package.do_install(keep_prefix=False,
keep_stage=True, keep_stage=True,
ignore_deps=False, install_deps=True,
install_self=True,
make_jobs=number_of_jobs, make_jobs=number_of_jobs,
verbose=True, verbose=True,
fake=False) fake=False)

View file

@ -259,7 +259,7 @@ class SomePackage(Package):
parallel = False parallel = False
... ...
This changes thd default behavior so that make is sequential. If you still This changes the default behavior so that make is sequential. If you still
want to build some parts in parallel, you can do this in your install want to build some parts in parallel, you can do this in your install
function: function:
@ -868,7 +868,8 @@ def _resource_stage(self, resource):
def do_install(self, def do_install(self,
keep_prefix=False, keep_prefix=False,
keep_stage=False, keep_stage=False,
ignore_deps=False, install_deps=True,
install_self=True,
skip_patch=False, skip_patch=False,
verbose=False, verbose=False,
make_jobs=None, make_jobs=None,
@ -887,8 +888,10 @@ def do_install(self,
:param keep_stage: By default, stage is destroyed only if there are \ :param keep_stage: By default, stage is destroyed only if there are \
no exceptions during build. Set to True to keep the stage no exceptions during build. Set to True to keep the stage
even with exceptions. even with exceptions.
:param ignore_deps: Don't install dependencies before installing this \ :param install_deps: Install dependencies before installing this \
package package
:param install_self: Install this package once dependencies have \
been installed.
:param fake: Don't really build; install fake stub files instead. :param fake: Don't really build; install fake stub files instead.
:param skip_patch: Skip patch stage of build if True. :param skip_patch: Skip patch stage of build if True.
:param verbose: Display verbose build output (by default, suppresses \ :param verbose: Display verbose build output (by default, suppresses \
@ -896,6 +899,7 @@ def do_install(self,
:param dirty: Don't clean the build environment before installing. :param dirty: Don't clean the build environment before installing.
:param make_jobs: Number of make jobs to use for install. Default is \ :param make_jobs: Number of make jobs to use for install. Default is \
ncpus ncpus
:param force: Install again, even if already installed.
:param run_tests: Run tests within the package's install() :param run_tests: Run tests within the package's install()
""" """
if not self.spec.concrete: if not self.spec.concrete:
@ -922,10 +926,13 @@ def do_install(self,
tty.msg("Installing %s" % self.name) tty.msg("Installing %s" % self.name)
# First, install dependencies recursively. # First, install dependencies recursively.
if not ignore_deps: if install_deps:
self.do_install_dependencies(keep_prefix=keep_prefix, for dep in self.spec.dependencies():
dep.package.do_install(
keep_prefix=keep_prefix,
keep_stage=keep_stage, keep_stage=keep_stage,
ignore_deps=ignore_deps, install_deps=install_deps,
install_self=True,
fake=fake, fake=fake,
skip_patch=skip_patch, skip_patch=skip_patch,
verbose=verbose, verbose=verbose,
@ -933,12 +940,18 @@ def do_install(self,
run_tests=run_tests, run_tests=run_tests,
dirty=dirty) dirty=dirty)
# The rest of this function is to install ourself,
# once deps have been installed.
if not install_self:
return
# Set run_tests flag before starting build. # Set run_tests flag before starting build.
self.run_tests = run_tests self.run_tests = run_tests
# Set parallelism before starting build. # Set parallelism before starting build.
self.make_jobs = make_jobs self.make_jobs = make_jobs
# ------------------- BEGIN def build_process()
# Then install the package itself. # Then install the package itself.
def build_process(): def build_process():
"""Forked for each build. Has its own process and python """Forked for each build. Has its own process and python
@ -1022,6 +1035,7 @@ def build_process():
(_hms(self._fetch_time), _hms(build_time), (_hms(self._fetch_time), _hms(build_time),
_hms(self._total_time))) _hms(self._total_time)))
print_pkg(self.prefix) print_pkg(self.prefix)
# ------------------- END def build_process()
try: try:
# Create the install prefix and fork the build process. # Create the install prefix and fork the build process.
@ -1079,11 +1093,6 @@ def check_paths(path_list, filetype, predicate):
raise InstallError( raise InstallError(
"Install failed for %s. Nothing was installed!" % self.name) "Install failed for %s. Nothing was installed!" % self.name)
def do_install_dependencies(self, **kwargs):
# Pass along paths of dependencies here
for dep in self.spec.dependencies():
dep.package.do_install(**kwargs)
@property @property
def build_log_path(self): def build_log_path(self):
if self.installed: if self.installed: