Features: Improve Spec format strings (#10556)
* Update spec format to simpler syntax, maintain backwards compatibility * Switch to new spec.format method throughout internals * update package files for new format strings * documentation and minor code cleanup. removed nonsensical variant sigils
This commit is contained in:
parent
49334f006d
commit
f242f5f8a9
@ -39,7 +39,7 @@ default path uses the full 32 characters.
|
|||||||
Secondly, it is
|
Secondly, it is
|
||||||
also possible to modify the entire installation scheme. By default
|
also possible to modify the entire installation scheme. By default
|
||||||
Spack uses
|
Spack uses
|
||||||
``${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}``
|
``{architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}``
|
||||||
where the tokens that are available for use in this directive are the
|
where the tokens that are available for use in this directive are the
|
||||||
same as those understood by the ``Spec.format`` method. Using this parameter it
|
same as those understood by the ``Spec.format`` method. Using this parameter it
|
||||||
is possible to use a different package layout or reduce the depth of
|
is possible to use a different package layout or reduce the depth of
|
||||||
@ -48,7 +48,7 @@ the installation paths. For example
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
config:
|
config:
|
||||||
install_path_scheme: '${PACKAGE}/${VERSION}/${HASH:7}'
|
install_path_scheme: '{name}/{version}/{hash:7}'
|
||||||
|
|
||||||
would install packages into sub-directories using only the package
|
would install packages into sub-directories using only the package
|
||||||
name, version and a hash length of 7 characters.
|
name, version and a hash length of 7 characters.
|
||||||
|
@ -459,7 +459,7 @@ account all scopes. For example, to see the fully merged
|
|||||||
install_tree: $spack/opt/spack
|
install_tree: $spack/opt/spack
|
||||||
template_dirs:
|
template_dirs:
|
||||||
- $spack/templates
|
- $spack/templates
|
||||||
directory_layout: ${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}
|
directory_layout: {architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}
|
||||||
module_roots:
|
module_roots:
|
||||||
tcl: $spack/share/spack/modules
|
tcl: $spack/share/spack/modules
|
||||||
lmod: $spack/share/spack/lmod
|
lmod: $spack/share/spack/lmod
|
||||||
@ -510,7 +510,7 @@ down the problem:
|
|||||||
./my-scope/config.yaml:2 install_tree: /path/to/some/tree
|
./my-scope/config.yaml:2 install_tree: /path/to/some/tree
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:23 template_dirs:
|
/home/myuser/spack/etc/spack/defaults/config.yaml:23 template_dirs:
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:24 - $spack/templates
|
/home/myuser/spack/etc/spack/defaults/config.yaml:24 - $spack/templates
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:28 directory_layout: ${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}
|
/home/myuser/spack/etc/spack/defaults/config.yaml:28 directory_layout: {architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:32 module_roots:
|
/home/myuser/spack/etc/spack/defaults/config.yaml:32 module_roots:
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:33 tcl: $spack/share/spack/modules
|
/home/myuser/spack/etc/spack/defaults/config.yaml:33 tcl: $spack/share/spack/modules
|
||||||
/home/myuser/spack/etc/spack/defaults/config.yaml:34 lmod: $spack/share/spack/lmod
|
/home/myuser/spack/etc/spack/defaults/config.yaml:34 lmod: $spack/share/spack/lmod
|
||||||
|
@ -535,10 +535,10 @@ most likely via the ``+blas`` variant specification.
|
|||||||
|
|
||||||
modules:
|
modules:
|
||||||
tcl:
|
tcl:
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
- 'intel/14.0.1'
|
- 'intel/14.0.1'
|
||||||
|
|
||||||
will create module files that will conflict with ``intel/14.0.1`` and with the
|
will create module files that will conflict with ``intel/14.0.1`` and with the
|
||||||
|
@ -646,14 +646,14 @@ modules that refer to different flavors of the same library/application:
|
|||||||
modules:
|
modules:
|
||||||
tcl:
|
tcl:
|
||||||
hash_length: 0
|
hash_length: 0
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||||
whitelist:
|
whitelist:
|
||||||
- gcc
|
- gcc
|
||||||
blacklist:
|
blacklist:
|
||||||
- '%gcc@5.4.0'
|
- '%gcc@5.4.0'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
suffixes:
|
suffixes:
|
||||||
'^openblas': openblas
|
'^openblas': openblas
|
||||||
'^netlib-lapack': netlib
|
'^netlib-lapack': netlib
|
||||||
@ -713,14 +713,14 @@ is installed. You can achieve this with Spack by adding an
|
|||||||
modules:
|
modules:
|
||||||
tcl:
|
tcl:
|
||||||
hash_length: 0
|
hash_length: 0
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||||
whitelist:
|
whitelist:
|
||||||
- gcc
|
- gcc
|
||||||
blacklist:
|
blacklist:
|
||||||
- '%gcc@5.4.0'
|
- '%gcc@5.4.0'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
suffixes:
|
suffixes:
|
||||||
'^openblas': openblas
|
'^openblas': openblas
|
||||||
'^netlib-lapack': netlib
|
'^netlib-lapack': netlib
|
||||||
@ -728,7 +728,7 @@ is installed. You can achieve this with Spack by adding an
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
netlib-scalapack:
|
netlib-scalapack:
|
||||||
suffixes:
|
suffixes:
|
||||||
'^openmpi': openmpi
|
'^openmpi': openmpi
|
||||||
@ -737,8 +737,9 @@ is installed. You can achieve this with Spack by adding an
|
|||||||
Under the hood Spack uses the :meth:`~spack.spec.Spec.format` API to substitute
|
Under the hood Spack uses the :meth:`~spack.spec.Spec.format` API to substitute
|
||||||
tokens in either environment variable names or values. There are two caveats though:
|
tokens in either environment variable names or values. There are two caveats though:
|
||||||
|
|
||||||
- The set of allowed tokens in variable names is restricted to ``PACKAGE``,
|
- The set of allowed tokens in variable names is restricted to
|
||||||
``VERSION``, ``COMPILER``, ``COMPILERNAME``, ``COMPILERVER``, ``ARCHITECTURE``
|
``name``, ``version``, ``compiler``, ``compiler.name``,
|
||||||
|
``compiler.version``, ``architecture``
|
||||||
- Any token expanded in a variable name is made uppercase, but other than that
|
- Any token expanded in a variable name is made uppercase, but other than that
|
||||||
case sensitivity is preserved
|
case sensitivity is preserved
|
||||||
|
|
||||||
@ -784,14 +785,14 @@ etc. in the ``gcc`` module file and apply other custom modifications to the
|
|||||||
modules:
|
modules:
|
||||||
tcl:
|
tcl:
|
||||||
hash_length: 0
|
hash_length: 0
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||||
whitelist:
|
whitelist:
|
||||||
- gcc
|
- gcc
|
||||||
blacklist:
|
blacklist:
|
||||||
- '%gcc@5.4.0'
|
- '%gcc@5.4.0'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
suffixes:
|
suffixes:
|
||||||
'^openblas': openblas
|
'^openblas': openblas
|
||||||
'^netlib-lapack': netlib
|
'^netlib-lapack': netlib
|
||||||
@ -799,7 +800,7 @@ etc. in the ``gcc`` module file and apply other custom modifications to the
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
gcc:
|
gcc:
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
@ -896,14 +897,14 @@ directive and assigning it the value ``direct``:
|
|||||||
tcl:
|
tcl:
|
||||||
verbose: True
|
verbose: True
|
||||||
hash_length: 0
|
hash_length: 0
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||||
whitelist:
|
whitelist:
|
||||||
- gcc
|
- gcc
|
||||||
blacklist:
|
blacklist:
|
||||||
- '%gcc@5.4.0'
|
- '%gcc@5.4.0'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
suffixes:
|
suffixes:
|
||||||
'^openblas': openblas
|
'^openblas': openblas
|
||||||
'^netlib-lapack': netlib
|
'^netlib-lapack': netlib
|
||||||
@ -911,7 +912,7 @@ directive and assigning it the value ``direct``:
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
gcc:
|
gcc:
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
@ -1089,7 +1090,7 @@ After these modifications your configuration file should look like:
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
gcc:
|
gcc:
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
@ -1298,7 +1299,7 @@ Coming back to our example, let's add ``lapack`` to the hierarchy and remove any
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
gcc:
|
gcc:
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
@ -1534,7 +1535,7 @@ it's ``netlib-scalapack``:
|
|||||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
gcc:
|
gcc:
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
|
@ -541,9 +541,9 @@ spec format strings, as shown in the example below.
|
|||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
projections:
|
projections:
|
||||||
zlib: ${PACKAGE}-${VERSION}
|
zlib: {name}-{version}
|
||||||
^mpi: ${PACKAGE}-${VERSION}/${DEP:mpi:PACKAGE}-${DEP:mpi:VERSION}-${COMPILERNAME}-${COMPILERVER}
|
^mpi: {name}-{version}/{^mpi.name}-{^mpi.version}-{compiler.name}-{compiler.version}
|
||||||
all: ${PACKAGE}-${VERSION}/${COMPILERNAME}-${COMPILERVER}
|
all: {name}-{version}/{compiler.name}-{compiler.version}
|
||||||
|
|
||||||
The entries in the projections configuration file must all be either
|
The entries in the projections configuration file must all be either
|
||||||
specs or the keyword ``all``. For each spec, the projection used will
|
specs or the keyword ``all``. For each spec, the projection used will
|
||||||
|
@ -336,7 +336,7 @@ def __init__(self, plat=None, os=None, target=None):
|
|||||||
self.platform = plat
|
self.platform = plat
|
||||||
if plat and os:
|
if plat and os:
|
||||||
os = self.platform.operating_system(os)
|
os = self.platform.operating_system(os)
|
||||||
self.platform_os = os
|
self.os = os
|
||||||
if plat and target:
|
if plat and target:
|
||||||
target = self.platform.target(target)
|
target = self.platform.target(target)
|
||||||
self.target = target
|
self.target = target
|
||||||
@ -349,16 +349,16 @@ def __init__(self, plat=None, os=None, target=None):
|
|||||||
def concrete(self):
|
def concrete(self):
|
||||||
return all((self.platform is not None,
|
return all((self.platform is not None,
|
||||||
isinstance(self.platform, Platform),
|
isinstance(self.platform, Platform),
|
||||||
self.platform_os is not None,
|
self.os is not None,
|
||||||
isinstance(self.platform_os, OperatingSystem),
|
isinstance(self.os, OperatingSystem),
|
||||||
self.target is not None, isinstance(self.target, Target)))
|
self.target is not None, isinstance(self.target, Target)))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.platform or self.platform_os or self.target:
|
if self.platform or self.os or self.target:
|
||||||
if self.platform.name == 'darwin':
|
if self.platform.name == 'darwin':
|
||||||
os_name = self.platform_os.name if self.platform_os else "None"
|
os_name = self.os.name if self.os else "None"
|
||||||
else:
|
else:
|
||||||
os_name = str(self.platform_os)
|
os_name = str(self.os)
|
||||||
|
|
||||||
return (str(self.platform) + "-" +
|
return (str(self.platform) + "-" +
|
||||||
os_name + "-" + str(self.target))
|
os_name + "-" + str(self.target))
|
||||||
@ -371,7 +371,7 @@ def __contains__(self, string):
|
|||||||
# TODO: make this unnecessary: don't include an empty arch on *every* spec.
|
# TODO: make this unnecessary: don't include an empty arch on *every* spec.
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
return (self.platform is not None or
|
return (self.platform is not None or
|
||||||
self.platform_os is not None or
|
self.os is not None or
|
||||||
self.target is not None)
|
self.target is not None)
|
||||||
__bool__ = __nonzero__
|
__bool__ = __nonzero__
|
||||||
|
|
||||||
@ -380,21 +380,21 @@ def _cmp_key(self):
|
|||||||
platform = self.platform.name
|
platform = self.platform.name
|
||||||
else:
|
else:
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
if isinstance(self.platform_os, OperatingSystem):
|
if isinstance(self.os, OperatingSystem):
|
||||||
platform_os = self.platform_os.name
|
os = self.os.name
|
||||||
else:
|
else:
|
||||||
platform_os = self.platform_os
|
os = self.os
|
||||||
if isinstance(self.target, Target):
|
if isinstance(self.target, Target):
|
||||||
target = self.target.name
|
target = self.target.name
|
||||||
else:
|
else:
|
||||||
target = self.target
|
target = self.target
|
||||||
return (platform, platform_os, target)
|
return (platform, os, target)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
str_or_none = lambda v: str(v) if v else None
|
str_or_none = lambda v: str(v) if v else None
|
||||||
d = syaml_dict([
|
d = syaml_dict([
|
||||||
('platform', str_or_none(self.platform)),
|
('platform', str_or_none(self.platform)),
|
||||||
('platform_os', str_or_none(self.platform_os)),
|
('platform_os', str_or_none(self.os)),
|
||||||
('target', str_or_none(self.target))])
|
('target', str_or_none(self.target))])
|
||||||
return syaml_dict([('arch', d)])
|
return syaml_dict([('arch', d)])
|
||||||
|
|
||||||
@ -430,13 +430,13 @@ def arch_for_spec(arch_spec):
|
|||||||
assert(arch_spec.concrete)
|
assert(arch_spec.concrete)
|
||||||
|
|
||||||
arch_plat = get_platform(arch_spec.platform)
|
arch_plat = get_platform(arch_spec.platform)
|
||||||
if not (arch_plat.operating_system(arch_spec.platform_os) and
|
if not (arch_plat.operating_system(arch_spec.os) and
|
||||||
arch_plat.target(arch_spec.target)):
|
arch_plat.target(arch_spec.target)):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Can't recreate arch for spec %s on current arch %s; "
|
"Can't recreate arch for spec %s on current arch %s; "
|
||||||
"spec architecture is too different" % (arch_spec, sys_type()))
|
"spec architecture is too different" % (arch_spec, sys_type()))
|
||||||
|
|
||||||
return Arch(arch_plat, arch_spec.platform_os, arch_spec.target)
|
return Arch(arch_plat, arch_spec.os, arch_spec.target)
|
||||||
|
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
|
@ -381,7 +381,7 @@ def set_build_environment_variables(pkg, env, dirty):
|
|||||||
if spack.config.get('config:debug'):
|
if spack.config.get('config:debug'):
|
||||||
env.set(SPACK_DEBUG, 'TRUE')
|
env.set(SPACK_DEBUG, 'TRUE')
|
||||||
env.set(SPACK_SHORT_SPEC, pkg.spec.short_spec)
|
env.set(SPACK_SHORT_SPEC, pkg.spec.short_spec)
|
||||||
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format('${PACKAGE}-${HASH:7}'))
|
env.set(SPACK_DEBUG_LOG_ID, pkg.spec.format('{name}-{hash:7}'))
|
||||||
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)
|
env.set(SPACK_DEBUG_LOG_DIR, spack.main.spack_working_dir)
|
||||||
|
|
||||||
# Find ccache binary and hand it to build environment
|
# Find ccache binary and hand it to build environment
|
||||||
|
@ -184,10 +184,11 @@ def disambiguate_spec(spec, env):
|
|||||||
tty.die("Spec '%s' matches no installed packages." % spec)
|
tty.die("Spec '%s' matches no installed packages." % spec)
|
||||||
|
|
||||||
elif len(matching_specs) > 1:
|
elif len(matching_specs) > 1:
|
||||||
|
format_string = '{name}{@version}{%compiler}{arch=architecture}'
|
||||||
args = ["%s matches multiple packages." % spec,
|
args = ["%s matches multiple packages." % spec,
|
||||||
"Matching packages:"]
|
"Matching packages:"]
|
||||||
args += [colorize(" @K{%s} " % s.dag_hash(7)) +
|
args += [colorize(" @K{%s} " % s.dag_hash(7)) +
|
||||||
s.cformat('$_$@$%@$=') for s in matching_specs]
|
s.cformat(format_string) for s in matching_specs]
|
||||||
args += ["Use a more specific spec."]
|
args += ["Use a more specific spec."]
|
||||||
tty.die(*args)
|
tty.die(*args)
|
||||||
|
|
||||||
@ -263,15 +264,15 @@ def get_arg(name, default=None):
|
|||||||
hashes = True
|
hashes = True
|
||||||
hlen = None
|
hlen = None
|
||||||
|
|
||||||
nfmt = '{fullpackage}' if namespace else '{package}'
|
nfmt = '{namespace}{name}' if namespace else '{name}'
|
||||||
ffmt = ''
|
ffmt = ''
|
||||||
if full_compiler or flags:
|
if full_compiler or flags:
|
||||||
ffmt += '$%'
|
ffmt += '{%compiler.name}'
|
||||||
if full_compiler:
|
if full_compiler:
|
||||||
ffmt += '@'
|
ffmt += '{@compiler.version}'
|
||||||
ffmt += '+'
|
ffmt += ' {compiler_flags}'
|
||||||
vfmt = '$+' if variants else ''
|
vfmt = '{variants}' if variants else ''
|
||||||
format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt)
|
format_string = nfmt + '{@version}' + ffmt + vfmt
|
||||||
|
|
||||||
# Make a dict with specs keyed by architecture and compiler.
|
# Make a dict with specs keyed by architecture and compiler.
|
||||||
index = index_by(specs, ('architecture', 'compiler'))
|
index = index_by(specs, ('architecture', 'compiler'))
|
||||||
@ -329,7 +330,7 @@ def fmt(s):
|
|||||||
if hashes:
|
if hashes:
|
||||||
string += gray_hash(s, hlen) + ' '
|
string += gray_hash(s, hlen) + ' '
|
||||||
string += s.cformat(
|
string += s.cformat(
|
||||||
'$%s$@%s' % (nfmt, vfmt), transform=transform)
|
nfmt + '{@version}' + vfmt, transform=transform)
|
||||||
return string
|
return string
|
||||||
|
|
||||||
if not flags and not full_compiler:
|
if not flags and not full_compiler:
|
||||||
|
@ -32,7 +32,7 @@ def arch(parser, args):
|
|||||||
if args.platform:
|
if args.platform:
|
||||||
print(arch.platform)
|
print(arch.platform)
|
||||||
elif args.operating_system:
|
elif args.operating_system:
|
||||||
print(arch.platform_os)
|
print(arch.os)
|
||||||
elif args.target:
|
elif args.target:
|
||||||
print(arch.target)
|
print(arch.target)
|
||||||
else:
|
else:
|
||||||
|
@ -42,7 +42,8 @@ def dependencies(parser, args):
|
|||||||
env = ev.get_env(args, 'dependencies')
|
env = ev.get_env(args, 'dependencies')
|
||||||
spec = spack.cmd.disambiguate_spec(specs[0], env)
|
spec = spack.cmd.disambiguate_spec(specs[0], env)
|
||||||
|
|
||||||
tty.msg("Dependencies of %s" % spec.format('$_$@$%@$/', color=True))
|
format_string = '{name}{@version}{%compiler}{/hash:7}'
|
||||||
|
tty.msg("Dependencies of %s" % spec.format(format_string, color=True))
|
||||||
deps = spack.store.db.installed_relatives(
|
deps = spack.store.db.installed_relatives(
|
||||||
spec, 'children', args.transitive)
|
spec, 'children', args.transitive)
|
||||||
if deps:
|
if deps:
|
||||||
|
@ -85,7 +85,8 @@ def dependents(parser, args):
|
|||||||
env = ev.get_env(args, 'dependents')
|
env = ev.get_env(args, 'dependents')
|
||||||
spec = spack.cmd.disambiguate_spec(specs[0], env)
|
spec = spack.cmd.disambiguate_spec(specs[0], env)
|
||||||
|
|
||||||
tty.msg("Dependents of %s" % spec.cformat('$_$@$%@$/'))
|
format_string = '{name}{@version}{%compiler}{/hash:7}'
|
||||||
|
tty.msg("Dependents of %s" % spec.cformat(format_string))
|
||||||
deps = spack.store.db.installed_relatives(
|
deps = spack.store.db.installed_relatives(
|
||||||
spec, 'parents', args.transitive)
|
spec, 'parents', args.transitive)
|
||||||
if deps:
|
if deps:
|
||||||
|
@ -162,7 +162,7 @@ def mirror_create(args):
|
|||||||
# If nothing is passed, use all packages.
|
# If nothing is passed, use all packages.
|
||||||
if not specs:
|
if not specs:
|
||||||
specs = [Spec(n) for n in spack.repo.all_package_names()]
|
specs = [Spec(n) for n in spack.repo.all_package_names()]
|
||||||
specs.sort(key=lambda s: s.format("$_$@").lower())
|
specs.sort(key=lambda s: s.format("{name}{@version}").lower())
|
||||||
|
|
||||||
# If the user asked for dependencies, traverse spec DAG get them.
|
# If the user asked for dependencies, traverse spec DAG get them.
|
||||||
if args.dependencies:
|
if args.dependencies:
|
||||||
@ -204,7 +204,7 @@ def mirror_create(args):
|
|||||||
" %-4d failed to fetch." % e)
|
" %-4d failed to fetch." % e)
|
||||||
if error:
|
if error:
|
||||||
tty.error("Failed downloads:")
|
tty.error("Failed downloads:")
|
||||||
colify(s.cformat("$_$@") for s in error)
|
colify(s.cformat("{name}{@version}") for s in error)
|
||||||
|
|
||||||
|
|
||||||
def mirror(parser, args):
|
def mirror(parser, args):
|
||||||
|
@ -344,7 +344,9 @@ def modules_cmd(parser, args, module_type, callbacks=callbacks):
|
|||||||
except MultipleSpecsMatch:
|
except MultipleSpecsMatch:
|
||||||
msg = "the constraint '{query}' matches multiple packages:\n"
|
msg = "the constraint '{query}' matches multiple packages:\n"
|
||||||
for s in specs:
|
for s in specs:
|
||||||
msg += '\t' + s.cformat(format_string='$/ $_$@$+$%@+$+$=') + '\n'
|
spec_fmt = '{hash:7} {name}{@version}{%compiler}'
|
||||||
|
spec_fmt += '{compiler_flags}{variants}{arch=architecture}'
|
||||||
|
msg += '\t' + s.cformat(spec_fmt) + '\n'
|
||||||
tty.error(msg.format(query=args.constraint))
|
tty.error(msg.format(query=args.constraint))
|
||||||
tty.die('In this context exactly **one** match is needed: please specify your constraints better.') # NOQA: ignore=E501
|
tty.die('In this context exactly **one** match is needed: please specify your constraints better.') # NOQA: ignore=E501
|
||||||
|
|
||||||
|
@ -42,11 +42,12 @@ def setup_parser(subparser):
|
|||||||
|
|
||||||
|
|
||||||
def spec(parser, args):
|
def spec(parser, args):
|
||||||
name_fmt = '$.' if args.namespaces else '$_'
|
name_fmt = '{namespace}.{name}' if args.namespaces else '{name}'
|
||||||
|
fmt = '{@version}{%compiler}{compiler_flags}{variants}{arch=architecture}'
|
||||||
install_status_fn = spack.spec.Spec.install_status
|
install_status_fn = spack.spec.Spec.install_status
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'cover': args.cover,
|
'cover': args.cover,
|
||||||
'format': name_fmt + '$@$%@+$+$=',
|
'format': name_fmt + fmt,
|
||||||
'hashlen': None if args.very_long else 7,
|
'hashlen': None if args.very_long else 7,
|
||||||
'show_types': args.types,
|
'show_types': args.types,
|
||||||
'status_fn': install_status_fn if args.install_status else None
|
'status_fn': install_status_fn if args.install_status else None
|
||||||
|
@ -260,7 +260,8 @@ def get_uninstall_list(args, specs, env):
|
|||||||
if i > 0:
|
if i > 0:
|
||||||
print()
|
print()
|
||||||
|
|
||||||
tty.info("Will not uninstall %s" % spec.cformat("$_$@$%@$/"),
|
spec_format = '{name}{@version}{%compiler}{/hash:7}'
|
||||||
|
tty.info("Will not uninstall %s" % spec.cformat(spec_format),
|
||||||
format='*r')
|
format='*r')
|
||||||
|
|
||||||
dependents = active_dpts.get(spec)
|
dependents = active_dpts.get(spec)
|
||||||
|
@ -70,10 +70,11 @@ def squash(matching_specs):
|
|||||||
matching_in_view = [ms for ms in matching_specs if ms in view_specs]
|
matching_in_view = [ms for ms in matching_specs if ms in view_specs]
|
||||||
|
|
||||||
if len(matching_in_view) > 1:
|
if len(matching_in_view) > 1:
|
||||||
|
spec_format = '{name}{@version}{%compiler}{arch=architecture}'
|
||||||
args = ["Spec matches multiple packages.",
|
args = ["Spec matches multiple packages.",
|
||||||
"Matching packages:"]
|
"Matching packages:"]
|
||||||
args += [colorize(" @K{%s} " % s.dag_hash(7)) +
|
args += [colorize(" @K{%s} " % s.dag_hash(7)) +
|
||||||
s.cformat('$_$@$%@$=') for s in matching_in_view]
|
s.cformat(spec_format) for s in matching_in_view]
|
||||||
args += ["Use a more specific spec."]
|
args += ["Use a more specific spec."]
|
||||||
tty.die(*args)
|
tty.die(*args)
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ def get_compilers(config, cspec=None, arch_spec=None):
|
|||||||
# If an arch spec is given, confirm that this compiler
|
# If an arch spec is given, confirm that this compiler
|
||||||
# is for the given operating system
|
# is for the given operating system
|
||||||
os = items.get('operating_system', None)
|
os = items.get('operating_system', None)
|
||||||
if arch_spec and os != arch_spec.platform_os:
|
if arch_spec and os != arch_spec.os:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If an arch spec is given, confirm that this compiler
|
# If an arch spec is given, confirm that this compiler
|
||||||
@ -333,7 +333,7 @@ def compiler_for_spec(compiler_spec, arch_spec):
|
|||||||
|
|
||||||
compilers = compilers_for_spec(compiler_spec, arch_spec=arch_spec)
|
compilers = compilers_for_spec(compiler_spec, arch_spec=arch_spec)
|
||||||
if len(compilers) < 1:
|
if len(compilers) < 1:
|
||||||
raise NoCompilerForSpecError(compiler_spec, arch_spec.platform_os)
|
raise NoCompilerForSpecError(compiler_spec, arch_spec.os)
|
||||||
if len(compilers) > 1:
|
if len(compilers) > 1:
|
||||||
raise CompilerDuplicateError(compiler_spec, arch_spec)
|
raise CompilerDuplicateError(compiler_spec, arch_spec)
|
||||||
return compilers[0]
|
return compilers[0]
|
||||||
|
@ -285,7 +285,7 @@ def concretize_compiler(self, spec):
|
|||||||
"""
|
"""
|
||||||
# Pass on concretizing the compiler if the target or operating system
|
# Pass on concretizing the compiler if the target or operating system
|
||||||
# is not yet determined
|
# is not yet determined
|
||||||
if not (spec.architecture.platform_os and spec.architecture.target):
|
if not (spec.architecture.os and spec.architecture.target):
|
||||||
# We haven't changed, but other changes need to happen before we
|
# We haven't changed, but other changes need to happen before we
|
||||||
# continue. `return True` here to force concretization to keep
|
# continue. `return True` here to force concretization to keep
|
||||||
# running.
|
# running.
|
||||||
@ -371,7 +371,7 @@ def concretize_compiler_flags(self, spec):
|
|||||||
"""
|
"""
|
||||||
# Pass on concretizing the compiler flags if the target or operating
|
# Pass on concretizing the compiler flags if the target or operating
|
||||||
# system is not set.
|
# system is not set.
|
||||||
if not (spec.architecture.platform_os and spec.architecture.target):
|
if not (spec.architecture.os and spec.architecture.target):
|
||||||
# We haven't changed, but other changes need to happen before we
|
# We haven't changed, but other changes need to happen before we
|
||||||
# continue. `return True` here to force concretization to keep
|
# continue. `return True` here to force concretization to keep
|
||||||
# running.
|
# running.
|
||||||
@ -471,7 +471,7 @@ def __init__(self, arch, available_os_targets):
|
|||||||
" for operating system %s and target %s."
|
" for operating system %s and target %s."
|
||||||
"\nIf previous installations have succeeded, the"
|
"\nIf previous installations have succeeded, the"
|
||||||
" operating system may have been updated." %
|
" operating system may have been updated." %
|
||||||
(arch.platform_os, arch.target))
|
(arch.os, arch.target))
|
||||||
|
|
||||||
available_os_target_strs = list()
|
available_os_target_strs = list()
|
||||||
for os, t in available_os_targets:
|
for os, t in available_os_targets:
|
||||||
@ -494,7 +494,7 @@ def __init__(self, compiler_spec, arch=None):
|
|||||||
err_msg = "No compilers with spec {0} found".format(compiler_spec)
|
err_msg = "No compilers with spec {0} found".format(compiler_spec)
|
||||||
if arch:
|
if arch:
|
||||||
err_msg += " for operating system {0} and target {1}.".format(
|
err_msg += " for operating system {0} and target {1}.".format(
|
||||||
arch.platform_os, arch.target
|
arch.os, arch.target
|
||||||
)
|
)
|
||||||
|
|
||||||
super(UnavailableCompilerVersionError, self).__init__(
|
super(UnavailableCompilerVersionError, self).__init__(
|
||||||
|
@ -384,7 +384,8 @@ def _assign_dependencies(self, hash_key, installs, data):
|
|||||||
if not child:
|
if not child:
|
||||||
msg = ("Missing dependency not in database: "
|
msg = ("Missing dependency not in database: "
|
||||||
"%s needs %s-%s" % (
|
"%s needs %s-%s" % (
|
||||||
spec.cformat('$_$/'), dname, dhash[:7]))
|
spec.cformat('{name}{/hash:7}'),
|
||||||
|
dname, dhash[:7]))
|
||||||
if self._fail_when_missing_deps:
|
if self._fail_when_missing_deps:
|
||||||
raise MissingDependenciesError(msg)
|
raise MissingDependenciesError(msg)
|
||||||
tty.warn(msg)
|
tty.warn(msg)
|
||||||
|
@ -175,15 +175,15 @@ def __init__(self, root, **kwargs):
|
|||||||
super(YamlDirectoryLayout, self).__init__(root)
|
super(YamlDirectoryLayout, self).__init__(root)
|
||||||
self.hash_len = kwargs.get('hash_len')
|
self.hash_len = kwargs.get('hash_len')
|
||||||
self.path_scheme = kwargs.get('path_scheme') or (
|
self.path_scheme = kwargs.get('path_scheme') or (
|
||||||
"${ARCHITECTURE}/"
|
"{architecture}/"
|
||||||
"${COMPILERNAME}-${COMPILERVER}/"
|
"{compiler.name}-{compiler.version}/"
|
||||||
"${PACKAGE}-${VERSION}-${HASH}")
|
"{name}-{version}-{hash}")
|
||||||
if self.hash_len is not None:
|
if self.hash_len is not None:
|
||||||
if re.search(r'\${HASH:\d+}', self.path_scheme):
|
if re.search(r'{hash:\d+}', self.path_scheme):
|
||||||
raise InvalidDirectoryLayoutParametersError(
|
raise InvalidDirectoryLayoutParametersError(
|
||||||
"Conflicting options for installation layout hash length")
|
"Conflicting options for installation layout hash length")
|
||||||
self.path_scheme = self.path_scheme.replace(
|
self.path_scheme = self.path_scheme.replace(
|
||||||
"${HASH}", "${HASH:%d}" % self.hash_len)
|
"{hash}", "{hash:%d}" % self.hash_len)
|
||||||
|
|
||||||
# If any of these paths change, downstream databases may not be able to
|
# If any of these paths change, downstream databases may not be able to
|
||||||
# locate files in older upstream databases
|
# locate files in older upstream databases
|
||||||
|
@ -557,7 +557,8 @@ def print_status(self, *specs, **kwargs):
|
|||||||
specs = index[(architecture, compiler)]
|
specs = index[(architecture, compiler)]
|
||||||
specs.sort()
|
specs.sort()
|
||||||
|
|
||||||
format_string = '$_$@$%@+$+'
|
format_string = '{name}{@version}'
|
||||||
|
format_string += '{%compiler}{compiler_flags}{variants}'
|
||||||
abbreviated = [s.cformat(format_string) for s in specs]
|
abbreviated = [s.cformat(format_string) for s in specs]
|
||||||
|
|
||||||
# Print one spec per line along with prefix path
|
# Print one spec per line along with prefix path
|
||||||
|
@ -210,7 +210,9 @@ def create(path, specs, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def add_single_spec(spec, mirror_root, categories, **kwargs):
|
def add_single_spec(spec, mirror_root, categories, **kwargs):
|
||||||
tty.msg("Adding package {pkg} to mirror".format(pkg=spec.format("$_$@")))
|
tty.msg("Adding package {pkg} to mirror".format(
|
||||||
|
pkg=spec.format("{name}{@version}")
|
||||||
|
))
|
||||||
try:
|
try:
|
||||||
spec.package.do_fetch()
|
spec.package.do_fetch()
|
||||||
spec.package.do_clean()
|
spec.package.do_clean()
|
||||||
@ -220,7 +222,8 @@ def add_single_spec(spec, mirror_root, categories, **kwargs):
|
|||||||
sys.excepthook(*sys.exc_info())
|
sys.excepthook(*sys.exc_info())
|
||||||
else:
|
else:
|
||||||
tty.warn(
|
tty.warn(
|
||||||
"Error while fetching %s" % spec.cformat('$_$@'), e.message)
|
"Error while fetching %s" % spec.cformat('{name}{@version}'),
|
||||||
|
e.message)
|
||||||
categories['error'].append(spec)
|
categories['error'].append(spec)
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,12 +59,12 @@
|
|||||||
|
|
||||||
#: Valid tokens for naming scheme and env variable names
|
#: Valid tokens for naming scheme and env variable names
|
||||||
_valid_tokens = (
|
_valid_tokens = (
|
||||||
'PACKAGE',
|
'name',
|
||||||
'VERSION',
|
'version',
|
||||||
'COMPILER',
|
'compiler',
|
||||||
'COMPILERNAME',
|
'compiler.name',
|
||||||
'COMPILERVER',
|
'compiler.version',
|
||||||
'ARCHITECTURE'
|
'architecture'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -80,8 +80,9 @@ def _check_tokens_are_valid(format_string, message):
|
|||||||
tokens are found
|
tokens are found
|
||||||
|
|
||||||
"""
|
"""
|
||||||
named_tokens = re.findall(r'\${(\w*)}', format_string)
|
named_tokens = re.findall(r'{(\w*)}', format_string)
|
||||||
invalid_tokens = [x for x in named_tokens if x not in _valid_tokens]
|
invalid_tokens = [x for x in named_tokens
|
||||||
|
if x.lower() not in _valid_tokens]
|
||||||
if invalid_tokens:
|
if invalid_tokens:
|
||||||
msg = message
|
msg = message
|
||||||
msg += ' [{0}]. '.format(', '.join(invalid_tokens))
|
msg += ' [{0}]. '.format(', '.join(invalid_tokens))
|
||||||
@ -294,7 +295,7 @@ def naming_scheme(self):
|
|||||||
"""Naming scheme suitable for non-hierarchical layouts"""
|
"""Naming scheme suitable for non-hierarchical layouts"""
|
||||||
scheme = self.module.configuration.get(
|
scheme = self.module.configuration.get(
|
||||||
'naming_scheme',
|
'naming_scheme',
|
||||||
'${PACKAGE}-${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
'{name}-{version}-{compiler.name}-{compiler.version}'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ensure the named tokens we are expanding are allowed, see
|
# Ensure the named tokens we are expanding are allowed, see
|
||||||
@ -523,7 +524,7 @@ def short_description(self):
|
|||||||
value = re.sub(r'"', "'", value)
|
value = re.sub(r'"', "'", value)
|
||||||
return value
|
return value
|
||||||
# Otherwise the short description is just the package + version
|
# Otherwise the short description is just the package + version
|
||||||
return self.spec.format("$_ $@")
|
return self.spec.format("{name} {@version}")
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
def long_description(self):
|
def long_description(self):
|
||||||
|
@ -232,7 +232,7 @@ def use_name(self):
|
|||||||
to console to use it.
|
to console to use it.
|
||||||
"""
|
"""
|
||||||
# Package name and version
|
# Package name and version
|
||||||
base = os.path.join("${PACKAGE}", "${VERSION}")
|
base = os.path.join("{name}", "{version}")
|
||||||
name_parts = [self.spec.format(base)]
|
name_parts = [self.spec.format(base)]
|
||||||
# The remaining elements are filename suffixes
|
# The remaining elements are filename suffixes
|
||||||
name_parts.extend(self.conf.suffixes)
|
name_parts.extend(self.conf.suffixes)
|
||||||
|
@ -946,7 +946,7 @@ def do_fetch(self, mirror_only=False):
|
|||||||
checksum = spack.config.get('config:checksum')
|
checksum = spack.config.get('config:checksum')
|
||||||
if checksum and self.version not in self.versions:
|
if checksum and self.version not in self.versions:
|
||||||
tty.warn("There is no checksum on file to fetch %s safely." %
|
tty.warn("There is no checksum on file to fetch %s safely." %
|
||||||
self.spec.cformat('$_$@'))
|
self.spec.cformat('{name}{@version}'))
|
||||||
|
|
||||||
# Ask the user whether to skip the checksum if we're
|
# Ask the user whether to skip the checksum if we're
|
||||||
# interactive, but just fail if non-interactive.
|
# interactive, but just fail if non-interactive.
|
||||||
@ -960,7 +960,7 @@ def do_fetch(self, mirror_only=False):
|
|||||||
|
|
||||||
if not ignore_checksum:
|
if not ignore_checksum:
|
||||||
raise FetchError("Will not fetch %s" %
|
raise FetchError("Will not fetch %s" %
|
||||||
self.spec.format('$_$@'), ck_msg)
|
self.spec.format('{name}{@version}'), ck_msg)
|
||||||
|
|
||||||
self.stage.create()
|
self.stage.create()
|
||||||
self.stage.fetch(mirror_only)
|
self.stage.fetch(mirror_only)
|
||||||
|
@ -96,6 +96,7 @@
|
|||||||
from llnl.util.tty.color import cwrite, colorize, cescape, get_color_when
|
from llnl.util.tty.color import cwrite, colorize, cescape, get_color_when
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
|
import spack.paths
|
||||||
import spack.architecture
|
import spack.architecture
|
||||||
import spack.compiler
|
import spack.compiler
|
||||||
import spack.compilers as compilers
|
import spack.compilers as compilers
|
||||||
@ -187,6 +188,10 @@
|
|||||||
#: Max integer helps avoid passing too large a value to cyaml.
|
#: Max integer helps avoid passing too large a value to cyaml.
|
||||||
maxint = 2 ** (ctypes.sizeof(ctypes.c_int) * 8 - 1) - 1
|
maxint = 2 ** (ctypes.sizeof(ctypes.c_int) * 8 - 1) - 1
|
||||||
|
|
||||||
|
default_format = '{name}{@version}'
|
||||||
|
default_format += '{%compiler.name}{@compiler.version}{compiler_flags}'
|
||||||
|
default_format += '{variants}{arch=architecture}'
|
||||||
|
|
||||||
|
|
||||||
def colorize_spec(spec):
|
def colorize_spec(spec):
|
||||||
"""Returns a spec colorized according to the colors specified in
|
"""Returns a spec colorized according to the colors specified in
|
||||||
@ -221,7 +226,7 @@ class ArchSpec(object):
|
|||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
to_attr_string = lambda s: str(s) if s and s != "None" else None
|
to_attr_string = lambda s: str(s) if s and s != "None" else None
|
||||||
|
|
||||||
self.platform, self.platform_os, self.target = (None, None, None)
|
self.platform, self.os, self.target = (None, None, None)
|
||||||
|
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
spec_like = args[0]
|
spec_like = args[0]
|
||||||
@ -231,13 +236,13 @@ def __init__(self, *args):
|
|||||||
spec_fields = spec_like.split("-")
|
spec_fields = spec_like.split("-")
|
||||||
|
|
||||||
if len(spec_fields) == 3:
|
if len(spec_fields) == 3:
|
||||||
self.platform, self.platform_os, self.target = tuple(
|
self.platform, self.os, self.target = tuple(
|
||||||
to_attr_string(f) for f in spec_fields)
|
to_attr_string(f) for f in spec_fields)
|
||||||
else:
|
else:
|
||||||
raise ValueError("%s is an invalid arch spec" % spec_like)
|
raise ValueError("%s is an invalid arch spec" % spec_like)
|
||||||
elif len(args) == 3:
|
elif len(args) == 3:
|
||||||
self.platform = to_attr_string(args[0])
|
self.platform = to_attr_string(args[0])
|
||||||
self.platform_os = to_attr_string(args[1])
|
self.os = to_attr_string(args[1])
|
||||||
self.target = to_attr_string(args[2])
|
self.target = to_attr_string(args[2])
|
||||||
elif len(args) != 0:
|
elif len(args) != 0:
|
||||||
raise TypeError("Can't make arch spec from %s" % args)
|
raise TypeError("Can't make arch spec from %s" % args)
|
||||||
@ -248,11 +253,11 @@ def _autospec(self, spec_like):
|
|||||||
return ArchSpec(spec_like)
|
return ArchSpec(spec_like)
|
||||||
|
|
||||||
def _cmp_key(self):
|
def _cmp_key(self):
|
||||||
return (self.platform, self.platform_os, self.target)
|
return (self.platform, self.os, self.target)
|
||||||
|
|
||||||
def _dup(self, other):
|
def _dup(self, other):
|
||||||
self.platform = other.platform
|
self.platform = other.platform
|
||||||
self.platform_os = other.platform_os
|
self.os = other.os
|
||||||
self.target = other.target
|
self.target = other.target
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -269,11 +274,11 @@ def platform(self, value):
|
|||||||
self._platform = value
|
self._platform = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def platform_os(self):
|
def os(self):
|
||||||
return self._platform_os
|
return self._os
|
||||||
|
|
||||||
@platform_os.setter
|
@os.setter
|
||||||
def platform_os(self, value):
|
def os(self, value):
|
||||||
""" The OS of the architecture spec will update the platform field
|
""" The OS of the architecture spec will update the platform field
|
||||||
if the OS is set to one of the reserved OS types so that the
|
if the OS is set to one of the reserved OS types so that the
|
||||||
default OS type can be resolved. Since the reserved OS
|
default OS type can be resolved. Since the reserved OS
|
||||||
@ -295,7 +300,7 @@ def platform_os(self, value):
|
|||||||
spec_platform = spack.architecture.get_platform(self.platform)
|
spec_platform = spack.architecture.get_platform(self.platform)
|
||||||
value = str(spec_platform.operating_system(value))
|
value = str(spec_platform.operating_system(value))
|
||||||
|
|
||||||
self._platform_os = value
|
self._os = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target(self):
|
def target(self):
|
||||||
@ -369,13 +374,13 @@ def to_cmp_dict(self):
|
|||||||
"""Returns a dictionary that can be used for field comparison."""
|
"""Returns a dictionary that can be used for field comparison."""
|
||||||
return dict([
|
return dict([
|
||||||
('platform', self.platform),
|
('platform', self.platform),
|
||||||
('platform_os', self.platform_os),
|
('os', self.os),
|
||||||
('target', self.target)])
|
('target', self.target)])
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
d = syaml_dict([
|
d = syaml_dict([
|
||||||
('platform', self.platform),
|
('platform', self.platform),
|
||||||
('platform_os', self.platform_os),
|
('platform_os', self.os),
|
||||||
('target', self.target)])
|
('target', self.target)])
|
||||||
return syaml_dict([('arch', d)])
|
return syaml_dict([('arch', d)])
|
||||||
|
|
||||||
@ -397,10 +402,13 @@ def from_dict(d):
|
|||||||
return ArchSpec('spack09', 'unknown', d['arch'])
|
return ArchSpec('spack09', 'unknown', d['arch'])
|
||||||
|
|
||||||
d = d['arch']
|
d = d['arch']
|
||||||
|
if 'platform_os' in d:
|
||||||
return ArchSpec(d['platform'], d['platform_os'], d['target'])
|
return ArchSpec(d['platform'], d['platform_os'], d['target'])
|
||||||
|
else:
|
||||||
|
return ArchSpec(d['platform'], d['os'], d['target'])
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s-%s-%s" % (self.platform, self.platform_os, self.target)
|
return "%s-%s-%s" % (self.platform, self.os, self.target)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return str(self)
|
return str(self)
|
||||||
@ -835,10 +843,10 @@ def __get__(self, instance, cls):
|
|||||||
# properties defined and no default handler, or that all callbacks
|
# properties defined and no default handler, or that all callbacks
|
||||||
# raised AttributeError. In this case, we raise AttributeError with an
|
# raised AttributeError. In this case, we raise AttributeError with an
|
||||||
# appropriate message.
|
# appropriate message.
|
||||||
fmt = '\'{name}\' package has no relevant attribute \'{query}\'\n' # NOQA: ignore=E501
|
fmt = '\'{name}\' package has no relevant attribute \'{query}\'\n'
|
||||||
fmt += '\tspec : \'{spec}\'\n'
|
fmt += '\tspec : \'{spec}\'\n'
|
||||||
fmt += '\tqueried as : \'{spec.last_query.name}\'\n'
|
fmt += '\tqueried as : \'{spec.last_query.name}\'\n'
|
||||||
fmt += '\textra parameters : \'{spec.last_query.extra_parameters}\'\n' # NOQA: ignore=E501
|
fmt += '\textra parameters : \'{spec.last_query.extra_parameters}\'\n'
|
||||||
message = fmt.format(
|
message = fmt.format(
|
||||||
name=pkg.name,
|
name=pkg.name,
|
||||||
query=self.attribute_name,
|
query=self.attribute_name,
|
||||||
@ -1004,11 +1012,11 @@ def _add_flag(self, name, value):
|
|||||||
if name == 'arch' or name == 'architecture':
|
if name == 'arch' or name == 'architecture':
|
||||||
parts = tuple(value.split('-'))
|
parts = tuple(value.split('-'))
|
||||||
plat, os, tgt = parts if len(parts) == 3 else (None, None, value)
|
plat, os, tgt = parts if len(parts) == 3 else (None, None, value)
|
||||||
self._set_architecture(platform=plat, platform_os=os, target=tgt)
|
self._set_architecture(platform=plat, os=os, target=tgt)
|
||||||
elif name == 'platform':
|
elif name == 'platform':
|
||||||
self._set_architecture(platform=value)
|
self._set_architecture(platform=value)
|
||||||
elif name == 'os' or name == 'operating_system':
|
elif name == 'os' or name == 'operating_system':
|
||||||
self._set_architecture(platform_os=value)
|
self._set_architecture(os=value)
|
||||||
elif name == 'target':
|
elif name == 'target':
|
||||||
self._set_architecture(target=value)
|
self._set_architecture(target=value)
|
||||||
elif name in valid_flags:
|
elif name in valid_flags:
|
||||||
@ -1026,7 +1034,7 @@ def _add_flag(self, name, value):
|
|||||||
|
|
||||||
def _set_architecture(self, **kwargs):
|
def _set_architecture(self, **kwargs):
|
||||||
"""Called by the parser to set the architecture."""
|
"""Called by the parser to set the architecture."""
|
||||||
arch_attrs = ['platform', 'platform_os', 'target']
|
arch_attrs = ['platform', 'os', 'target']
|
||||||
if self.architecture and self.architecture.concrete:
|
if self.architecture and self.architecture.concrete:
|
||||||
raise DuplicateArchitectureError(
|
raise DuplicateArchitectureError(
|
||||||
"Spec for '%s' cannot have two architectures." % self.name)
|
"Spec for '%s' cannot have two architectures." % self.name)
|
||||||
@ -1258,12 +1266,16 @@ def return_val(dspec):
|
|||||||
def short_spec(self):
|
def short_spec(self):
|
||||||
"""Returns a version of the spec with the dependencies hashed
|
"""Returns a version of the spec with the dependencies hashed
|
||||||
instead of completely enumerated."""
|
instead of completely enumerated."""
|
||||||
return self.format('$_$@$%@$+$=$/')
|
spec_format = '{name}{@version}{%compiler}'
|
||||||
|
spec_format += '{variants}{arch=architecture}{/hash:7}'
|
||||||
|
return self.format(spec_format)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cshort_spec(self):
|
def cshort_spec(self):
|
||||||
"""Returns an auto-colorized version of ``self.short_spec``."""
|
"""Returns an auto-colorized version of ``self.short_spec``."""
|
||||||
return self.cformat('$_$@$%@$+$=$/')
|
spec_format = '{name}{@version}{%compiler}'
|
||||||
|
spec_format += '{variants}{arch=architecture}{/hash:7}'
|
||||||
|
return self.cformat(spec_format)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prefix(self):
|
def prefix(self):
|
||||||
@ -2434,8 +2446,8 @@ def constrain(self, other, deps=True):
|
|||||||
if sarch.platform is not None and oarch.platform is not None:
|
if sarch.platform is not None and oarch.platform is not None:
|
||||||
if sarch.platform != oarch.platform:
|
if sarch.platform != oarch.platform:
|
||||||
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
||||||
if sarch.platform_os is not None and oarch.platform_os is not None:
|
if sarch.os is not None and oarch.os is not None:
|
||||||
if sarch.platform_os != oarch.platform_os:
|
if sarch.os != oarch.os:
|
||||||
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
||||||
if sarch.target is not None and oarch.target is not None:
|
if sarch.target is not None and oarch.target is not None:
|
||||||
if sarch.target != oarch.target:
|
if sarch.target != oarch.target:
|
||||||
@ -2460,8 +2472,8 @@ def constrain(self, other, deps=True):
|
|||||||
else:
|
else:
|
||||||
if sarch.platform is None or oarch.platform is None:
|
if sarch.platform is None or oarch.platform is None:
|
||||||
self.architecture.platform = sarch.platform or oarch.platform
|
self.architecture.platform = sarch.platform or oarch.platform
|
||||||
if sarch.platform_os is None or oarch.platform_os is None:
|
if sarch.os is None or oarch.os is None:
|
||||||
sarch.platform_os = sarch.platform_os or oarch.platform_os
|
sarch.os = sarch.os or oarch.os
|
||||||
if sarch.target is None or oarch.target is None:
|
if sarch.target is None or oarch.target is None:
|
||||||
sarch.target = sarch.target or oarch.target
|
sarch.target = sarch.target or oarch.target
|
||||||
changed |= (str(self.architecture) != old)
|
changed |= (str(self.architecture) != old)
|
||||||
@ -3010,10 +3022,245 @@ def _cmp_key(self):
|
|||||||
def colorized(self):
|
def colorized(self):
|
||||||
return colorize_spec(self)
|
return colorize_spec(self)
|
||||||
|
|
||||||
def format(self, format_string='$_$@$%@+$+$=', **kwargs):
|
def format(self, format_string=default_format, **kwargs):
|
||||||
"""Prints out particular pieces of a spec, depending on what is
|
r"""Prints out particular pieces of a spec, depending on what is
|
||||||
in the format string.
|
in the format string.
|
||||||
|
|
||||||
|
Using the ``{attribute}`` syntax, any field of the spec can be
|
||||||
|
selected. Those attributes can be recursive. For example,
|
||||||
|
``s.format({compiler.version})`` will print the version of the
|
||||||
|
compiler.
|
||||||
|
|
||||||
|
Commonly used attributes of the Spec for format strings include::
|
||||||
|
|
||||||
|
name
|
||||||
|
version
|
||||||
|
compiler
|
||||||
|
compiler.name
|
||||||
|
compiler.version
|
||||||
|
compiler_flags
|
||||||
|
variants
|
||||||
|
architecture
|
||||||
|
architecture.platform
|
||||||
|
architecture.os
|
||||||
|
architecture.target
|
||||||
|
prefix
|
||||||
|
|
||||||
|
Some additional special-case properties can be added::
|
||||||
|
|
||||||
|
hash[:len] The DAG hash with optional length argument
|
||||||
|
spack_root The spack root directory
|
||||||
|
spack_install The spack install directory
|
||||||
|
|
||||||
|
The ``^`` sigil can be used to access dependencies by name.
|
||||||
|
``s.format({^mpi.name})`` will print the name of the MPI
|
||||||
|
implementation in the spec.
|
||||||
|
|
||||||
|
The ``@``, ``%``, ``arch=``, and ``/`` sigils
|
||||||
|
can be used to include the sigil with the printed
|
||||||
|
string. These sigils may only be used with the appropriate
|
||||||
|
attributes, listed below::
|
||||||
|
|
||||||
|
@ ``{@version}``, ``{@compiler.version}``
|
||||||
|
% ``{%compiler}``, ``{%compiler.name}``
|
||||||
|
arch= ``{arch=architecture}``
|
||||||
|
/ ``{/hash}``, ``{/hash:7}``, etc
|
||||||
|
|
||||||
|
The ``@`` sigil may also be used for any other property named
|
||||||
|
``version``. Sigils printed with the attribute string are only
|
||||||
|
printed if the attribute string is non-empty, and are colored
|
||||||
|
according to the color of the attribute.
|
||||||
|
|
||||||
|
Sigils are not used for printing variants. Variants listed by
|
||||||
|
name naturally print with their sigil. For example,
|
||||||
|
``spec.format('{variants.debug}')`` would print either
|
||||||
|
``+debug`` or ``~debug`` depending on the name of the
|
||||||
|
variant. Non-boolean variants print as ``name=value``. To
|
||||||
|
print variant names or values independently, use
|
||||||
|
``spec.format('{variants.<name>.name}')`` or
|
||||||
|
``spec.format('{variants.<name>.value}')``.
|
||||||
|
|
||||||
|
Spec format strings use ``\`` as the escape character. Use
|
||||||
|
``\{`` and ``\}`` for literal braces, and ``\\`` for the
|
||||||
|
literal ``\`` character. Also use ``\$`` for the literal ``$``
|
||||||
|
to differentiate from previous, deprecated format string
|
||||||
|
syntax.
|
||||||
|
|
||||||
|
The previous format strings are deprecated. They can still be
|
||||||
|
accessed by the ``old_format`` method. The ``format`` method
|
||||||
|
will call ``old_format`` if the character ``$`` appears
|
||||||
|
unescaped in the format string.
|
||||||
|
|
||||||
|
|
||||||
|
Args:
|
||||||
|
format_string (str): string containing the format to be expanded
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
color (bool): True if returned string is colored
|
||||||
|
transform (dict): maps full-string formats to a callable \
|
||||||
|
that accepts a string and returns another one
|
||||||
|
|
||||||
|
"""
|
||||||
|
# If we have an unescaped $ sigil, use the deprecated format strings
|
||||||
|
if re.search(r'[^\\]*\$', format_string):
|
||||||
|
return self.old_format(format_string, **kwargs)
|
||||||
|
|
||||||
|
color = kwargs.get('color', False)
|
||||||
|
transform = kwargs.get('transform', {})
|
||||||
|
|
||||||
|
out = StringIO()
|
||||||
|
|
||||||
|
def write(s, c=None):
|
||||||
|
f = cescape(s)
|
||||||
|
if c is not None:
|
||||||
|
f = color_formats[c] + f + '@.'
|
||||||
|
cwrite(f, stream=out, color=color)
|
||||||
|
|
||||||
|
def write_attribute(spec, attribute, color):
|
||||||
|
if attribute.startswith('^'):
|
||||||
|
attribute = attribute[1:]
|
||||||
|
dep, attribute = attribute.split('.', 1)
|
||||||
|
current = self[dep]
|
||||||
|
|
||||||
|
if attribute == '':
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Format string attributes must be non-empty')
|
||||||
|
attribute = attribute.lower()
|
||||||
|
|
||||||
|
current = spec
|
||||||
|
sig = ''
|
||||||
|
if attribute[0] in '@%/':
|
||||||
|
# color sigils that are inside braces
|
||||||
|
sig = attribute[0]
|
||||||
|
attribute = attribute[1:]
|
||||||
|
elif attribute.startswith('arch='):
|
||||||
|
sig = ' arch=' # include space as separator
|
||||||
|
attribute = attribute[5:]
|
||||||
|
|
||||||
|
parts = attribute.split('.')
|
||||||
|
assert parts
|
||||||
|
|
||||||
|
# check that the sigil is valid for the attribute.
|
||||||
|
if sig == '@' and parts[-1] not in ('versions', 'version'):
|
||||||
|
raise SpecFormatSigilError(sig, 'versions', attribute)
|
||||||
|
elif sig == '%' and attribute not in ('compiler', 'compiler.name'):
|
||||||
|
raise SpecFormatSigilError(sig, 'compilers', attribute)
|
||||||
|
elif sig == '/' and not re.match(r'hash(:\d+)?$', attribute):
|
||||||
|
raise SpecFormatSigilError(sig, 'DAG hashes', attribute)
|
||||||
|
elif sig == ' arch=' and attribute not in ('architecture', 'arch'):
|
||||||
|
raise SpecFormatSigilError(sig, 'the architecture', attribute)
|
||||||
|
|
||||||
|
# find the morph function for our attribute
|
||||||
|
morph = transform.get(attribute, lambda s, x: x)
|
||||||
|
|
||||||
|
# Special cases for non-spec attributes and hashes.
|
||||||
|
# These must be the only non-dep component of the format attribute
|
||||||
|
if attribute == 'spack_root':
|
||||||
|
write(morph(spec, spack.paths.spack_root))
|
||||||
|
return
|
||||||
|
elif attribute == 'spack_install':
|
||||||
|
write(morph(spec, spack.store.layout.root))
|
||||||
|
return
|
||||||
|
elif re.match(r'hash(:\d)?', attribute):
|
||||||
|
col = '#'
|
||||||
|
if ':' in attribute:
|
||||||
|
_, length = attribute.split(':')
|
||||||
|
write(sig + morph(spec, spec.dag_hash(int(length))), col)
|
||||||
|
else:
|
||||||
|
write(sig + morph(spec, spec.dag_hash()), col)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Iterate over components using getattr to get next element
|
||||||
|
for idx, part in enumerate(parts):
|
||||||
|
if not part:
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Format string attributes must be non-empty'
|
||||||
|
)
|
||||||
|
if part.startswith('_'):
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Attempted to format private attribute'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if isinstance(current, VariantMap):
|
||||||
|
# subscript instead of getattr for variant names
|
||||||
|
current = current[part]
|
||||||
|
else:
|
||||||
|
# aliases
|
||||||
|
if part == 'arch':
|
||||||
|
part = 'architecture'
|
||||||
|
elif part == 'version':
|
||||||
|
# Version requires concrete spec, versions does not
|
||||||
|
# when concrete, they print the same thing
|
||||||
|
part = 'versions'
|
||||||
|
try:
|
||||||
|
current = getattr(current, part)
|
||||||
|
except AttributeError:
|
||||||
|
parent = '.'.join(parts[:idx])
|
||||||
|
m = 'Attempted to format attribute %s.' % attribute
|
||||||
|
m += 'Spec.%s has no attribute %s' % (parent, part)
|
||||||
|
raise SpecFormatStringError(m)
|
||||||
|
if isinstance(current, VersionList):
|
||||||
|
if current == _any_version:
|
||||||
|
# We don't print empty version lists
|
||||||
|
return
|
||||||
|
|
||||||
|
if callable(current):
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Attempted to format callable object'
|
||||||
|
)
|
||||||
|
if not current:
|
||||||
|
# We're not printing anything
|
||||||
|
return
|
||||||
|
|
||||||
|
# Set color codes for various attributes
|
||||||
|
col = None
|
||||||
|
if 'variants' in parts:
|
||||||
|
col = '+'
|
||||||
|
elif 'architecture' in parts:
|
||||||
|
col = '='
|
||||||
|
elif 'compiler' in parts or 'compiler_flags' in parts:
|
||||||
|
col = '%'
|
||||||
|
elif 'version' in parts:
|
||||||
|
col = '@'
|
||||||
|
|
||||||
|
# Finally, write the ouptut
|
||||||
|
write(sig + morph(spec, str(current)), col)
|
||||||
|
|
||||||
|
attribute = ''
|
||||||
|
in_attribute = False
|
||||||
|
escape = False
|
||||||
|
|
||||||
|
for c in format_string:
|
||||||
|
if escape:
|
||||||
|
out.write(c)
|
||||||
|
escape = False
|
||||||
|
elif c == '\\':
|
||||||
|
escape = True
|
||||||
|
elif in_attribute:
|
||||||
|
if c == '}':
|
||||||
|
write_attribute(self, attribute, color)
|
||||||
|
attribute = ''
|
||||||
|
in_attribute = False
|
||||||
|
else:
|
||||||
|
attribute += c
|
||||||
|
else:
|
||||||
|
if c == '}':
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Encountered closing } before opening {'
|
||||||
|
)
|
||||||
|
elif c == '{':
|
||||||
|
in_attribute = True
|
||||||
|
else:
|
||||||
|
out.write(c)
|
||||||
|
if in_attribute:
|
||||||
|
raise SpecFormatStringError(
|
||||||
|
'Format string terminated while reading attribute.'
|
||||||
|
'Missing terminating }.'
|
||||||
|
)
|
||||||
|
return out.getvalue()
|
||||||
|
|
||||||
|
def old_format(self, format_string='$_$@$%@+$+$=', **kwargs):
|
||||||
|
"""
|
||||||
The format strings you can provide are::
|
The format strings you can provide are::
|
||||||
|
|
||||||
$_ Package name
|
$_ Package name
|
||||||
@ -3085,6 +3332,7 @@ def format(self, format_string='$_$@$%@+$+$=', **kwargs):
|
|||||||
TODO: allow, e.g., ``$6#`` to customize short hash length
|
TODO: allow, e.g., ``$6#`` to customize short hash length
|
||||||
TODO: allow, e.g., ``$//`` for full hash.
|
TODO: allow, e.g., ``$//`` for full hash.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
color = kwargs.get('color', False)
|
color = kwargs.get('color', False)
|
||||||
|
|
||||||
# Dictionary of transformations for named tokens
|
# Dictionary of transformations for named tokens
|
||||||
@ -3218,7 +3466,7 @@ def write(s, c=None):
|
|||||||
platform = str(self.architecture.platform)
|
platform = str(self.architecture.platform)
|
||||||
write(fmt % transform(self, platform), '=')
|
write(fmt % transform(self, platform), '=')
|
||||||
elif named_str == "OS":
|
elif named_str == "OS":
|
||||||
operating_sys = str(self.architecture.platform_os)
|
operating_sys = str(self.architecture.os)
|
||||||
write(fmt % transform(self, operating_sys), '=')
|
write(fmt % transform(self, operating_sys), '=')
|
||||||
elif named_str == "TARGET":
|
elif named_str == "TARGET":
|
||||||
target = str(self.architecture.target)
|
target = str(self.architecture.target)
|
||||||
@ -3302,7 +3550,7 @@ def tree(self, **kwargs):
|
|||||||
status_fn = kwargs.pop('status_fn', False)
|
status_fn = kwargs.pop('status_fn', False)
|
||||||
cover = kwargs.pop('cover', 'nodes')
|
cover = kwargs.pop('cover', 'nodes')
|
||||||
indent = kwargs.pop('indent', 0)
|
indent = kwargs.pop('indent', 0)
|
||||||
fmt = kwargs.pop('format', '$_$@$%@+$+$=')
|
fmt = kwargs.pop('format', default_format)
|
||||||
prefix = kwargs.pop('prefix', None)
|
prefix = kwargs.pop('prefix', None)
|
||||||
show_types = kwargs.pop('show_types', False)
|
show_types = kwargs.pop('show_types', False)
|
||||||
deptypes = kwargs.pop('deptypes', 'all')
|
deptypes = kwargs.pop('deptypes', 'all')
|
||||||
@ -3516,7 +3764,7 @@ def do_parse(self):
|
|||||||
for spec in specs:
|
for spec in specs:
|
||||||
for s in spec.traverse():
|
for s in spec.traverse():
|
||||||
if s.architecture and not s.architecture.platform and \
|
if s.architecture and not s.architecture.platform and \
|
||||||
(s.architecture.platform_os or s.architecture.target):
|
(s.architecture.os or s.architecture.target):
|
||||||
s._set_architecture(platform=platform_default)
|
s._set_architecture(platform=platform_default)
|
||||||
return specs
|
return specs
|
||||||
|
|
||||||
@ -3877,7 +4125,9 @@ def __init__(self, provided, required):
|
|||||||
|
|
||||||
class AmbiguousHashError(SpecError):
|
class AmbiguousHashError(SpecError):
|
||||||
def __init__(self, msg, *specs):
|
def __init__(self, msg, *specs):
|
||||||
specs_str = '\n ' + '\n '.join(spec.format('$.$@$%@+$+$=$/')
|
spec_fmt = '{namespace}.{name}{@version}{%compiler}{compiler_flags}'
|
||||||
|
spec_fmt += '{variants}{arch=architecture}{/hash:7}'
|
||||||
|
specs_str = '\n ' + '\n '.join(spec.format(spec_fmt)
|
||||||
for spec in specs)
|
for spec in specs)
|
||||||
super(AmbiguousHashError, self).__init__(msg + specs_str)
|
super(AmbiguousHashError, self).__init__(msg + specs_str)
|
||||||
|
|
||||||
@ -3904,6 +4154,18 @@ def __init__(self, spec, addition):
|
|||||||
% (addition, spec))
|
% (addition, spec))
|
||||||
|
|
||||||
|
|
||||||
|
class SpecFormatStringError(SpecError):
|
||||||
|
"""Called for errors in Spec format strings."""
|
||||||
|
|
||||||
|
|
||||||
|
class SpecFormatSigilError(SpecFormatStringError):
|
||||||
|
"""Called for mismatched sigils and attributes in format strings"""
|
||||||
|
def __init__(self, sigil, requirement, used):
|
||||||
|
msg = 'The sigil %s may only be used for %s.' % (sigil, requirement)
|
||||||
|
msg += ' It was used with the attribute %s.' % used
|
||||||
|
super(SpecFormatSigilError, self).__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
class ConflictsInSpecError(SpecError, RuntimeError):
|
class ConflictsInSpecError(SpecError, RuntimeError):
|
||||||
def __init__(self, spec, matches):
|
def __init__(self, spec, matches):
|
||||||
message = 'Conflicts in concretized spec "{0}"\n'.format(
|
message = 'Conflicts in concretized spec "{0}"\n'.format(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
|
# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
|
||||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
#
|
#
|
||||||
@ -21,7 +22,7 @@
|
|||||||
def test_dict_functions_for_architecture():
|
def test_dict_functions_for_architecture():
|
||||||
arch = spack.architecture.Arch()
|
arch = spack.architecture.Arch()
|
||||||
arch.platform = spack.architecture.platform()
|
arch.platform = spack.architecture.platform()
|
||||||
arch.platform_os = arch.platform.operating_system('default_os')
|
arch.os = arch.platform.operating_system('default_os')
|
||||||
arch.target = arch.platform.target('default_target')
|
arch.target = arch.platform.target('default_target')
|
||||||
|
|
||||||
new_arch = spack.architecture.Arch.from_dict(arch.to_dict())
|
new_arch = spack.architecture.Arch.from_dict(arch.to_dict())
|
||||||
@ -29,11 +30,11 @@ def test_dict_functions_for_architecture():
|
|||||||
assert arch == new_arch
|
assert arch == new_arch
|
||||||
assert isinstance(arch, spack.architecture.Arch)
|
assert isinstance(arch, spack.architecture.Arch)
|
||||||
assert isinstance(arch.platform, spack.architecture.Platform)
|
assert isinstance(arch.platform, spack.architecture.Platform)
|
||||||
assert isinstance(arch.platform_os, spack.architecture.OperatingSystem)
|
assert isinstance(arch.os, spack.architecture.OperatingSystem)
|
||||||
assert isinstance(arch.target, spack.architecture.Target)
|
assert isinstance(arch.target, spack.architecture.Target)
|
||||||
assert isinstance(new_arch, spack.architecture.Arch)
|
assert isinstance(new_arch, spack.architecture.Arch)
|
||||||
assert isinstance(new_arch.platform, spack.architecture.Platform)
|
assert isinstance(new_arch.platform, spack.architecture.Platform)
|
||||||
assert isinstance(new_arch.platform_os, spack.architecture.OperatingSystem)
|
assert isinstance(new_arch.os, spack.architecture.OperatingSystem)
|
||||||
assert isinstance(new_arch.target, spack.architecture.Target)
|
assert isinstance(new_arch.target, spack.architecture.Target)
|
||||||
|
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ def test_boolness():
|
|||||||
assert arch
|
assert arch
|
||||||
|
|
||||||
arch = spack.architecture.Arch()
|
arch = spack.architecture.Arch()
|
||||||
arch.platform_os = plat_os
|
arch.os = plat_os
|
||||||
assert arch
|
assert arch
|
||||||
|
|
||||||
arch = spack.architecture.Arch()
|
arch = spack.architecture.Arch()
|
||||||
@ -86,7 +87,7 @@ def test_user_front_end_input(config):
|
|||||||
frontend_spec = Spec('libelf os=frontend target=frontend')
|
frontend_spec = Spec('libelf os=frontend target=frontend')
|
||||||
frontend_spec.concretize()
|
frontend_spec.concretize()
|
||||||
|
|
||||||
assert frontend_os == frontend_spec.architecture.platform_os
|
assert frontend_os == frontend_spec.architecture.os
|
||||||
assert frontend_target == frontend_spec.architecture.target
|
assert frontend_target == frontend_spec.architecture.target
|
||||||
|
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ def test_user_back_end_input(config):
|
|||||||
backend_spec = Spec("libelf os=backend target=backend")
|
backend_spec = Spec("libelf os=backend target=backend")
|
||||||
backend_spec.concretize()
|
backend_spec.concretize()
|
||||||
|
|
||||||
assert backend_os == backend_spec.architecture.platform_os
|
assert backend_os == backend_spec.architecture.os
|
||||||
assert backend_target == backend_spec.architecture.target
|
assert backend_target == backend_spec.architecture.target
|
||||||
|
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ def test_user_defaults(config):
|
|||||||
default_spec = Spec("libelf") # default is no args
|
default_spec = Spec("libelf") # default is no args
|
||||||
default_spec.concretize()
|
default_spec.concretize()
|
||||||
|
|
||||||
assert default_os == default_spec.architecture.platform_os
|
assert default_os == default_spec.architecture.os
|
||||||
assert default_target == default_spec.architecture.target
|
assert default_target == default_spec.architecture.target
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ def test_user_input_combination(config):
|
|||||||
spec = Spec("libelf os=%s target=%s" % (o, t))
|
spec = Spec("libelf os=%s target=%s" % (o, t))
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
results.append(
|
results.append(
|
||||||
spec.architecture.platform_os == str(platform.operating_system(o))
|
spec.architecture.os == str(platform.operating_system(o))
|
||||||
)
|
)
|
||||||
results.append(
|
results.append(
|
||||||
spec.architecture.target == str(platform.target(t))
|
spec.architecture.target == str(platform.target(t))
|
||||||
|
@ -45,7 +45,7 @@ def test_view_projections(
|
|||||||
viewpath = str(tmpdir.mkdir('view_{0}'.format(cmd)))
|
viewpath = str(tmpdir.mkdir('view_{0}'.format(cmd)))
|
||||||
view_projection = {
|
view_projection = {
|
||||||
'projections': {
|
'projections': {
|
||||||
'all': '${PACKAGE}-${VERSION}'
|
'all': '{name}-{version}'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmpdir, view_projection)
|
||||||
@ -65,8 +65,8 @@ def test_view_multiple_projections(
|
|||||||
|
|
||||||
viewpath = str(tmpdir.mkdir('view'))
|
viewpath = str(tmpdir.mkdir('view'))
|
||||||
view_projection = s_yaml.syaml_dict(
|
view_projection = s_yaml.syaml_dict(
|
||||||
[('extendee', '${PACKAGE}-${COMPILERNAME}'),
|
[('extendee', '{name}-{compiler.name}'),
|
||||||
('all', '${PACKAGE}-${VERSION}')]
|
('all', '{name}-{version}')]
|
||||||
)
|
)
|
||||||
|
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmpdir, view_projection)
|
||||||
@ -87,8 +87,8 @@ def test_view_multiple_projections_all_first(
|
|||||||
|
|
||||||
viewpath = str(tmpdir.mkdir('view'))
|
viewpath = str(tmpdir.mkdir('view'))
|
||||||
view_projection = s_yaml.syaml_dict(
|
view_projection = s_yaml.syaml_dict(
|
||||||
[('all', '${PACKAGE}-${VERSION}'),
|
[('all', '{name}-{version}'),
|
||||||
('extendee', '${PACKAGE}-${COMPILERNAME}')]
|
('extendee', '{name}-{compiler.name}')]
|
||||||
)
|
)
|
||||||
|
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmpdir, view_projection)
|
||||||
@ -145,7 +145,7 @@ def test_view_extension_projection(
|
|||||||
install('extension2@1.0')
|
install('extension2@1.0')
|
||||||
|
|
||||||
viewpath = str(tmpdir.mkdir('view'))
|
viewpath = str(tmpdir.mkdir('view'))
|
||||||
view_projection = {'all': '${PACKAGE}-${VERSION}'}
|
view_projection = {'all': '{name}-{version}'}
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmpdir, view_projection)
|
||||||
view('symlink', viewpath, '--projection-file={0}'.format(projection_file),
|
view('symlink', viewpath, '--projection-file={0}'.format(projection_file),
|
||||||
'extension1@1.0')
|
'extension1@1.0')
|
||||||
|
@ -13,7 +13,7 @@ lmod:
|
|||||||
- CMAKE_PREFIX_PATH
|
- CMAKE_PREFIX_PATH
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
|
|
||||||
'platform=test target=x86_64':
|
'platform=test target=x86_64':
|
||||||
environment:
|
environment:
|
||||||
|
@ -7,7 +7,7 @@ tcl:
|
|||||||
- CMAKE_PREFIX_PATH
|
- CMAKE_PREFIX_PATH
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
'{name}_ROOT': '{prefix}'
|
||||||
|
|
||||||
'platform=test target=x86_64':
|
'platform=test target=x86_64':
|
||||||
environment:
|
environment:
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
enable:
|
enable:
|
||||||
- tcl
|
- tcl
|
||||||
tcl:
|
tcl:
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
naming_scheme: '{name}/{version}-{compiler.name}'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}'
|
- '{name}'
|
||||||
- 'intel/14.0.1'
|
- 'intel/14.0.1'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
enable:
|
enable:
|
||||||
- tcl
|
- tcl
|
||||||
tcl:
|
tcl:
|
||||||
# ${OPTIONS} is not allowed in the naming scheme, see #2884
|
# {variants} is not allowed in the naming scheme, see #2884
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${OPTIONS}'
|
naming_scheme: '{name}/{version}-{compiler.name}-{variants}'
|
||||||
|
@ -7,12 +7,12 @@ tcl:
|
|||||||
- CMAKE_PREFIX_PATH
|
- CMAKE_PREFIX_PATH
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
'${PACKAGE}_ROOT_${PREFIX}': '${PREFIX}'
|
'{name}_ROOT_{prefix}': '{prefix}'
|
||||||
|
|
||||||
'platform=test target=x86_64':
|
'platform=test target=x86_64':
|
||||||
environment:
|
environment:
|
||||||
set:
|
set:
|
||||||
FOO_${OPTIONS}: 'foo'
|
FOO_{variants}: 'foo'
|
||||||
unset:
|
unset:
|
||||||
- BAR
|
- BAR
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
enable:
|
enable:
|
||||||
- tcl
|
- tcl
|
||||||
tcl:
|
tcl:
|
||||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
naming_scheme: '{name}/{version}-{compiler.name}'
|
||||||
all:
|
all:
|
||||||
conflict:
|
conflict:
|
||||||
- '${PACKAGE}/${COMPILERNAME}'
|
- '{name}/{compiler.name}'
|
||||||
|
@ -41,9 +41,9 @@ def test_yaml_directory_layout_parameters(
|
|||||||
layout_default = YamlDirectoryLayout(str(tmpdir))
|
layout_default = YamlDirectoryLayout(str(tmpdir))
|
||||||
path_default = layout_default.relative_path_for_spec(spec)
|
path_default = layout_default.relative_path_for_spec(spec)
|
||||||
assert(path_default == spec.format(
|
assert(path_default == spec.format(
|
||||||
"${ARCHITECTURE}/"
|
"{architecture}/"
|
||||||
"${COMPILERNAME}-${COMPILERVER}/"
|
"{compiler.name}-{compiler.version}/"
|
||||||
"${PACKAGE}-${VERSION}-${HASH}"))
|
"{name}-{version}-{hash}"))
|
||||||
|
|
||||||
# Test hash_length parameter works correctly
|
# Test hash_length parameter works correctly
|
||||||
layout_10 = YamlDirectoryLayout(str(tmpdir), hash_len=10)
|
layout_10 = YamlDirectoryLayout(str(tmpdir), hash_len=10)
|
||||||
@ -56,7 +56,7 @@ def test_yaml_directory_layout_parameters(
|
|||||||
|
|
||||||
# Test path_scheme
|
# Test path_scheme
|
||||||
arch, compiler, package7 = path_7.split('/')
|
arch, compiler, package7 = path_7.split('/')
|
||||||
scheme_package7 = "${PACKAGE}-${VERSION}-${HASH:7}"
|
scheme_package7 = "{name}-{version}-{hash:7}"
|
||||||
layout_package7 = YamlDirectoryLayout(str(tmpdir),
|
layout_package7 = YamlDirectoryLayout(str(tmpdir),
|
||||||
path_scheme=scheme_package7)
|
path_scheme=scheme_package7)
|
||||||
path_package7 = layout_package7.relative_path_for_spec(spec)
|
path_package7 = layout_package7.relative_path_for_spec(spec)
|
||||||
@ -64,7 +64,7 @@ def test_yaml_directory_layout_parameters(
|
|||||||
assert(package7 == path_package7)
|
assert(package7 == path_package7)
|
||||||
|
|
||||||
# Test separation of architecture
|
# Test separation of architecture
|
||||||
arch_scheme_package = "${PLATFORM}/${TARGET}/${OS}/${PACKAGE}/${VERSION}/${HASH:7}" # NOQA: ignore=E501
|
arch_scheme_package = "{architecture.platform}/{architecture.target}/{architecture.os}/{name}/{version}/{hash:7}" # NOQA: ignore=E501
|
||||||
layout_arch_package = YamlDirectoryLayout(str(tmpdir),
|
layout_arch_package = YamlDirectoryLayout(str(tmpdir),
|
||||||
path_scheme=arch_scheme_package)
|
path_scheme=arch_scheme_package)
|
||||||
arch_path_package = layout_arch_package.relative_path_for_spec(spec)
|
arch_path_package = layout_arch_package.relative_path_for_spec(spec)
|
||||||
|
@ -65,16 +65,16 @@ def test_dynamic_dot_graph_mpileaks(mock_packages):
|
|||||||
|
|
||||||
dot = stream.getvalue()
|
dot = stream.getvalue()
|
||||||
|
|
||||||
mpileaks_hash, mpileaks_lbl = s.dag_hash(), s.format('$_$/')
|
mpileaks_hash, mpileaks_lbl = s.dag_hash(), s.format('{name}{/hash:7}')
|
||||||
mpi_hash, mpi_lbl = s['mpi'].dag_hash(), s['mpi'].format('$_$/')
|
mpi_hash, mpi_lbl = s['mpi'].dag_hash(), s['mpi'].format('{name}{/hash:7}')
|
||||||
callpath_hash, callpath_lbl = (
|
callpath_hash, callpath_lbl = (
|
||||||
s['callpath'].dag_hash(), s['callpath'].format('$_$/'))
|
s['callpath'].dag_hash(), s['callpath'].format('{name}{/hash:7}'))
|
||||||
dyninst_hash, dyninst_lbl = (
|
dyninst_hash, dyninst_lbl = (
|
||||||
s['dyninst'].dag_hash(), s['dyninst'].format('$_$/'))
|
s['dyninst'].dag_hash(), s['dyninst'].format('{name}{/hash:7}'))
|
||||||
libdwarf_hash, libdwarf_lbl = (
|
libdwarf_hash, libdwarf_lbl = (
|
||||||
s['libdwarf'].dag_hash(), s['libdwarf'].format('$_$/'))
|
s['libdwarf'].dag_hash(), s['libdwarf'].format('{name}{/hash:7}'))
|
||||||
libelf_hash, libelf_lbl = (
|
libelf_hash, libelf_lbl = (
|
||||||
s['libelf'].dag_hash(), s['libelf'].format('$_$/'))
|
s['libelf'].dag_hash(), s['libelf'].format('{name}{/hash:7}'))
|
||||||
|
|
||||||
assert ' "%s" [label="%s"]\n' % (mpileaks_hash, mpileaks_lbl) in dot
|
assert ' "%s" [label="%s"]\n' % (mpileaks_hash, mpileaks_lbl) in dot
|
||||||
assert ' "%s" [label="%s"]\n' % (callpath_hash, callpath_lbl) in dot
|
assert ' "%s" [label="%s"]\n' % (callpath_hash, callpath_lbl) in dot
|
||||||
|
@ -151,7 +151,7 @@ def test_naming_scheme(self, factory, module_configuration):
|
|||||||
|
|
||||||
# Test we read the expected configuration for the naming scheme
|
# Test we read the expected configuration for the naming scheme
|
||||||
writer, _ = factory('mpileaks')
|
writer, _ = factory('mpileaks')
|
||||||
expected = '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
expected = '{name}/{version}-{compiler.name}'
|
||||||
|
|
||||||
assert writer.conf.naming_scheme == expected
|
assert writer.conf.naming_scheme == expected
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
from spack.spec import Spec, UnsatisfiableSpecError, SpecError
|
from spack.spec import Spec, UnsatisfiableSpecError, SpecError
|
||||||
from spack.spec import substitute_abstract_variants, parse_anonymous_spec
|
from spack.spec import substitute_abstract_variants, parse_anonymous_spec
|
||||||
|
from spack.spec import SpecFormatSigilError, SpecFormatStringError
|
||||||
from spack.variant import InvalidVariantValueError
|
from spack.variant import InvalidVariantValueError
|
||||||
from spack.variant import MultipleValuesInExclusiveVariantError
|
from spack.variant import MultipleValuesInExclusiveVariantError
|
||||||
|
|
||||||
@ -736,28 +737,133 @@ def test_exceptional_paths_for_constructor(self):
|
|||||||
Spec('libelf foo')
|
Spec('libelf foo')
|
||||||
|
|
||||||
def test_spec_formatting(self):
|
def test_spec_formatting(self):
|
||||||
|
spec = Spec("multivalue_variant cflags=-O2")
|
||||||
|
spec.concretize()
|
||||||
|
|
||||||
|
# Since the default is the full spec see if the string rep of
|
||||||
|
# spec is the same as the output of spec.format()
|
||||||
|
# ignoring whitespace (though should we?) and ignoring dependencies
|
||||||
|
spec_string = str(spec)
|
||||||
|
idx = spec_string.index(' ^')
|
||||||
|
assert spec_string[:idx] == spec.format().strip()
|
||||||
|
|
||||||
|
# Testing named strings ie {string} and whether we get
|
||||||
|
# the correct component
|
||||||
|
# Mixed case intentional to test both
|
||||||
|
package_segments = [("{NAME}", "name"),
|
||||||
|
("{VERSION}", "versions"),
|
||||||
|
("{compiler}", "compiler"),
|
||||||
|
("{compiler_flags}", "compiler_flags"),
|
||||||
|
("{variants}", "variants"),
|
||||||
|
("{architecture}", "architecture")]
|
||||||
|
|
||||||
|
sigil_package_segments = [("{@VERSIONS}", '@' + str(spec.version)),
|
||||||
|
("{%compiler}", '%' + str(spec.compiler)),
|
||||||
|
("{arch=architecture}",
|
||||||
|
' arch=' + str(spec.architecture))]
|
||||||
|
|
||||||
|
compiler_segments = [("{compiler.name}", "name"),
|
||||||
|
("{compiler.version}", "versions")]
|
||||||
|
|
||||||
|
sigil_compiler_segments = [("{%compiler.name}",
|
||||||
|
'%' + spec.compiler.name),
|
||||||
|
("{@compiler.version}",
|
||||||
|
'@' + str(spec.compiler.version))]
|
||||||
|
|
||||||
|
architecture_segments = [("{architecture.platform}", "platform"),
|
||||||
|
("{architecture.os}", "os"),
|
||||||
|
("{architecture.target}", "target")]
|
||||||
|
|
||||||
|
other_segments = [('{spack_root}', spack.paths.spack_root),
|
||||||
|
('{spack_install}', spack.store.layout.root),
|
||||||
|
('{hash:7}', spec.dag_hash(7)),
|
||||||
|
('{/hash}', '/' + spec.dag_hash())]
|
||||||
|
|
||||||
|
for named_str, prop in package_segments:
|
||||||
|
expected = getattr(spec, prop, "")
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert str(expected) == actual
|
||||||
|
|
||||||
|
for named_str, expected in sigil_package_segments:
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert expected == actual
|
||||||
|
|
||||||
|
compiler = spec.compiler
|
||||||
|
for named_str, prop in compiler_segments:
|
||||||
|
expected = getattr(compiler, prop, "")
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert str(expected) == actual
|
||||||
|
|
||||||
|
for named_str, expected in sigil_compiler_segments:
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert expected == actual
|
||||||
|
|
||||||
|
arch = spec.architecture
|
||||||
|
for named_str, prop in architecture_segments:
|
||||||
|
expected = getattr(arch, prop, "")
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert str(expected) == actual
|
||||||
|
|
||||||
|
for named_str, expected in other_segments:
|
||||||
|
actual = spec.format(named_str)
|
||||||
|
assert expected == actual
|
||||||
|
|
||||||
|
def test_spec_formatting_escapes(self):
|
||||||
|
spec = Spec('multivalue_variant cflags=-O2')
|
||||||
|
spec.concretize()
|
||||||
|
|
||||||
|
sigil_mismatches = [
|
||||||
|
'{@name}',
|
||||||
|
'{@version.concrete}',
|
||||||
|
'{%compiler.version}',
|
||||||
|
'{/hashd}',
|
||||||
|
'{arch=architecture.os}'
|
||||||
|
]
|
||||||
|
|
||||||
|
for fmt_str in sigil_mismatches:
|
||||||
|
with pytest.raises(SpecFormatSigilError):
|
||||||
|
spec.format(fmt_str)
|
||||||
|
|
||||||
|
bad_formats = [
|
||||||
|
'{}',
|
||||||
|
'name}',
|
||||||
|
'\{name}', # NOQA: ignore=W605
|
||||||
|
'{name',
|
||||||
|
'{name\}', # NOQA: ignore=W605
|
||||||
|
'{_concrete}',
|
||||||
|
'{dag_hash}',
|
||||||
|
'{foo}',
|
||||||
|
'{+variants.debug}'
|
||||||
|
]
|
||||||
|
|
||||||
|
for fmt_str in bad_formats:
|
||||||
|
with pytest.raises(SpecFormatStringError):
|
||||||
|
spec.format(fmt_str)
|
||||||
|
|
||||||
|
def test_spec_deprecated_formatting(self):
|
||||||
spec = Spec("libelf cflags=-O2")
|
spec = Spec("libelf cflags=-O2")
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
|
|
||||||
# Since the default is the full spec see if the string rep of
|
# Since the default is the full spec see if the string rep of
|
||||||
# spec is the same as the output of spec.format()
|
# spec is the same as the output of spec.format()
|
||||||
# ignoring whitespace (though should we?)
|
# ignoring whitespace (though should we?)
|
||||||
assert str(spec) == spec.format().strip()
|
assert str(spec) == spec.format('$_$@$%@+$+$=').strip()
|
||||||
|
|
||||||
# Testing named strings ie ${STRING} and whether we get
|
# Testing named strings ie {string} and whether we get
|
||||||
# the correct component
|
# the correct component
|
||||||
|
# Mixed case intentional for testing both
|
||||||
package_segments = [("${PACKAGE}", "name"),
|
package_segments = [("${PACKAGE}", "name"),
|
||||||
("${VERSION}", "versions"),
|
("${VERSION}", "versions"),
|
||||||
("${COMPILER}", "compiler"),
|
("${compiler}", "compiler"),
|
||||||
("${COMPILERFLAGS}", "compiler_flags"),
|
("${compilerflags}", "compiler_flags"),
|
||||||
("${OPTIONS}", "variants"),
|
("${options}", "variants"),
|
||||||
("${ARCHITECTURE}", "architecture")]
|
("${architecture}", "architecture")]
|
||||||
|
|
||||||
compiler_segments = [("${COMPILERNAME}", "name"),
|
compiler_segments = [("${compilername}", "name"),
|
||||||
("${COMPILERVER}", "versions")]
|
("${compilerver}", "versions")]
|
||||||
|
|
||||||
architecture_segments = [("${PLATFORM}", "platform"),
|
architecture_segments = [("${PLATFORM}", "platform"),
|
||||||
("${OS}", "platform_os"),
|
("${OS}", "os"),
|
||||||
("${TARGET}", "target")]
|
("${TARGET}", "target")]
|
||||||
|
|
||||||
for named_str, prop in package_segments:
|
for named_str, prop in package_segments:
|
||||||
|
@ -203,8 +203,8 @@ def test_canonicalize(self):
|
|||||||
"x ^y~f+e~d+c~b+a@4,2:3,1%intel@4,3,2,1")
|
"x ^y~f+e~d+c~b+a@4,2:3,1%intel@4,3,2,1")
|
||||||
|
|
||||||
self.check_parse(
|
self.check_parse(
|
||||||
"x arch=test-redhat6-None "
|
"x arch=test-redhat6-None"
|
||||||
" ^y arch=test-None-x86_64 "
|
" ^y arch=test-None-x86_64"
|
||||||
" ^z arch=linux-None-None",
|
" ^z arch=linux-None-None",
|
||||||
|
|
||||||
"x os=fe "
|
"x os=fe "
|
||||||
@ -212,11 +212,11 @@ def test_canonicalize(self):
|
|||||||
"^z platform=linux")
|
"^z platform=linux")
|
||||||
|
|
||||||
self.check_parse(
|
self.check_parse(
|
||||||
"x arch=test-debian6-x86_64 "
|
"x arch=test-debian6-x86_64"
|
||||||
" ^y arch=test-debian6-x86_64",
|
" ^y arch=test-debian6-x86_64",
|
||||||
|
|
||||||
"x os=default_os target=default_target "
|
"x os=default_os target=default_target"
|
||||||
"^y os=default_os target=default_target")
|
" ^y os=default_os target=default_target")
|
||||||
|
|
||||||
self.check_parse("x ^y", "x@: ^y@:")
|
self.check_parse("x ^y", "x@: ^y@:")
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ def write_rpath_specs(self):
|
|||||||
the compiler used to build the executable."""
|
the compiler used to build the executable."""
|
||||||
if not self.spec_dir:
|
if not self.spec_dir:
|
||||||
tty.warn('Could not install specs for {0}.'.format(
|
tty.warn('Could not install specs for {0}.'.format(
|
||||||
self.spec.format('$_$@')))
|
self.spec.format('{name}{@version}')))
|
||||||
return
|
return
|
||||||
|
|
||||||
gcc = self.spec['gcc'].command
|
gcc = self.spec['gcc'].command
|
||||||
|
@ -67,7 +67,9 @@ def patch(self):
|
|||||||
add_extra_files(self, self.common, self.assets)
|
add_extra_files(self, self.common, self.assets)
|
||||||
# Emit openfoam version immediately, if we resolved the wrong version
|
# Emit openfoam version immediately, if we resolved the wrong version
|
||||||
# it takes a very long time to rebuild!
|
# it takes a very long time to rebuild!
|
||||||
tty.info('Build for ' + self.spec['openfoam'].format('$_$@$%@+$+'))
|
tty.info('Build for ' + self.spec['openfoam'].format(
|
||||||
|
'{name}{@version}{%compiler}{compiler_flags}{variants}'
|
||||||
|
))
|
||||||
|
|
||||||
def configure(self, spec, prefix):
|
def configure(self, spec, prefix):
|
||||||
"""Generate spack-config.sh file."""
|
"""Generate spack-config.sh file."""
|
||||||
|
@ -42,7 +42,9 @@ def patch(self):
|
|||||||
add_extra_files(self, self.common, self.assets)
|
add_extra_files(self, self.common, self.assets)
|
||||||
# Emit openfoam version immediately, if we resolved the wrong version
|
# Emit openfoam version immediately, if we resolved the wrong version
|
||||||
# it takes a very long time to rebuild!
|
# it takes a very long time to rebuild!
|
||||||
tty.info('Build for ' + self.spec['openfoam'].format('$_$@$%@+$+'))
|
tty.info('Build for ' + self.spec['openfoam'].format(
|
||||||
|
'{name}{@version}{%compiler}{compiler_flags}{variants}'
|
||||||
|
))
|
||||||
|
|
||||||
def configure(self, spec, prefix):
|
def configure(self, spec, prefix):
|
||||||
"""Generate spack-config.sh file."""
|
"""Generate spack-config.sh file."""
|
||||||
|
Loading…
Reference in New Issue
Block a user