Remove the old spec format in configuration (#37425)
The format was deprecated in v0.15
This commit is contained in:
parent
e6d37b3b61
commit
95e61f2fdf
@ -4080,15 +4080,7 @@ def format(self, format_string=default_format, **kwargs):
|
|||||||
|
|
||||||
Spec format strings use ``\`` as the escape character. Use
|
Spec format strings use ``\`` as the escape character. Use
|
||||||
``\{`` and ``\}`` for literal braces, and ``\\`` for the
|
``\{`` and ``\}`` for literal braces, and ``\\`` for the
|
||||||
literal ``\`` character. Also use ``\$`` for the literal ``$``
|
literal ``\`` character.
|
||||||
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:
|
Args:
|
||||||
format_string (str): string containing the format to be expanded
|
format_string (str): string containing the format to be expanded
|
||||||
@ -4099,10 +4091,6 @@ def format(self, format_string=default_format, **kwargs):
|
|||||||
that accepts a string and returns another one
|
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)
|
color = kwargs.get("color", False)
|
||||||
transform = kwargs.get("transform", {})
|
transform = kwargs.get("transform", {})
|
||||||
|
|
||||||
@ -4252,250 +4240,6 @@ def write_attribute(spec, attribute, color):
|
|||||||
formatted_spec = out.getvalue()
|
formatted_spec = out.getvalue()
|
||||||
return formatted_spec.strip()
|
return formatted_spec.strip()
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
warnings.warn(
|
|
||||||
"Using the old Spec.format method."
|
|
||||||
" This method was deprecated in Spack v0.15 and will be removed in Spack v0.20"
|
|
||||||
)
|
|
||||||
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
|
|
||||||
|
|
||||||
def cformat(self, *args, **kwargs):
|
def cformat(self, *args, **kwargs):
|
||||||
"""Same as format, but color defaults to auto instead of False."""
|
"""Same as format, but color defaults to auto instead of False."""
|
||||||
kwargs = kwargs.copy()
|
kwargs = kwargs.copy()
|
||||||
|
@ -713,52 +713,6 @@ def test_spec_formatting_escapes(self, default_mock_concretization):
|
|||||||
with pytest.raises(SpecFormatStringError):
|
with pytest.raises(SpecFormatStringError):
|
||||||
spec.format(fmt_str)
|
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()
|
|
||||||
|
|
||||||
# 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_segments = [("${compilername}", "name"), ("${compilerver}", "versions")]
|
|
||||||
|
|
||||||
architecture_segments = [
|
|
||||||
("${PLATFORM}", "platform"),
|
|
||||||
("${OS}", "os"),
|
|
||||||
("${TARGET}", "target"),
|
|
||||||
]
|
|
||||||
|
|
||||||
for named_str, prop in package_segments:
|
|
||||||
expected = getattr(spec, prop, "")
|
|
||||||
actual = spec.format(named_str)
|
|
||||||
assert str(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
|
|
||||||
|
|
||||||
arch = spec.architecture
|
|
||||||
for named_str, prop in architecture_segments:
|
|
||||||
expected = getattr(arch, prop, "")
|
|
||||||
actual = spec.format(named_str)
|
|
||||||
assert str(expected) == actual
|
|
||||||
|
|
||||||
@pytest.mark.regression("9908")
|
@pytest.mark.regression("9908")
|
||||||
def test_spec_flags_maintain_order(self):
|
def test_spec_flags_maintain_order(self):
|
||||||
# Spack was assembling flags in a manner that could result in
|
# Spack was assembling flags in a manner that could result in
|
||||||
|
Loading…
Reference in New Issue
Block a user