flake8 fixes.

- package.py
- spec.py
- test/architecture.py
This commit is contained in:
Todd Gamblin 2016-07-18 02:20:41 -07:00
parent 192369dd2b
commit cddaba8add
5 changed files with 214 additions and 170 deletions

View File

@ -29,9 +29,11 @@
description = "Get detailed information on a particular package" description = "Get detailed information on a particular package"
def padder(str_list, extra=0): def padder(str_list, extra=0):
"""Return a function to pad elements of a list.""" """Return a function to pad elements of a list."""
length = max(len(str(s)) for s in str_list) + extra length = max(len(str(s)) for s in str_list) + extra
def pad(string): def pad(string):
string = str(string) string = str(string)
padding = max(0, length - len(string)) padding = max(0, length - len(string))
@ -40,7 +42,8 @@ def pad(string):
def setup_parser(subparser): def setup_parser(subparser):
subparser.add_argument('name', metavar="PACKAGE", help="Name of package to get info for.") subparser.add_argument(
'name', metavar="PACKAGE", help="Name of package to get info for.")
def print_text_info(pkg): def print_text_info(pkg):

View File

@ -635,8 +635,8 @@ def _exit(self):
class CorruptDatabaseError(SpackError): class CorruptDatabaseError(SpackError):
def __init__(self, path, msg=''): def __init__(self, path, msg=''):
super(CorruptDatabaseError, self).__init__( super(CorruptDatabaseError, self).__init__(
"Spack database is corrupt: %s. %s." + \ "Spack database is corrupt: %s. %s." % (path, msg),
"Try running `spack reindex` to fix." % (path, msg)) "Try running `spack reindex` to fix.")
class InvalidDatabaseVersionError(SpackError): class InvalidDatabaseVersionError(SpackError):

View File

