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
|
||||
``\{`` 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.
|
||||
|
||||
literal ``\`` character.
|
||||
|
||||
Args:
|
||||
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
|
||||
|
||||
"""
|
||||
# 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", {})
|
||||
|
||||
@ -4252,250 +4240,6 @@ def write_attribute(spec, attribute, color):
|
||||
formatted_spec = out.getvalue()
|
||||
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):
|
||||
"""Same as format, but color defaults to auto instead of False."""
|
||||
kwargs = kwargs.copy()
|
||||
|
@ -713,52 +713,6 @@ def test_spec_formatting_escapes(self, default_mock_concretization):
|
||||
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()
|
||||
|
||||
# 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")
|
||||
def test_spec_flags_maintain_order(self):
|
||||
# Spack was assembling flags in a manner that could result in
|
||||
|
Loading…
Reference in New Issue
Block a user