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
|
||||
also possible to modify the entire installation scheme. By default
|
||||
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
|
||||
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
|
||||
@ -48,7 +48,7 @@ the installation paths. For example
|
||||
.. code-block:: yaml
|
||||
|
||||
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
|
||||
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
|
||||
template_dirs:
|
||||
- $spack/templates
|
||||
directory_layout: ${ARCHITECTURE}/${COMPILERNAME}-${COMPILERVER}/${PACKAGE}-${VERSION}-${HASH}
|
||||
directory_layout: {architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}
|
||||
module_roots:
|
||||
tcl: $spack/share/spack/modules
|
||||
lmod: $spack/share/spack/lmod
|
||||
@ -510,7 +510,7 @@ down the problem:
|
||||
./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: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:33 tcl: $spack/share/spack/modules
|
||||
/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:
|
||||
tcl:
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
- 'intel/14.0.1'
|
||||
|
||||
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:
|
||||
tcl:
|
||||
hash_length: 0
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||
whitelist:
|
||||
- gcc
|
||||
blacklist:
|
||||
- '%gcc@5.4.0'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
suffixes:
|
||||
'^openblas': openblas
|
||||
'^netlib-lapack': netlib
|
||||
@ -713,14 +713,14 @@ is installed. You can achieve this with Spack by adding an
|
||||
modules:
|
||||
tcl:
|
||||
hash_length: 0
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||
whitelist:
|
||||
- gcc
|
||||
blacklist:
|
||||
- '%gcc@5.4.0'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
suffixes:
|
||||
'^openblas': openblas
|
||||
'^netlib-lapack': netlib
|
||||
@ -728,7 +728,7 @@ is installed. You can achieve this with Spack by adding an
|
||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
netlib-scalapack:
|
||||
suffixes:
|
||||
'^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
|
||||
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``,
|
||||
``VERSION``, ``COMPILER``, ``COMPILERNAME``, ``COMPILERVER``, ``ARCHITECTURE``
|
||||
- The set of allowed tokens in variable names is restricted to
|
||||
``name``, ``version``, ``compiler``, ``compiler.name``,
|
||||
``compiler.version``, ``architecture``
|
||||
- Any token expanded in a variable name is made uppercase, but other than that
|
||||
case sensitivity is preserved
|
||||
|
||||
@ -784,14 +785,14 @@ etc. in the ``gcc`` module file and apply other custom modifications to the
|
||||
modules:
|
||||
tcl:
|
||||
hash_length: 0
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||
whitelist:
|
||||
- gcc
|
||||
blacklist:
|
||||
- '%gcc@5.4.0'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
suffixes:
|
||||
'^openblas': openblas
|
||||
'^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:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
gcc:
|
||||
environment:
|
||||
set:
|
||||
@ -896,14 +897,14 @@ directive and assigning it the value ``direct``:
|
||||
tcl:
|
||||
verbose: True
|
||||
hash_length: 0
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{compiler.version}'
|
||||
whitelist:
|
||||
- gcc
|
||||
blacklist:
|
||||
- '%gcc@5.4.0'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
suffixes:
|
||||
'^openblas': openblas
|
||||
'^netlib-lapack': netlib
|
||||
@ -911,7 +912,7 @@ directive and assigning it the value ``direct``:
|
||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
gcc:
|
||||
environment:
|
||||
set:
|
||||
@ -1089,7 +1090,7 @@ After these modifications your configuration file should look like:
|
||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
gcc:
|
||||
environment:
|
||||
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:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
gcc:
|
||||
environment:
|
||||
set:
|
||||
@ -1534,7 +1535,7 @@ it's ``netlib-scalapack``:
|
||||
environment_blacklist: ['CPATH', 'LIBRARY_PATH']
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
gcc:
|
||||
environment:
|
||||
set:
|
||||
|
@ -541,9 +541,9 @@ spec format strings, as shown in the example below.
|
||||
.. code-block:: yaml
|
||||
|
||||
projections:
|
||||
zlib: ${PACKAGE}-${VERSION}
|
||||
^mpi: ${PACKAGE}-${VERSION}/${DEP:mpi:PACKAGE}-${DEP:mpi:VERSION}-${COMPILERNAME}-${COMPILERVER}
|
||||
all: ${PACKAGE}-${VERSION}/${COMPILERNAME}-${COMPILERVER}
|
||||
zlib: {name}-{version}
|
||||
^mpi: {name}-{version}/{^mpi.name}-{^mpi.version}-{compiler.name}-{compiler.version}
|
||||
all: {name}-{version}/{compiler.name}-{compiler.version}
|
||||
|
||||
The entries in the projections configuration file must all be either
|
||||
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
|
||||
if plat and os:
|
||||
os = self.platform.operating_system(os)
|
||||
self.platform_os = os
|
||||
self.os = os
|
||||
if plat and target:
|
||||
target = self.platform.target(target)
|
||||
self.target = target
|
||||
@ -349,16 +349,16 @@ def __init__(self, plat=None, os=None, target=None):
|
||||
def concrete(self):
|
||||
return all((self.platform is not None,
|
||||
isinstance(self.platform, Platform),
|
||||
self.platform_os is not None,
|
||||
isinstance(self.platform_os, OperatingSystem),
|
||||
self.os is not None,
|
||||
isinstance(self.os, OperatingSystem),
|
||||
self.target is not None, isinstance(self.target, Target)))
|
||||
|
||||
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':
|
||||
os_name = self.platform_os.name if self.platform_os else "None"
|
||||
os_name = self.os.name if self.os else "None"
|
||||
else:
|
||||
os_name = str(self.platform_os)
|
||||
os_name = str(self.os)
|
||||
|
||||
return (str(self.platform) + "-" +
|
||||
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.
|
||||
def __nonzero__(self):
|
||||
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)
|
||||
__bool__ = __nonzero__
|
||||
|
||||
@ -380,21 +380,21 @@ def _cmp_key(self):
|
||||
platform = self.platform.name
|
||||
else:
|
||||
platform = self.platform
|
||||
if isinstance(self.platform_os, OperatingSystem):
|
||||
platform_os = self.platform_os.name
|
||||
if isinstance(self.os, OperatingSystem):
|
||||
os = self.os.name
|
||||
else:
|
||||
platform_os = self.platform_os
|
||||
os = self.os
|
||||
if isinstance(self.target, Target):
|
||||
target = self.target.name
|
||||
else:
|
||||
target = self.target
|
||||
return (platform, platform_os, target)
|
||||
return (platform, os, target)
|
||||
|
||||
def to_dict(self):
|
||||
str_or_none = lambda v: str(v) if v else None
|
||||
d = syaml_dict([
|
||||
('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))])
|
||||
return syaml_dict([('arch', d)])
|
||||
|
||||
@ -430,13 +430,13 @@ def arch_for_spec(arch_spec):
|
||||
assert(arch_spec.concrete)
|
||||
|
||||
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)):
|
||||
raise ValueError(
|
||||
"Can't recreate arch for spec %s on current arch %s; "
|
||||
"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
|
||||
|
@ -381,7 +381,7 @@ def set_build_environment_variables(pkg, env, dirty):
|
||||
if spack.config.get('config:debug'):
|
||||
env.set(SPACK_DEBUG, 'TRUE')
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
elif len(matching_specs) > 1:
|
||||
format_string = '{name}{@version}{%compiler}{arch=architecture}'
|
||||
args = ["%s matches multiple packages." % spec,
|
||||
"Matching packages:"]
|
||||
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."]
|
||||
tty.die(*args)
|
||||
|
||||
@ -263,15 +264,15 @@ def get_arg(name, default=None):
|
||||
hashes = True
|
||||
hlen = None
|
||||
|
||||
nfmt = '{fullpackage}' if namespace else '{package}'
|
||||
nfmt = '{namespace}{name}' if namespace else '{name}'
|
||||
ffmt = ''
|
||||
if full_compiler or flags:
|
||||
ffmt += '$%'
|
||||
ffmt += '{%compiler.name}'
|
||||
if full_compiler:
|
||||
ffmt += '@'
|
||||
ffmt += '+'
|
||||
vfmt = '$+' if variants else ''
|
||||
format_string = '$%s$@%s%s' % (nfmt, ffmt, vfmt)
|
||||
ffmt += '{@compiler.version}'
|
||||
ffmt += ' {compiler_flags}'
|
||||
vfmt = '{variants}' if variants else ''
|
||||
format_string = nfmt + '{@version}' + ffmt + vfmt
|
||||
|
||||
# Make a dict with specs keyed by architecture and compiler.
|
||||
index = index_by(specs, ('architecture', 'compiler'))
|
||||
@ -329,7 +330,7 @@ def fmt(s):
|
||||
if hashes:
|
||||
string += gray_hash(s, hlen) + ' '
|
||||
string += s.cformat(
|
||||
'$%s$@%s' % (nfmt, vfmt), transform=transform)
|
||||
nfmt + '{@version}' + vfmt, transform=transform)
|
||||
return string
|
||||
|
||||
if not flags and not full_compiler:
|
||||
|
@ -32,7 +32,7 @@ def arch(parser, args):
|
||||
if args.platform:
|
||||
print(arch.platform)
|
||||
elif args.operating_system:
|
||||
print(arch.platform_os)
|
||||
print(arch.os)
|
||||
elif args.target:
|
||||
print(arch.target)
|
||||
else:
|
||||
|
@ -42,7 +42,8 @@ def dependencies(parser, args):
|
||||
env = ev.get_env(args, 'dependencies')
|
||||
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(
|
||||
spec, 'children', args.transitive)
|
||||
if deps:
|
||||
|
@ -85,7 +85,8 @@ def dependents(parser, args):
|
||||
env = ev.get_env(args, 'dependents')
|
||||
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(
|
||||
spec, 'parents', args.transitive)
|
||||
if deps:
|
||||
|
@ -162,7 +162,7 @@ def mirror_create(args):
|
||||
# If nothing is passed, use all packages.
|
||||
if not specs:
|
||||
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 args.dependencies:
|
||||
@ -204,7 +204,7 @@ def mirror_create(args):
|
||||
" %-4d failed to fetch." % e)
|
||||
if error:
|
||||
tty.error("Failed downloads:")
|
||||
colify(s.cformat("$_$@") for s in error)
|
||||
colify(s.cformat("{name}{@version}") for s in error)
|
||||
|
||||
|
||||
def mirror(parser, args):
|
||||
|
@ -344,7 +344,9 @@ def modules_cmd(parser, args, module_type, callbacks=callbacks):
|
||||
except MultipleSpecsMatch:
|
||||
msg = "the constraint '{query}' matches multiple packages:\n"
|
||||
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.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):
|
||||
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
|
||||
kwargs = {
|
||||
'cover': args.cover,
|
||||
'format': name_fmt + '$@$%@+$+$=',
|
||||
'format': name_fmt + fmt,
|
||||
'hashlen': None if args.very_long else 7,
|
||||
'show_types': args.types,
|
||||
'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:
|
||||
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')
|
||||
|
||||
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]
|
||||
|
||||
if len(matching_in_view) > 1:
|
||||
spec_format = '{name}{@version}{%compiler}{arch=architecture}'
|
||||
args = ["Spec matches multiple packages.",
|
||||
"Matching packages:"]
|
||||
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."]
|
||||
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
|
||||
# is for the given operating system
|
||||
os = items.get('operating_system', None)
|
||||
if arch_spec and os != arch_spec.platform_os:
|
||||
if arch_spec and os != arch_spec.os:
|
||||
continue
|
||||
|
||||
# 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)
|
||||
if len(compilers) < 1:
|
||||
raise NoCompilerForSpecError(compiler_spec, arch_spec.platform_os)
|
||||
raise NoCompilerForSpecError(compiler_spec, arch_spec.os)
|
||||
if len(compilers) > 1:
|
||||
raise CompilerDuplicateError(compiler_spec, arch_spec)
|
||||
return compilers[0]
|
||||
|
@ -285,7 +285,7 @@ def concretize_compiler(self, spec):
|
||||
"""
|
||||
# Pass on concretizing the compiler if the target or operating system
|
||||
# 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
|
||||
# continue. `return True` here to force concretization to keep
|
||||
# running.
|
||||
@ -371,7 +371,7 @@ def concretize_compiler_flags(self, spec):
|
||||
"""
|
||||
# Pass on concretizing the compiler flags if the target or operating
|
||||
# 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
|
||||
# continue. `return True` here to force concretization to keep
|
||||
# running.
|
||||
@ -471,7 +471,7 @@ def __init__(self, arch, available_os_targets):
|
||||
" for operating system %s and target %s."
|
||||
"\nIf previous installations have succeeded, the"
|
||||
" operating system may have been updated." %
|
||||
(arch.platform_os, arch.target))
|
||||
(arch.os, arch.target))
|
||||
|
||||
available_os_target_strs = list()
|
||||
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)
|
||||
if arch:
|
||||
err_msg += " for operating system {0} and target {1}.".format(
|
||||
arch.platform_os, arch.target
|
||||
arch.os, arch.target
|
||||
)
|
||||
|
||||
super(UnavailableCompilerVersionError, self).__init__(
|
||||
|
@ -384,7 +384,8 @@ def _assign_dependencies(self, hash_key, installs, data):
|
||||
if not child:
|
||||
msg = ("Missing dependency not in database: "
|
||||
"%s needs %s-%s" % (
|
||||
spec.cformat('$_$/'), dname, dhash[:7]))
|
||||
spec.cformat('{name}{/hash:7}'),
|
||||
dname, dhash[:7]))
|
||||
if self._fail_when_missing_deps:
|
||||
raise MissingDependenciesError(msg)
|
||||
tty.warn(msg)
|
||||
|
@ -175,15 +175,15 @@ def __init__(self, root, **kwargs):
|
||||
super(YamlDirectoryLayout, self).__init__(root)
|
||||
self.hash_len = kwargs.get('hash_len')
|
||||
self.path_scheme = kwargs.get('path_scheme') or (
|
||||
"${ARCHITECTURE}/"
|
||||
"${COMPILERNAME}-${COMPILERVER}/"
|
||||
"${PACKAGE}-${VERSION}-${HASH}")
|
||||
"{architecture}/"
|
||||
"{compiler.name}-{compiler.version}/"
|
||||
"{name}-{version}-{hash}")
|
||||
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(
|
||||
"Conflicting options for installation layout hash length")
|
||||
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
|
||||
# locate files in older upstream databases
|
||||
|
@ -557,7 +557,8 @@ def print_status(self, *specs, **kwargs):
|
||||
specs = index[(architecture, compiler)]
|
||||
specs.sort()
|
||||
|
||||
format_string = '$_$@$%@+$+'
|
||||
format_string = '{name}{@version}'
|
||||
format_string += '{%compiler}{compiler_flags}{variants}'
|
||||
abbreviated = [s.cformat(format_string) for s in specs]
|
||||
|
||||
# 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):
|
||||
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:
|
||||
spec.package.do_fetch()
|
||||
spec.package.do_clean()
|
||||
@ -220,7 +222,8 @@ def add_single_spec(spec, mirror_root, categories, **kwargs):
|
||||
sys.excepthook(*sys.exc_info())
|
||||
else:
|
||||
tty.warn(
|
||||
"Error while fetching %s" % spec.cformat('$_$@'), e.message)
|
||||
"Error while fetching %s" % spec.cformat('{name}{@version}'),
|
||||
e.message)
|
||||
categories['error'].append(spec)
|
||||
|
||||
|
||||
|
@ -59,12 +59,12 @@
|
||||
|
||||
#: Valid tokens for naming scheme and env variable names
|
||||
_valid_tokens = (
|
||||
'PACKAGE',
|
||||
'VERSION',
|
||||
'COMPILER',
|
||||
'COMPILERNAME',
|
||||
'COMPILERVER',
|
||||
'ARCHITECTURE'
|
||||
'name',
|
||||
'version',
|
||||
'compiler',
|
||||
'compiler.name',
|
||||
'compiler.version',
|
||||
'architecture'
|
||||
)
|
||||
|
||||
|
||||
@ -80,8 +80,9 @@ def _check_tokens_are_valid(format_string, message):
|
||||
tokens are found
|
||||
|
||||
"""
|
||||
named_tokens = re.findall(r'\${(\w*)}', format_string)
|
||||
invalid_tokens = [x for x in named_tokens if x not in _valid_tokens]
|
||||
named_tokens = re.findall(r'{(\w*)}', format_string)
|
||||
invalid_tokens = [x for x in named_tokens
|
||||
if x.lower() not in _valid_tokens]
|
||||
if invalid_tokens:
|
||||
msg = message
|
||||
msg += ' [{0}]. '.format(', '.join(invalid_tokens))
|
||||
@ -294,7 +295,7 @@ def naming_scheme(self):
|
||||
"""Naming scheme suitable for non-hierarchical layouts"""
|
||||
scheme = self.module.configuration.get(
|
||||
'naming_scheme',
|
||||
'${PACKAGE}-${VERSION}-${COMPILERNAME}-${COMPILERVER}'
|
||||
'{name}-{version}-{compiler.name}-{compiler.version}'
|
||||
)
|
||||
|
||||
# Ensure the named tokens we are expanding are allowed, see
|
||||
@ -523,7 +524,7 @@ def short_description(self):
|
||||
value = re.sub(r'"', "'", value)
|
||||
return value
|
||||
# Otherwise the short description is just the package + version
|
||||
return self.spec.format("$_ $@")
|
||||
return self.spec.format("{name} {@version}")
|
||||
|
||||
@tengine.context_property
|
||||
def long_description(self):
|
||||
|
@ -232,7 +232,7 @@ def use_name(self):
|
||||
to console to use it.
|
||||
"""
|
||||
# Package name and version
|
||||
base = os.path.join("${PACKAGE}", "${VERSION}")
|
||||
base = os.path.join("{name}", "{version}")
|
||||
name_parts = [self.spec.format(base)]
|
||||
# The remaining elements are filename suffixes
|
||||
name_parts.extend(self.conf.suffixes)
|
||||
|
@ -946,7 +946,7 @@ def do_fetch(self, mirror_only=False):
|
||||
checksum = spack.config.get('config:checksum')
|
||||
if checksum and self.version not in self.versions:
|
||||
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
|
||||
# interactive, but just fail if non-interactive.
|
||||
@ -960,7 +960,7 @@ def do_fetch(self, mirror_only=False):
|
||||
|
||||
if not ignore_checksum:
|
||||
raise FetchError("Will not fetch %s" %
|
||||
self.spec.format('$_$@'), ck_msg)
|
||||
self.spec.format('{name}{@version}'), ck_msg)
|
||||
|
||||
self.stage.create()
|
||||
self.stage.fetch(mirror_only)
|
||||
|
@ -96,6 +96,7 @@
|
||||
from llnl.util.tty.color import cwrite, colorize, cescape, get_color_when
|
||||
import llnl.util.tty as tty
|
||||
|
||||
import spack.paths
|
||||
import spack.architecture
|
||||
import spack.compiler
|
||||
import spack.compilers as compilers
|
||||
@ -187,6 +188,10 @@
|
||||
#: Max integer helps avoid passing too large a value to cyaml.
|
||||
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):
|
||||
"""Returns a spec colorized according to the colors specified in
|
||||
@ -221,7 +226,7 @@ class ArchSpec(object):
|
||||
def __init__(self, *args):
|
||||
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:
|
||||
spec_like = args[0]
|
||||
@ -231,13 +236,13 @@ def __init__(self, *args):
|
||||
spec_fields = spec_like.split("-")
|
||||
|
||||
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)
|
||||
else:
|
||||
raise ValueError("%s is an invalid arch spec" % spec_like)
|
||||
elif len(args) == 3:
|
||||
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])
|
||||
elif len(args) != 0:
|
||||
raise TypeError("Can't make arch spec from %s" % args)
|
||||
@ -248,11 +253,11 @@ def _autospec(self, spec_like):
|
||||
return ArchSpec(spec_like)
|
||||
|
||||
def _cmp_key(self):
|
||||
return (self.platform, self.platform_os, self.target)
|
||||
return (self.platform, self.os, self.target)
|
||||
|
||||
def _dup(self, other):
|
||||
self.platform = other.platform
|
||||
self.platform_os = other.platform_os
|
||||
self.os = other.os
|
||||
self.target = other.target
|
||||
|
||||
@property
|
||||
@ -269,11 +274,11 @@ def platform(self, value):
|
||||
self._platform = value
|
||||
|
||||
@property
|
||||
def platform_os(self):
|
||||
return self._platform_os
|
||||
def os(self):
|
||||
return self._os
|
||||
|
||||
@platform_os.setter
|
||||
def platform_os(self, value):
|
||||
@os.setter
|
||||
def os(self, value):
|
||||
""" 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
|
||||
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)
|
||||
value = str(spec_platform.operating_system(value))
|
||||
|
||||
self._platform_os = value
|
||||
self._os = value
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
@ -369,13 +374,13 @@ def to_cmp_dict(self):
|
||||
"""Returns a dictionary that can be used for field comparison."""
|
||||
return dict([
|
||||
('platform', self.platform),
|
||||
('platform_os', self.platform_os),
|
||||
('os', self.os),
|
||||
('target', self.target)])
|
||||
|
||||
def to_dict(self):
|
||||
d = syaml_dict([
|
||||
('platform', self.platform),
|
||||
('platform_os', self.platform_os),
|
||||
('platform_os', self.os),
|
||||
('target', self.target)])
|
||||
return syaml_dict([('arch', d)])
|
||||
|
||||
@ -397,10 +402,13 @@ def from_dict(d):
|
||||
return ArchSpec('spack09', 'unknown', d['arch'])
|
||||
|
||||
d = d['arch']
|
||||
if 'platform_os' in d:
|
||||
return ArchSpec(d['platform'], d['platform_os'], d['target'])
|
||||
else:
|
||||
return ArchSpec(d['platform'], d['os'], d['target'])
|
||||
|
||||
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):
|
||||
return str(self)
|
||||
@ -835,10 +843,10 @@ def __get__(self, instance, cls):
|
||||
# properties defined and no default handler, or that all callbacks
|
||||
# raised AttributeError. In this case, we raise AttributeError with an
|
||||
# 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 += '\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(
|
||||
name=pkg.name,
|
||||
query=self.attribute_name,
|
||||
@ -1004,11 +1012,11 @@ def _add_flag(self, name, value):
|
||||
if name == 'arch' or name == 'architecture':
|
||||
parts = tuple(value.split('-'))
|
||||
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':
|
||||
self._set_architecture(platform=value)
|
||||
elif name == 'os' or name == 'operating_system':
|
||||
self._set_architecture(platform_os=value)
|
||||
self._set_architecture(os=value)
|
||||
elif name == 'target':
|
||||
self._set_architecture(target=value)
|
||||
elif name in valid_flags:
|
||||
@ -1026,7 +1034,7 @@ def _add_flag(self, name, value):
|
||||
|
||||
def _set_architecture(self, **kwargs):
|
||||
"""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:
|
||||
raise DuplicateArchitectureError(
|
||||
"Spec for '%s' cannot have two architectures." % self.name)
|
||||
@ -1258,12 +1266,16 @@ def return_val(dspec):
|
||||
def short_spec(self):
|
||||
"""Returns a version of the spec with the dependencies hashed
|
||||
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
|
||||
def cshort_spec(self):
|
||||
"""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
|
||||
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 != oarch.platform:
|
||||
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
||||
if sarch.platform_os is not None and oarch.platform_os is not None:
|
||||
if sarch.platform_os != oarch.platform_os:
|
||||
if sarch.os is not None and oarch.os is not None:
|
||||
if sarch.os != oarch.os:
|
||||
raise UnsatisfiableArchitectureSpecError(sarch, oarch)
|
||||
if sarch.target is not None and oarch.target is not None:
|
||||
if sarch.target != oarch.target:
|
||||
@ -2460,8 +2472,8 @@ def constrain(self, other, deps=True):
|
||||
else:
|
||||
if sarch.platform is None or oarch.platform is None:
|
||||
self.architecture.platform = sarch.platform or oarch.platform
|
||||
if sarch.platform_os is None or oarch.platform_os is None:
|
||||
sarch.platform_os = sarch.platform_os or oarch.platform_os
|
||||
if sarch.os is None or oarch.os is None:
|
||||
sarch.os = sarch.os or oarch.os
|
||||
if sarch.target is None or oarch.target is None:
|
||||
sarch.target = sarch.target or oarch.target
|
||||
changed |= (str(self.architecture) != old)
|
||||
@ -3010,10 +3022,245 @@ def _cmp_key(self):
|
||||
def colorized(self):
|
||||
return colorize_spec(self)
|
||||
|
||||
def format(self, format_string='$_$@$%@+$+$=', **kwargs):
|
||||
"""Prints out particular pieces of a spec, depending on what is
|
||||
def format(self, format_string=default_format, **kwargs):
|
||||
r"""Prints out particular pieces of a spec, depending on what is
|
||||
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::
|
||||
|
||||
$_ 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., ``$//`` for full hash.
|
||||
"""
|
||||
|
||||
color = kwargs.get('color', False)
|
||||
|
||||
# Dictionary of transformations for named tokens
|
||||
@ -3218,7 +3466,7 @@ def write(s, c=None):
|
||||
platform = str(self.architecture.platform)
|
||||
write(fmt % transform(self, platform), '=')
|
||||
elif named_str == "OS":
|
||||
operating_sys = str(self.architecture.platform_os)
|
||||
operating_sys = str(self.architecture.os)
|
||||
write(fmt % transform(self, operating_sys), '=')
|
||||
elif named_str == "TARGET":
|
||||
target = str(self.architecture.target)
|
||||
@ -3302,7 +3550,7 @@ def tree(self, **kwargs):
|
||||
status_fn = kwargs.pop('status_fn', False)
|
||||
cover = kwargs.pop('cover', 'nodes')
|
||||
indent = kwargs.pop('indent', 0)
|
||||
fmt = kwargs.pop('format', '$_$@$%@+$+$=')
|
||||
fmt = kwargs.pop('format', default_format)
|
||||
prefix = kwargs.pop('prefix', None)
|
||||
show_types = kwargs.pop('show_types', False)
|
||||
deptypes = kwargs.pop('deptypes', 'all')
|
||||
@ -3516,7 +3764,7 @@ def do_parse(self):
|
||||
for spec in specs:
|
||||
for s in spec.traverse():
|
||||
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)
|
||||
return specs
|
||||
|
||||
@ -3877,7 +4125,9 @@ def __init__(self, provided, required):
|
||||
|
||||
class AmbiguousHashError(SpecError):
|
||||
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)
|
||||
super(AmbiguousHashError, self).__init__(msg + specs_str)
|
||||
|
||||
@ -3904,6 +4154,18 @@ def __init__(self, spec, addition):
|
||||
% (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):
|
||||
def __init__(self, spec, matches):
|
||||
message = 'Conflicts in concretized spec "{0}"\n'.format(
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
@ -21,7 +22,7 @@
|
||||
def test_dict_functions_for_architecture():
|
||||
arch = spack.architecture.Arch()
|
||||
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')
|
||||
|
||||
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 isinstance(arch, spack.architecture.Arch)
|
||||
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(new_arch, spack.architecture.Arch)
|
||||
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)
|
||||
|
||||
|
||||
@ -67,7 +68,7 @@ def test_boolness():
|
||||
assert arch
|
||||
|
||||
arch = spack.architecture.Arch()
|
||||
arch.platform_os = plat_os
|
||||
arch.os = plat_os
|
||||
assert 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.concretize()
|
||||
|
||||
assert frontend_os == frontend_spec.architecture.platform_os
|
||||
assert frontend_os == frontend_spec.architecture.os
|
||||
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.concretize()
|
||||
|
||||
assert backend_os == backend_spec.architecture.platform_os
|
||||
assert backend_os == backend_spec.architecture.os
|
||||
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.concretize()
|
||||
|
||||
assert default_os == default_spec.architecture.platform_os
|
||||
assert default_os == default_spec.architecture.os
|
||||
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.concretize()
|
||||
results.append(
|
||||
spec.architecture.platform_os == str(platform.operating_system(o))
|
||||
spec.architecture.os == str(platform.operating_system(o))
|
||||
)
|
||||
results.append(
|
||||
spec.architecture.target == str(platform.target(t))
|
||||
|
@ -45,7 +45,7 @@ def test_view_projections(
|
||||
viewpath = str(tmpdir.mkdir('view_{0}'.format(cmd)))
|
||||
view_projection = {
|
||||
'projections': {
|
||||
'all': '${PACKAGE}-${VERSION}'
|
||||
'all': '{name}-{version}'
|
||||
}
|
||||
}
|
||||
projection_file = create_projection_file(tmpdir, view_projection)
|
||||
@ -65,8 +65,8 @@ def test_view_multiple_projections(
|
||||
|
||||
viewpath = str(tmpdir.mkdir('view'))
|
||||
view_projection = s_yaml.syaml_dict(
|
||||
[('extendee', '${PACKAGE}-${COMPILERNAME}'),
|
||||
('all', '${PACKAGE}-${VERSION}')]
|
||||
[('extendee', '{name}-{compiler.name}'),
|
||||
('all', '{name}-{version}')]
|
||||
)
|
||||
|
||||
projection_file = create_projection_file(tmpdir, view_projection)
|
||||
@ -87,8 +87,8 @@ def test_view_multiple_projections_all_first(
|
||||
|
||||
viewpath = str(tmpdir.mkdir('view'))
|
||||
view_projection = s_yaml.syaml_dict(
|
||||
[('all', '${PACKAGE}-${VERSION}'),
|
||||
('extendee', '${PACKAGE}-${COMPILERNAME}')]
|
||||
[('all', '{name}-{version}'),
|
||||
('extendee', '{name}-{compiler.name}')]
|
||||
)
|
||||
|
||||
projection_file = create_projection_file(tmpdir, view_projection)
|
||||
@ -145,7 +145,7 @@ def test_view_extension_projection(
|
||||
install('extension2@1.0')
|
||||
|
||||
viewpath = str(tmpdir.mkdir('view'))
|
||||
view_projection = {'all': '${PACKAGE}-${VERSION}'}
|
||||
view_projection = {'all': '{name}-{version}'}
|
||||
projection_file = create_projection_file(tmpdir, view_projection)
|
||||
view('symlink', viewpath, '--projection-file={0}'.format(projection_file),
|
||||
'extension1@1.0')
|
||||
|
@ -13,7 +13,7 @@ lmod:
|
||||
- CMAKE_PREFIX_PATH
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
|
||||
'platform=test target=x86_64':
|
||||
environment:
|
||||
|
@ -7,7 +7,7 @@ tcl:
|
||||
- CMAKE_PREFIX_PATH
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT': '${PREFIX}'
|
||||
'{name}_ROOT': '{prefix}'
|
||||
|
||||
'platform=test target=x86_64':
|
||||
environment:
|
||||
|
@ -1,8 +1,8 @@
|
||||
enable:
|
||||
- tcl
|
||||
tcl:
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}'
|
||||
- '{name}'
|
||||
- 'intel/14.0.1'
|
||||
|
@ -1,5 +1,5 @@
|
||||
enable:
|
||||
- tcl
|
||||
tcl:
|
||||
# ${OPTIONS} is not allowed in the naming scheme, see #2884
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}-${OPTIONS}'
|
||||
# {variants} is not allowed in the naming scheme, see #2884
|
||||
naming_scheme: '{name}/{version}-{compiler.name}-{variants}'
|
||||
|
@ -7,12 +7,12 @@ tcl:
|
||||
- CMAKE_PREFIX_PATH
|
||||
environment:
|
||||
set:
|
||||
'${PACKAGE}_ROOT_${PREFIX}': '${PREFIX}'
|
||||
'{name}_ROOT_{prefix}': '{prefix}'
|
||||
|
||||
'platform=test target=x86_64':
|
||||
environment:
|
||||
set:
|
||||
FOO_${OPTIONS}: 'foo'
|
||||
FOO_{variants}: 'foo'
|
||||
unset:
|
||||
- BAR
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
enable:
|
||||
- tcl
|
||||
tcl:
|
||||
naming_scheme: '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
||||
naming_scheme: '{name}/{version}-{compiler.name}'
|
||||
all:
|
||||
conflict:
|
||||
- '${PACKAGE}/${COMPILERNAME}'
|
||||
- '{name}/{compiler.name}'
|
||||
|
@ -41,9 +41,9 @@ def test_yaml_directory_layout_parameters(
|
||||
layout_default = YamlDirectoryLayout(str(tmpdir))
|
||||
path_default = layout_default.relative_path_for_spec(spec)
|
||||
assert(path_default == spec.format(
|
||||
"${ARCHITECTURE}/"
|
||||
"${COMPILERNAME}-${COMPILERVER}/"
|
||||
"${PACKAGE}-${VERSION}-${HASH}"))
|
||||
"{architecture}/"
|
||||
"{compiler.name}-{compiler.version}/"
|
||||
"{name}-{version}-{hash}"))
|
||||
|
||||
# Test hash_length parameter works correctly
|
||||
layout_10 = YamlDirectoryLayout(str(tmpdir), hash_len=10)
|
||||
@ -56,7 +56,7 @@ def test_yaml_directory_layout_parameters(
|
||||
|
||||
# Test path_scheme
|
||||
arch, compiler, package7 = path_7.split('/')
|
||||
scheme_package7 = "${PACKAGE}-${VERSION}-${HASH:7}"
|
||||
scheme_package7 = "{name}-{version}-{hash:7}"
|
||||
layout_package7 = YamlDirectoryLayout(str(tmpdir),
|
||||
path_scheme=scheme_package7)
|
||||
path_package7 = layout_package7.relative_path_for_spec(spec)
|
||||
@ -64,7 +64,7 @@ def test_yaml_directory_layout_parameters(
|
||||
assert(package7 == path_package7)
|
||||
|
||||
# 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),
|
||||
path_scheme=arch_scheme_package)
|
||||
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()
|
||||
|
||||
mpileaks_hash, mpileaks_lbl = s.dag_hash(), s.format('$_$/')
|
||||
mpi_hash, mpi_lbl = s['mpi'].dag_hash(), s['mpi'].format('$_$/')
|
||||
mpileaks_hash, mpileaks_lbl = s.dag_hash(), s.format('{name}{/hash:7}')
|
||||
mpi_hash, mpi_lbl = s['mpi'].dag_hash(), s['mpi'].format('{name}{/hash:7}')
|
||||
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 = (
|
||||
s['dyninst'].dag_hash(), s['dyninst'].format('$_$/'))
|
||||
s['dyninst'].dag_hash(), s['dyninst'].format('{name}{/hash:7}'))
|
||||
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 = (
|
||||
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' % (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
|
||||
writer, _ = factory('mpileaks')
|
||||
expected = '${PACKAGE}/${VERSION}-${COMPILERNAME}'
|
||||
expected = '{name}/{version}-{compiler.name}'
|
||||
|
||||
assert writer.conf.naming_scheme == expected
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
from spack.spec import Spec, UnsatisfiableSpecError, SpecError
|
||||
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 MultipleValuesInExclusiveVariantError
|
||||
|
||||
@ -736,28 +737,133 @@ def test_exceptional_paths_for_constructor(self):
|
||||
Spec('libelf foo')
|
||||
|
||||
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.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?)
|
||||
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
|
||||
# Mixed case intentional for testing both
|
||||
package_segments = [("${PACKAGE}", "name"),
|
||||
("${VERSION}", "versions"),
|
||||
("${COMPILER}", "compiler"),
|
||||
("${COMPILERFLAGS}", "compiler_flags"),
|
||||
("${OPTIONS}", "variants"),
|
||||
("${ARCHITECTURE}", "architecture")]
|
||||
("${compiler}", "compiler"),
|
||||
("${compilerflags}", "compiler_flags"),
|
||||
("${options}", "variants"),
|
||||
("${architecture}", "architecture")]
|
||||
|
||||
compiler_segments = [("${COMPILERNAME}", "name"),
|
||||
("${COMPILERVER}", "versions")]
|
||||
compiler_segments = [("${compilername}", "name"),
|
||||
("${compilerver}", "versions")]
|
||||
|
||||
architecture_segments = [("${PLATFORM}", "platform"),
|
||||
("${OS}", "platform_os"),
|
||||
("${OS}", "os"),
|
||||
("${TARGET}", "target")]
|
||||
|
||||
for named_str, prop in package_segments:
|
||||
|
@ -397,7 +397,7 @@ def write_rpath_specs(self):
|
||||
the compiler used to build the executable."""
|
||||
if not self.spec_dir:
|
||||
tty.warn('Could not install specs for {0}.'.format(
|
||||
self.spec.format('$_$@')))
|
||||
self.spec.format('{name}{@version}')))
|
||||
return
|
||||
|
||||
gcc = self.spec['gcc'].command
|
||||
|
@ -67,7 +67,9 @@ def patch(self):
|
||||
add_extra_files(self, self.common, self.assets)
|
||||
# Emit openfoam version immediately, if we resolved the wrong version
|
||||
# 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):
|
||||
"""Generate spack-config.sh file."""
|
||||
|
@ -42,7 +42,9 @@ def patch(self):
|
||||
add_extra_files(self, self.common, self.assets)
|
||||
# Emit openfoam version immediately, if we resolved the wrong version
|
||||
# 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):
|
||||
"""Generate spack-config.sh file."""
|
||||
|
Loading…
Reference in New Issue
Block a user