@ -37,7 +37,6 @@
import re import re
import textwrap import textwrap
import time import time
import glob
import string import string
import llnl.util.tty as tty import llnl.util.tty as tty
@ -62,10 +61,10 @@
from spack.stage import Stage, ResourceStage, StageComposite from spack.stage import Stage, ResourceStage, StageComposite
from spack.util.compression import allowed_archive from spack.util.compression import allowed_archive
from spack.util.environment import dump_environment from spack.util.environment import dump_environment
from spack.util.executable import ProcessError, Executable, which from spack.util.executable import ProcessError, which
from spack.version import * from spack.version import *
from spack import directory_layout from spack import directory_layout
from urlparse import urlparse
"""Allowed URL schemes for spack packages.""" """Allowed URL schemes for spack packages."""
_ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"] _ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"]
@ -410,7 +409,6 @@ def package_dir(self):
"""Return the directory where the package.py file lives.""" """Return the directory where the package.py file lives."""
return os.path.dirname(self.module.__file__) return os.path.dirname(self.module.__file__)
@property @property
def global_license_dir(self): def global_license_dir(self):
"""Returns the directory where global license files for all """Returns the directory where global license files for all
@ -565,13 +563,11 @@ def fetcher(self):
def fetcher(self, f): def fetcher(self, f):
self._fetcher = f self._fetcher = f
def dependencies_of_type(self, *deptypes): def dependencies_of_type(self, *deptypes):
"""Get subset of the dependencies with certain types.""" """Get subset of the dependencies with certain types."""
return dict((name, conds) for name, conds in self.dependencies.items() return dict((name, conds) for name, conds in self.dependencies.items()
if any(d in self._deptypes[name] for d in deptypes)) if any(d in self._deptypes[name] for d in deptypes))
@property @property
def extendee_spec(self): def extendee_spec(self):
""" """
@ -694,7 +690,7 @@ def installed_dependents(self):
if self.name == spec.name: if self.name == spec.name:
continue continue
# XXX(deptype): Should build dependencies not count here? # XXX(deptype): Should build dependencies not count here?
#for dep in spec.traverse(deptype=('run')): # for dep in spec.traverse(deptype=('run')):
for dep in spec.traverse(deptype=spack.alldeps): for dep in spec.traverse(deptype=spack.alldeps):
if self.spec == dep: if self.spec == dep:
dependents.append(spec) dependents.append(spec)
@ -706,13 +702,13 @@ def prefix(self):
return self.spec.prefix return self.spec.prefix
@property @property
#TODO: Change this to architecture # TODO: Change this to architecture
def compiler(self): def compiler(self):
"""Get the spack.compiler.Compiler object used to build this package""" """Get the spack.compiler.Compiler object used to build this package"""
if not self.spec.concrete: if not self.spec.concrete:
raise ValueError("Can only get a compiler for a concrete package.") raise ValueError("Can only get a compiler for a concrete package.")
return spack.compilers.compiler_for_spec(self.spec.compiler, return spack.compilers.compiler_for_spec(self.spec.compiler,
self.spec.architecture) self.spec.architecture)
def url_version(self, version): def url_version(self, version):
""" """
@ -768,7 +764,6 @@ def do_fetch(self, mirror_only=False):
self.stage.cache_local() self.stage.cache_local()
def do_stage(self, mirror_only=False): def do_stage(self, mirror_only=False):
"""Unpacks the fetched tarball, then changes into the expanded tarball """Unpacks the fetched tarball, then changes into the expanded tarball
directory.""" directory."""
@ -886,6 +881,7 @@ def _resource_stage(self, resource):
return resource_stage_folder return resource_stage_folder
install_phases = set(['configure', 'build', 'install', 'provenance']) install_phases = set(['configure', 'build', 'install', 'provenance'])
def do_install(self, def do_install(self,
keep_prefix=False, keep_prefix=False,
keep_stage=False, keep_stage=False,
@ -897,7 +893,7 @@ def do_install(self,
fake=False, fake=False,
explicit=False, explicit=False,
dirty=False, dirty=False,
install_phases = install_phases): install_phases=install_phases):
"""Called by commands to install a package and its dependencies. """Called by commands to install a package and its dependencies.
Package implementations should override install() to describe Package implementations should override install() to describe
@ -918,7 +914,8 @@ def do_install(self,
run_tests -- Runn tests within the package's install() run_tests -- Runn tests within the package's install()
""" """
if not self.spec.concrete: if not self.spec.concrete:
raise ValueError("Can only install concrete packages: %s." % self.spec.name) raise ValueError("Can only install concrete packages: %s."
% self.spec.name)
# No installation needed if package is external # No installation needed if package is external
if self.spec.external: if self.spec.external:
@ -927,7 +924,8 @@ def do_install(self,
return return
# Ensure package is not already installed # Ensure package is not already installed
if 'install' in install_phases and spack.install_layout.check_installed(self.spec): layout = spack.install_layout
if 'install' in install_phases and layout.check_installed(self.spec):
tty.msg("%s is already installed in %s" % (self.name, self.prefix)) tty.msg("%s is already installed in %s" % (self.name, self.prefix))
rec = spack.installed_db.get_record(self.spec) rec = spack.installed_db.get_record(self.spec)
if (not rec.explicit) and explicit: if (not rec.explicit) and explicit:
@ -1008,20 +1006,17 @@ def build_process():
if 'install' in self.install_phases: if 'install' in self.install_phases:
self.sanity_check_prefix() self.sanity_check_prefix()
# Copy provenance into the install directory on success # Copy provenance into the install directory on success
if 'provenance' in self.install_phases: if 'provenance' in self.install_phases:
log_install_path = spack.install_layout.build_log_path( log_install_path = layout.build_log_path(self.spec)
self.spec) env_install_path = layout.build_env_path(self.spec)
env_install_path = spack.install_layout.build_env_path( packages_dir = layout.build_packages_path(self.spec)
self.spec)
packages_dir = spack.install_layout.build_packages_path(
self.spec)
# Remove first if we're overwriting another build # Remove first if we're overwriting another build
# (can happen with spack setup) # (can happen with spack setup)
try: try:
shutil.rmtree(packages_dir) # log_install_path and env_install_path are inside this # log_install_path and env_install_path are here
shutil.rmtree(packages_dir)
except: except:
pass pass
@ -1048,7 +1043,7 @@ def build_process():
except directory_layout.InstallDirectoryAlreadyExistsError: except directory_layout.InstallDirectoryAlreadyExistsError:
if 'install' in install_phases: if 'install' in install_phases:
# Abort install if install directory exists. # Abort install if install directory exists.
# But do NOT remove it (you'd be overwriting someon else's stuff) # But do NOT remove it (you'd be overwriting someone's data)
tty.warn("Keeping existing install prefix in place.") tty.warn("Keeping existing install prefix in place.")
raise raise
else: else:
@ -1540,24 +1535,29 @@ def _hms(seconds):
parts.append("%.2fs" % s) parts.append("%.2fs" % s)
return ' '.join(parts) return ' '.join(parts)
class StagedPackage(Package): class StagedPackage(Package):
"""A Package subclass where the install() is split up into stages.""" """A Package subclass where the install() is split up into stages."""
def install_setup(self): def install_setup(self):
"""Creates an spack_setup.py script to configure the package later if we like.""" """Creates a spack_setup.py script to configure the package later."""
raise InstallError("Package %s provides no install_setup() method!" % self.name) raise InstallError(
"Package %s provides no install_setup() method!" % self.name)
def install_configure(self): def install_configure(self):
"""Runs the configure process.""" """Runs the configure process."""
raise InstallError("Package %s provides no install_configure() method!" % self.name) raise InstallError(
"Package %s provides no install_configure() method!" % self.name)
def install_build(self): def install_build(self):
"""Runs the build process.""" """Runs the build process."""
raise InstallError("Package %s provides no install_build() method!" % self.name) raise InstallError(
"Package %s provides no install_build() method!" % self.name)
def install_install(self): def install_install(self):
"""Runs the install process.""" """Runs the install process."""
raise InstallError("Package %s provides no install_install() method!" % self.name) raise InstallError(
"Package %s provides no install_install() method!" % self.name)
def install(self, spec, prefix): def install(self, spec, prefix):
if 'setup' in self.install_phases: if 'setup' in self.install_phases:
@ -1574,9 +1574,10 @@ def install(self, spec, prefix):
else: else:
# Create a dummy file so the build doesn't fail. # Create a dummy file so the build doesn't fail.
# That way, the module file will also be created. # That way, the module file will also be created.
with open(os.path.join(prefix, 'dummy'), 'w') as fout: with open(os.path.join(prefix, 'dummy'), 'w'):
pass pass
# stackoverflow.com/questions/12791997/how-do-you-do-a-simple-chmod-x-from-within-python # stackoverflow.com/questions/12791997/how-do-you-do-a-simple-chmod-x-from-within-python
def make_executable(path): def make_executable(path):
mode = os.stat(path).st_mode mode = os.stat(path).st_mode
@ -1584,9 +1585,7 @@ def make_executable(path):
os.chmod(path, mode) os.chmod(path, mode)
class CMakePackage(StagedPackage): class CMakePackage(StagedPackage):
def make_make(self): def make_make(self):
import multiprocessing import multiprocessing
# number of jobs spack will to build with. # number of jobs spack will to build with.
@ -1600,37 +1599,41 @@ def make_make(self):
return make return make
def configure_args(self): def configure_args(self):
"""Returns package-specific arguments to be provided to the configure command.""" """Returns package-specific arguments to be provided to
the configure command.
"""
return list() return list()
def configure_env(self): def configure_env(self):
"""Returns package-specific environment under which the configure command should be run.""" """Returns package-specific environment under which the
configure command should be run.
"""
return dict() return dict()
def spack_transitive_include_path(self): def transitive_inc_path(self):
return ';'.join( return ';'.join(
os.path.join(dep, 'include') os.path.join(dep, 'include')
for dep in os.environ['SPACK_DEPENDENCIES'].split(os.pathsep) for dep in os.environ['SPACK_DEPENDENCIES'].split(os.pathsep)
) )
def install_setup(self): def install_setup(self):
cmd = [str(which('cmake'))] + \ cmd = [str(which('cmake'))]
spack.build_environment.get_std_cmake_args(self) + \ cmd += spack.build_environment.get_std_cmake_args(self)
['-DCMAKE_INSTALL_PREFIX=%s' % os.environ['SPACK_PREFIX'], cmd += ['-DCMAKE_INSTALL_PREFIX=%s' % os.environ['SPACK_PREFIX'],
'-DCMAKE_C_COMPILER=%s' % os.environ['SPACK_CC'], '-DCMAKE_C_COMPILER=%s' % os.environ['SPACK_CC'],
'-DCMAKE_CXX_COMPILER=%s' % os.environ['SPACK_CXX'], '-DCMAKE_CXX_COMPILER=%s' % os.environ['SPACK_CXX'],
'-DCMAKE_Fortran_COMPILER=%s' % os.environ['SPACK_FC']] + \ '-DCMAKE_Fortran_COMPILER=%s' % os.environ['SPACK_FC']]
self.configure_args() cmd += self.configure_args()
env = dict() env = {
env['PATH'] = os.environ['PATH'] 'PATH': os.environ['PATH'],
env['SPACK_TRANSITIVE_INCLUDE_PATH'] = self.spack_transitive_include_path() 'SPACK_TRANSITIVE_INCLUDE_PATH': self.transitive_inc_path(),
env['CMAKE_PREFIX_PATH'] = os.environ['CMAKE_PREFIX_PATH'] 'CMAKE_PREFIX_PATH': os.environ['CMAKE_PREFIX_PATH']
}
setup_fname = 'spconfig.py' setup_fname = 'spconfig.py'
with open(setup_fname, 'w') as fout: with open(setup_fname, 'w') as fout:
fout.write(\ fout.write(r"""#!%s
r"""#!%s
# #
import sys import sys
@ -1638,7 +1641,7 @@ def install_setup(self):
import subprocess import subprocess
def cmdlist(str): def cmdlist(str):
return list(x.strip().replace("'",'') for x in str.split('\n') if x) return list(x.strip().replace("'",'') for x in str.split('\n') if x)
env = dict(os.environ) env = dict(os.environ)
""" % sys.executable) """ % sys.executable)
@ -1646,34 +1649,39 @@ def cmdlist(str):
for name in env_vars: for name in env_vars:
val = env[name] val = env[name]
if string.find(name, 'PATH') < 0: if string.find(name, 'PATH') < 0:
fout.write('env[%s] = %s\n' % (repr(name),repr(val))) fout.write('env[%s] = %s\n' % (repr(name), repr(val)))
else: else:
if name == 'SPACK_TRANSITIVE_INCLUDE_PATH': if name == 'SPACK_TRANSITIVE_INCLUDE_PATH':
sep = ';' sep = ';'
else: else:
sep = ':' sep = ':'
fout.write('env[%s] = "%s".join(cmdlist("""\n' % (repr(name),sep)) fout.write('env[%s] = "%s".join(cmdlist("""\n'
% (repr(name), sep))
for part in string.split(val, sep): for part in string.split(val, sep):
fout.write(' %s\n' % part) fout.write(' %s\n' % part)
fout.write('"""))\n') fout.write('"""))\n')
fout.write("env['CMAKE_TRANSITIVE_INCLUDE_PATH'] = env['SPACK_TRANSITIVE_INCLUDE_PATH'] # Deprecated\n") fout.write("env['CMAKE_TRANSITIVE_INCLUDE_PATH'] = "
"env['SPACK_TRANSITIVE_INCLUDE_PATH'] # Deprecated\n")
fout.write('\ncmd = cmdlist("""\n') fout.write('\ncmd = cmdlist("""\n')
fout.write('%s\n' % cmd[0]) fout.write('%s\n' % cmd[0])
for arg in cmd[1:]: for arg in cmd[1:]:
fout.write(' %s\n' % arg) fout.write(' %s\n' % arg)
fout.write('""") + sys.argv[1:]\n') fout.write('""") + sys.argv[1:]\n')
fout.write('\nproc = subprocess.Popen(cmd, env=env)\nproc.wait()\n') fout.write('\nproc = subprocess.Popen(cmd, env=env)\n')
fout.write('proc.wait()\n')
make_executable(setup_fname) make_executable(setup_fname)
def install_configure(self): def install_configure(self):
cmake = which('cmake') cmake = which('cmake')
with working_dir(self.build_directory, create=True): with working_dir(self.build_directory, create=True):
os.environ.update(self.configure_env()) env = os.environ
os.environ['SPACK_TRANSITIVE_INCLUDE_PATH'] = self.spack_transitive_include_path() env.update(self.configure_env())
options = self.configure_args() + spack.build_environment.get_std_cmake_args(self) env['SPACK_TRANSITIVE_INCLUDE_PATH'] = self.transitive_inc_path()
options = self.configure_args()
options += spack.build_environment.get_std_cmake_args(self)
cmake(self.source_directory, *options) cmake(self.source_directory, *options)
def install_build(self): def install_build(self):

View File

@ -96,7 +96,6 @@
expansion when it is the first character in an id typed on the command line. expansion when it is the first character in an id typed on the command line.
""" """
import sys import sys
import itertools
import hashlib import hashlib
import base64 import base64
import imp import imp
@ -116,8 +115,6 @@
import spack.error import spack.error
import spack.compilers as compilers import spack.compilers as compilers
# TODO: move display_specs to some other location.
from spack.cmd.find import display_specs
from spack.version import * from spack.version import *
from spack.util.string import * from spack.util.string import *
from spack.util.prefix import Prefix from spack.util.prefix import Prefix
@ -650,7 +647,8 @@ def _set_platform(self, value):
mod = imp.load_source(mod_name, path) mod = imp.load_source(mod_name, path)
class_name = mod_to_class(value) class_name = mod_to_class(value)
if not hasattr(mod, class_name): if not hasattr(mod, class_name):
tty.die('No class %s defined in %s' % (class_name, mod_name)) tty.die(
'No class %s defined in %s' % (class_name, mod_name))
cls = getattr(mod, class_name) cls = getattr(mod, class_name)
if not inspect.isclass(cls): if not inspect.isclass(cls):
tty.die('%s.%s is not a class' % (mod_name, class_name)) tty.die('%s.%s is not a class' % (mod_name, class_name))
@ -673,13 +671,15 @@ def _set_platform(self, value):
def _set_os(self, value): def _set_os(self, value):
"""Called by the parser to set the architecture operating system""" """Called by the parser to set the architecture operating system"""
if self.architecture.platform: arch = self.architecture
self.architecture.platform_os = self.architecture.platform.operating_system(value) if arch.platform:
arch.platform_os = arch.platform.operating_system(value)
def _set_target(self, value): def _set_target(self, value):
"""Called by the parser to set the architecture target""" """Called by the parser to set the architecture target"""
if self.architecture.platform: arch = self.architecture
self.architecture.target = self.architecture.platform.target(value) if arch.platform:
arch.target = arch.platform.target(value)
def _add_dependency(self, spec, deptypes): def _add_dependency(self, spec, deptypes):
"""Called by the parser to add another spec as a dependency.""" """Called by the parser to add another spec as a dependency."""
@ -694,8 +694,9 @@ def _add_dependency(self, spec, deptypes):
# #
@property @property
def fullname(self): def fullname(self):
return (('%s.%s' % (self.namespace, self.name)) if self.namespace else return (
(self.name if self.name else '')) ('%s.%s' % (self.namespace, self.name)) if self.namespace else
(self.name if self.name else ''))
@property @property
def root(self): def root(self):
@ -751,15 +752,15 @@ def concrete(self):
if self._concrete: if self._concrete:
return True return True
self._concrete = bool(not self.virtual self._concrete = bool(not self.virtual and
and self.namespace is not None self.namespace is not None and
and self.versions.concrete self.versions.concrete and
and self.variants.concrete self.variants.concrete and
and self.architecture self.architecture and
and self.architecture.concrete self.architecture.concrete and
and self.compiler and self.compiler.concrete self.compiler and self.compiler.concrete and
and self.compiler_flags.concrete self.compiler_flags.concrete and
and self._dependencies.concrete) self._dependencies.concrete)
return self._concrete return self._concrete
def traverse(self, visited=None, deptype=None, **kwargs): def traverse(self, visited=None, deptype=None, **kwargs):
@ -870,9 +871,9 @@ def return_val(res):
for name in sorted(successors): for name in sorted(successors):
child = successors[name] child = successors[name]
children = child.spec.traverse_with_deptype( children = child.spec.traverse_with_deptype(
visited, d=d + 1, deptype=deptype_query, visited, d=d + 1, deptype=deptype_query,
deptype_query=deptype_query, deptype_query=deptype_query,
_self_deptype=child.deptypes, **kwargs) _self_deptype=child.deptypes, **kwargs)
for elt in children: for elt in children:
yield elt yield elt
@ -995,7 +996,6 @@ def from_node_dict(node):
return spec return spec
@staticmethod @staticmethod
def read_yaml_dep_specs(dependency_dict): def read_yaml_dep_specs(dependency_dict):
"""Read the DependencySpec portion of a YAML-formatted Spec. """Read the DependencySpec portion of a YAML-formatted Spec.
@ -1018,7 +1018,6 @@ def read_yaml_dep_specs(dependency_dict):
yield dep_name, dag_hash, list(deptypes) yield dep_name, dag_hash, list(deptypes)
@staticmethod @staticmethod
def from_yaml(stream): def from_yaml(stream):
"""Construct a spec from YAML. """Construct a spec from YAML.
@ -1204,14 +1203,16 @@ def _expand_virtual_packages(self):
def feq(cfield, sfield): def feq(cfield, sfield):
return (not cfield) or (cfield == sfield) return (not cfield) or (cfield == sfield)
if replacement is spec or (feq(replacement.name, spec.name) and if replacement is spec or (
feq(replacement.versions, spec.versions) and feq(replacement.name, spec.name) and
feq(replacement.compiler, spec.compiler) and feq(replacement.versions, spec.versions) and
feq(replacement.architecture, spec.architecture) and feq(replacement.compiler, spec.compiler) and
feq(replacement._dependencies, spec._dependencies) and feq(replacement.architecture, spec.architecture) and
feq(replacement.variants, spec.variants) and feq(replacement._dependencies, spec._dependencies) and
feq(replacement.external, spec.external) and feq(replacement.variants, spec.variants) and
feq(replacement.external_module, spec.external_module)): feq(replacement.external, spec.external) and
feq(replacement.external_module,
spec.external_module)):
continue continue
# Refine this spec to the candidate. This uses # Refine this spec to the candidate. This uses
# replace_with AND dup so that it can work in # replace_with AND dup so that it can work in
@ -1268,10 +1269,10 @@ def concretize(self):
if s.namespace is None: if s.namespace is None:
s.namespace = spack.repo.repo_for_pkg(s.name).namespace s.namespace = spack.repo.repo_for_pkg(s.name).namespace
for s in self.traverse(root=False): for s in self.traverse(root=False):
if s.external_module: if s.external_module:
compiler = spack.compilers.compiler_for_spec(s.compiler, s.architecture) compiler = spack.compilers.compiler_for_spec(
s.compiler, s.architecture)
for mod in compiler.modules: for mod in compiler.modules:
load_module(mod) load_module(mod)
@ -1617,20 +1618,17 @@ def constrain(self, other, deps=True):
other.variants[v]) other.variants[v])
# TODO: Check out the logic here # TODO: Check out the logic here
if self.architecture is not None and other.architecture is not None: sarch, oarch = self.architecture, other.architecture
if self.architecture.platform is not None and other.architecture.platform is not None: if sarch is not None and oarch is not None:
if self.architecture.platform != other.architecture.platform: if sarch.platform is not None and oarch.platform is not None:
raise UnsatisfiableArchitectureSpecError(self.architecture, if sarch.platform != oarch.platform:
other.architecture) raise UnsatisfiableArchitectureSpecError(sarch, oarch)
if self.architecture.platform_os is not None and other.architecture.platform_os is not None: if sarch.platform_os is not None and oarch.platform_os is not None:
if self.architecture.platform_os != other.architecture.platform_os: if sarch.platform_os != oarch.platform_os:
raise UnsatisfiableArchitectureSpecError(self.architecture, raise UnsatisfiableArchitectureSpecError(sarch, oarch)
other.architecture) if sarch.target is not None and oarch.target is not None:
if self.architecture.target is not None and other.architecture.target is not None: if sarch.target != oarch.target:
if self.architecture.target != other.architecture.target: raise UnsatisfiableArchitectureSpecError(sarch, oarch)
raise UnsatisfiableArchitectureSpecError(self.architecture,
other.architecture)
changed = False changed = False
if self.compiler is not None and other.compiler is not None: if self.compiler is not None and other.compiler is not None:
@ -1645,15 +1643,16 @@ def constrain(self, other, deps=True):
changed |= self.compiler_flags.constrain(other.compiler_flags) changed |= self.compiler_flags.constrain(other.compiler_flags)
old = str(self.architecture) old = str(self.architecture)
if self.architecture is None or other.architecture is None: sarch, oarch = self.architecture, other.architecture
self.architecture = self.architecture or other.architecture if sarch is None or other.architecture is None:
self.architecture = sarch or oarch
else: else:
if self.architecture.platform is None or other.architecture.platform is None: if sarch.platform is None or oarch.platform is None:
self.architecture.platform = self.architecture.platform or other.architecture.platform self.architecture.platform = sarch.platform or oarch.platform
if self.architecture.platform_os is None or other.architecture.platform_os is None: if sarch.platform_os is None or oarch.platform_os is None:
self.architecture.platform_os = self.architecture.platform_os or other.architecture.platform_os sarch.platform_os = sarch.platform_os or oarch.platform_os
if self.architecture.target is None or other.architecture.target is None: if sarch.target is None or oarch.target is None:
self.architecture.target = self.architecture.target or other.architecture.target sarch.target = sarch.target or oarch.target
changed |= (str(self.architecture) != old) changed |= (str(self.architecture) != old)
if deps: if deps:
@ -1784,15 +1783,25 @@ def satisfies(self, other, deps=True, strict=False):
# Architecture satisfaction is currently just string equality. # Architecture satisfaction is currently just string equality.
# If not strict, None means unconstrained. # If not strict, None means unconstrained.
if self.architecture and other.architecture: sarch, oarch = self.architecture, other.architecture
if ((self.architecture.platform and other.architecture.platform and self.architecture.platform != other.architecture.platform) or if sarch and oarch:
(self.architecture.platform_os and other.architecture.platform_os and self.architecture.platform_os != other.architecture.platform_os) or if ((sarch.platform and
(self.architecture.target and other.architecture.target and self.architecture.target != other.architecture.target)): oarch.platform and
sarch.platform != oarch.platform) or
(sarch.platform_os and
oarch.platform_os and
sarch.platform_os != oarch.platform_os) or
(sarch.target and
oarch.target and
sarch.target != oarch.target)):
return False return False
elif strict and ((other.architecture and not self.architecture) or
(other.architecture.platform and not self.architecture.platform) or elif strict and ((oarch and not sarch) or
(other.architecture.platform_os and not self.architecture.platform_os) or (oarch.platform and not sarch.platform) or
(other.architecture.target and not self.architecture.target)): (oarch.platform_os and not sarch.platform_os) or
(oarch.target and not sarch.target)):
return False return False
if not self.compiler_flags.satisfies( if not self.compiler_flags.satisfies(
@ -1874,11 +1883,16 @@ def _dup(self, other, **kwargs):
# We don't count dependencies as changes here # We don't count dependencies as changes here
changed = True changed = True
if hasattr(self, 'name'): if hasattr(self, 'name'):
changed = (self.name != other.name and self.versions != other.versions and \ changed = (self.name != other.name and
self.architecture != other.architecture and self.compiler != other.compiler and \ self.versions != other.versions and
self.variants != other.variants and self._normal != other._normal and \ self.architecture != other.architecture and
self.concrete != other.concrete and self.external != other.external and \ self.compiler != other.compiler and
self.external_module != other.external_module and self.compiler_flags != other.compiler_flags) self.variants != other.variants and
self._normal != other._normal and
self.concrete != other.concrete and
self.external != other.external and
self.external_module != other.external_module and
self.compiler_flags != other.compiler_flags)
# Local node attributes get copied first. # Local node attributes get copied first.
self.name = other.name self.name = other.name
@ -1922,7 +1936,7 @@ def _dup(self, other, **kwargs):
# here. # here.
if depspec.spec.name not in new_spec._dependencies: if depspec.spec.name not in new_spec._dependencies:
new_spec._add_dependency( new_spec._add_dependency(
new_nodes[depspec.spec.name], depspec.deptypes) new_nodes[depspec.spec.name], depspec.deptypes)
# Since we preserved structure, we can copy _normal safely. # Since we preserved structure, we can copy _normal safely.
self._normal = other._normal self._normal = other._normal
@ -2033,7 +2047,6 @@ def _cmp_node(self):
self.compiler, self.compiler,
self.compiler_flags) self.compiler_flags)
def eq_node(self, other): def eq_node(self, other):
"""Equality with another spec, not including dependencies.""" """Equality with another spec, not including dependencies."""
return self._cmp_node() == other._cmp_node() return self._cmp_node() == other._cmp_node()
@ -2229,41 +2242,39 @@ def write(s, c):
def dep_string(self): def dep_string(self):
return ''.join("^" + dep.format() for dep in self.sorted_deps()) return ''.join("^" + dep.format() for dep in self.sorted_deps())
def __cmp__(self, other): def __cmp__(self, other):
#Package name sort order is not configurable, always goes alphabetical # Package name sort order is not configurable, always goes alphabetical
if self.name != other.name: if self.name != other.name:
return cmp(self.name, other.name) return cmp(self.name, other.name)
#Package version is second in compare order # Package version is second in compare order
pkgname = self.name pkgname = self.name
if self.versions != other.versions: if self.versions != other.versions:
return spack.pkgsort.version_compare(pkgname, return spack.pkgsort.version_compare(
self.versions, other.versions) pkgname, self.versions, other.versions)
#Compiler is third # Compiler is third
if self.compiler != other.compiler: if self.compiler != other.compiler:
return spack.pkgsort.compiler_compare(pkgname, return spack.pkgsort.compiler_compare(
self.compiler, other.compiler) pkgname, self.compiler, other.compiler)
#Variants # Variants
if self.variants != other.variants: if self.variants != other.variants:
return spack.pkgsort.variant_compare(pkgname, return spack.pkgsort.variant_compare(
self.variants, other.variants) pkgname, self.variants, other.variants)
#Target # Target
if self.architecture != other.architecture: if self.architecture != other.architecture:
return spack.pkgsort.architecture_compare(pkgname, return spack.pkgsort.architecture_compare(
self.architecture, other.architecture) pkgname, self.architecture, other.architecture)
#Dependency is not configurable # Dependency is not configurable
if self._dependencies != other._dependencies: if self._dependencies != other._dependencies:
return -1 if self._dependencies < other._dependencies else 1 return -1 if self._dependencies < other._dependencies else 1
#Equal specs # Equal specs
return 0 return 0
def __str__(self): def __str__(self):
return self.format() + self.dep_string() return self.format() + self.dep_string()
@ -2338,8 +2349,8 @@ def __init__(self):
# Lexer is always the same for every parser. # Lexer is always the same for every parser.
_lexer = SpecLexer() _lexer = SpecLexer()
class SpecParser(spack.parse.Parser):
class SpecParser(spack.parse.Parser):
def __init__(self): def __init__(self):
super(SpecParser, self).__init__(_lexer) super(SpecParser, self).__init__(_lexer)
self.previous = None self.previous = None
@ -2392,8 +2403,8 @@ def do_parse(self):
except spack.parse.ParseError, e: except spack.parse.ParseError, e:
raise SpecParseError(e) raise SpecParseError(e)
# If the spec has an os or a target and no platform, give it
# If the spec has an os or a target and no platform, give it the default platform # the default platform
for spec in specs: for spec in specs:
for s in spec.traverse(): for s in spec.traverse():
if s.architecture.os_string or s.architecture.target_string: if s.architecture.os_string or s.architecture.target_string:

View File

@ -1,7 +1,31 @@
##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
""" Test checks if the architecture class is created correctly and also that """ Test checks if the architecture class is created correctly and also that
the functions are looking for the correct architecture name the functions are looking for the correct architecture name
""" """
import unittest import itertools
import os import os
import platform as py_platform import platform as py_platform
import spack import spack
@ -14,9 +38,8 @@
from spack.test.mock_packages_test import * from spack.test.mock_packages_test import *
#class ArchitectureTest(unittest.TestCase):
class ArchitectureTest(MockPackagesTest):
class ArchitectureTest(MockPackagesTest):
def setUp(self): def setUp(self):
super(ArchitectureTest, self).setUp() super(ArchitectureTest, self).setUp()
self.platform = spack.architecture.platform() self.platform = spack.architecture.platform()
@ -36,24 +59,22 @@ def test_dict_functions_for_architecture(self):
self.assertEqual(arch, new_arch) self.assertEqual(arch, new_arch)
self.assertTrue( isinstance(arch, spack.architecture.Arch) ) self.assertTrue(isinstance(arch, spack.architecture.Arch))
self.assertTrue( isinstance(arch.platform, spack.architecture.Platform) ) self.assertTrue(isinstance(arch.platform, spack.architecture.Platform))
self.assertTrue( isinstance(arch.platform_os, self.assertTrue(isinstance(arch.platform_os,
spack.architecture.OperatingSystem) ) spack.architecture.OperatingSystem))
self.assertTrue( isinstance(arch.target, self.assertTrue(isinstance(arch.target,
spack.architecture.Target) ) spack.architecture.Target))
self.assertTrue( isinstance(new_arch, spack.architecture.Arch) ) self.assertTrue(isinstance(new_arch, spack.architecture.Arch))
self.assertTrue( isinstance(new_arch.platform, self.assertTrue(isinstance(new_arch.platform,
spack.architecture.Platform) ) spack.architecture.Platform))
self.assertTrue( isinstance(new_arch.platform_os, self.assertTrue(isinstance(new_arch.platform_os,
spack.architecture.OperatingSystem) ) spack.architecture.OperatingSystem))
self.assertTrue( isinstance(new_arch.target, self.assertTrue(isinstance(new_arch.target,
spack.architecture.Target) ) spack.architecture.Target))
def test_platform(self): def test_platform(self):
output_platform_class = spack.architecture.platform() output_platform_class = spack.architecture.platform()
my_arch_class = None
if os.path.exists('/opt/cray/craype'): if os.path.exists('/opt/cray/craype'):
my_platform_class = CrayXc() my_platform_class = CrayXc()
elif os.path.exists('/bgsys'): elif os.path.exists('/bgsys'):
@ -91,7 +112,7 @@ def test_user_defaults(self):
default_os = self.platform.operating_system("default_os") default_os = self.platform.operating_system("default_os")
default_target = self.platform.target("default_target") default_target = self.platform.target("default_target")
default_spec = Spec("libelf") # default is no args default_spec = Spec("libelf") # default is no args
default_spec.concretize() default_spec.concretize()
self.assertEqual(default_os, default_spec.architecture.platform_os) self.assertEqual(default_os, default_spec.architecture.platform_os)
self.assertEqual(default_target, default_spec.architecture.target) self.assertEqual(default_target, default_spec.architecture.target)
@ -107,10 +128,11 @@ def test_user_input_combination(self):
combinations = itertools.product(os_list, target_list) combinations = itertools.product(os_list, target_list)
results = [] results = []
for arch in combinations: for arch in combinations:
o,t = arch o, t = arch
spec = Spec("libelf os=%s target=%s" % (o, t)) spec = Spec("libelf os=%s target=%s" % (o, t))
spec.concretize() spec.concretize()
results.append(spec.architecture.platform_os == self.platform.operating_system(o)) results.append(spec.architecture.platform_os ==
self.platform.operating_system(o))
results.append(spec.architecture.target == self.platform.target(t)) results.append(spec.architecture.target == self.platform.target(t))
res = all(results) res = all(results)