in lib/ramble/spack/spec.py [0:0]
def old_format(self, format_string='$_$@$%@+$+$=', **kwargs):
"""
The format strings you can provide are::
$_ Package name
$. Full package name (with namespace)
$@ Version with '@' prefix
$% Compiler with '%' prefix
$%@ Compiler with '%' prefix & compiler version with '@' prefix
$%+ Compiler with '%' prefix & compiler flags prefixed by name
$%@+ Compiler, compiler version, and compiler flags with same
prefixes as above
$+ Options
$= Architecture prefixed by 'arch='
$/ 7-char prefix of DAG hash with '-' prefix
$$ $
You can also use full-string versions, which elide the prefixes::
${PACKAGE} Package name
${FULLPACKAGE} Full package name (with namespace)
${VERSION} Version
${COMPILER} Full compiler string
${COMPILERNAME} Compiler name
${COMPILERVER} Compiler version
${COMPILERFLAGS} Compiler flags
${OPTIONS} Options
${ARCHITECTURE} Architecture
${PLATFORM} Platform
${OS} Operating System
${TARGET} Target
${SHA1} Dependencies 8-char sha1 prefix
${HASH:len} DAG hash with optional length specifier
${DEP:name:OPTION} Evaluates as OPTION would for self['name']
${SPACK_ROOT} The spack root directory
${SPACK_INSTALL} The default spack install directory,
${SPACK_PREFIX}/opt
${PREFIX} The package prefix
${NAMESPACE} The package namespace
Note these are case-insensitive: for example you can specify either
``${PACKAGE}`` or ``${package}``.
Optionally you can provide a width, e.g. ``$20_`` for a 20-wide name.
Like printf, you can provide '-' for left justification, e.g.
``$-20_`` for a left-justified name.
Anything else is copied verbatim into the output stream.
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
Examples:
The following line:
.. code-block:: python
s = spec.format('$_$@$+')
translates to the name, version, and options of the package, but no
dependencies, arch, or compiler.
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
token_transforms = dict(
(k.upper(), v) for k, v in kwargs.get('transform', {}).items())
length = len(format_string)
out = io.StringIO()
named = escape = compiler = False
named_str = fmt = ''
def write(s, c=None):
f = clr.cescape(s)
if c is not None:
f = color_formats[c] + f + '@.'
clr.cwrite(f, stream=out, color=color)
iterator = enumerate(format_string)
for i, c in iterator:
if escape:
fmt = '%'
if c == '-':
fmt += c
i, c = next(iterator)
while c in '0123456789':
fmt += c
i, c = next(iterator)
fmt += 's'
if c == '_':
name = self.name if self.name else ''
out.write(fmt % name)
elif c == '.':
name = self.fullname if self.fullname else ''
out.write(fmt % name)
elif c == '@':
if self.versions and self.versions != _any_version:
write(fmt % (c + str(self.versions)), c)
elif c == '%':
if self.compiler:
write(fmt % (c + str(self.compiler.name)), c)
compiler = True
elif c == '+':
if self.variants:
write(fmt % str(self.variants), c)
elif c == '=':
if self.architecture and str(self.architecture):
a_str = ' arch' + c + str(self.architecture) + ' '
write(fmt % (a_str), c)
elif c == '/':
out.write('/' + fmt % (self.dag_hash(7)))
elif c == '$':
if fmt != '%s':
raise ValueError("Can't use format width with $$.")
out.write('$')
elif c == '{':
named = True
named_str = ''
escape = False
elif compiler:
if c == '@':
if (self.compiler and self.compiler.versions and
self.compiler.versions != _any_version):
write(c + str(self.compiler.versions), '%')
elif c == '+':
if self.compiler_flags:
write(fmt % str(self.compiler_flags), '%')
compiler = False
elif c == '$':
escape = True
compiler = False
else:
out.write(c)
compiler = False
elif named:
if not c == '}':
if i == length - 1:
raise ValueError("Error: unterminated ${ in format:"
"'%s'" % format_string)
named_str += c
continue
named_str = named_str.upper()
# Retrieve the token transformation from the dictionary.
#
# The default behavior is to leave the string unchanged
# (`lambda x: x` is the identity function)
transform = token_transforms.get(named_str, lambda s, x: x)
if named_str == 'PACKAGE':
name = self.name if self.name else ''
write(fmt % transform(self, name))
elif named_str == 'FULLPACKAGE':
name = self.fullname if self.fullname else ''
write(fmt % transform(self, name))
elif named_str == 'VERSION':
if self.versions and self.versions != _any_version:
write(fmt % transform(self, str(self.versions)), '@')
elif named_str == 'COMPILER':
if self.compiler:
write(fmt % transform(self, self.compiler), '%')
elif named_str == 'COMPILERNAME':
if self.compiler:
write(fmt % transform(self, self.compiler.name), '%')
elif named_str in ['COMPILERVER', 'COMPILERVERSION']:
if self.compiler:
write(
fmt % transform(self, self.compiler.versions),
'%'
)
elif named_str == 'COMPILERFLAGS':
if self.compiler:
write(
fmt % transform(self, str(self.compiler_flags)),
'%'
)
elif named_str == 'OPTIONS':
if self.variants:
write(fmt % transform(self, str(self.variants)), '+')
elif named_str in ["ARCHITECTURE", "PLATFORM", "TARGET", "OS"]:
if self.architecture and str(self.architecture):
if named_str == "ARCHITECTURE":
write(
fmt % transform(self, str(self.architecture)),
'='
)
elif named_str == "PLATFORM":
platform = str(self.architecture.platform)
write(fmt % transform(self, platform), '=')
elif named_str == "OS":
operating_sys = str(self.architecture.os)
write(fmt % transform(self, operating_sys), '=')
elif named_str == "TARGET":
target = str(self.architecture.target)
write(fmt % transform(self, target), '=')
elif named_str == 'SHA1':
if self.dependencies:
out.write(fmt % transform(self, str(self.dag_hash(7))))
elif named_str == 'SPACK_ROOT':
out.write(fmt % transform(self, spack.paths.prefix))
elif named_str == 'SPACK_INSTALL':
out.write(fmt % transform(self, spack.store.root))
elif named_str == 'PREFIX':
out.write(fmt % transform(self, self.prefix))
elif named_str.startswith('HASH'):
if named_str.startswith('HASH:'):
_, hashlen = named_str.split(':')
hashlen = int(hashlen)
else:
hashlen = None
out.write(fmt % (self.dag_hash(hashlen)))
elif named_str == 'NAMESPACE':
out.write(fmt % transform(self, self.namespace))
elif named_str.startswith('DEP:'):
_, dep_name, dep_option = named_str.lower().split(':', 2)
dep_spec = self[dep_name]
out.write(fmt % (dep_spec.format('${%s}' % dep_option)))
named = False
elif c == '$':
escape = True
if i == length - 1:
raise ValueError("Error: unterminated $ in format: '%s'"
% format_string)
else:
out.write(c)
result = out.getvalue()
return result