Phillip Smyth pushed to branch mandatory_suffix at BuildStream / buildstream
Commits:
-
83394c98
by Phillip Smyth at 2018-11-27T15:07:19Z
-
9e2941b3
by Phillip Smyth at 2018-11-27T15:07:28Z
-
e632fd94
by Phillip Smyth at 2018-11-27T15:07:28Z
-
79b0ed8c
by Phillip Smyth at 2018-11-27T15:07:29Z
-
c95919da
by Phillip Smyth at 2018-11-27T15:07:29Z
-
ab18dc12
by Phillip Smyth at 2018-11-27T15:07:29Z
-
f0e50898
by Phillip Smyth at 2018-11-27T15:07:29Z
14 changed files:
- NEWS
- buildstream/_context.py
- buildstream/_frontend/cli.py
- buildstream/_loader/loadelement.py
- buildstream/_loader/loader.py
- buildstream/_project.py
- buildstream/plugin.py
- tests/completions/completions.py
- + tests/frontend/.buildcheckout.py.swp
- tests/frontend/buildcheckout.py
- + tests/frontend/project/elements/target.foo
- + tests/frontend/project/elements/target2.bst
- tests/frontend/project/project.conf
- tests/integration/source-determinism.py
Changes:
| ... | ... | @@ -2,6 +2,10 @@ |
| 2 | 2 |
buildstream 1.3.1
|
| 3 | 3 |
=================
|
| 4 | 4 |
|
| 5 |
+ o BREAKING CHANGE: Attempting to use an element that does not have the `.bst`
|
|
| 6 |
+ extension, will result in an error message.
|
|
| 7 |
+ All elements must now be suffixed with `.bst`
|
|
| 8 |
+ |
|
| 5 | 9 |
o BREAKING CHANGE: The 'manual' element lost its default 'MAKEFLAGS' and 'V'
|
| 6 | 10 |
environment variables. There is already a 'make' element with the same
|
| 7 | 11 |
variables. Note that this is a breaking change, it will require users to
|
| ... | ... | @@ -27,7 +27,7 @@ from . import _cachekey |
| 27 | 27 |
from . import _signals
|
| 28 | 28 |
from . import _site
|
| 29 | 29 |
from . import _yaml
|
| 30 |
-from ._exceptions import LoadError, LoadErrorReason, BstError
|
|
| 30 |
+from ._exceptions import LoadError, LoadErrorReason, BstError, PluginError
|
|
| 31 | 31 |
from ._message import Message, MessageType
|
| 32 | 32 |
from ._profile import Topics, profile_start, profile_end
|
| 33 | 33 |
from ._artifactcache import ArtifactCache
|
| ... | ... | @@ -142,6 +142,37 @@ class Context(): |
| 142 | 142 |
self._log_handle = None
|
| 143 | 143 |
self._log_filename = None
|
| 144 | 144 |
|
| 145 |
+ # Print a warning message, checks warning_token against project configuration
|
|
| 146 |
+ #
|
|
| 147 |
+ # Args:
|
|
| 148 |
+ # project (Project): The related project
|
|
| 149 |
+ # brief (str): The brief message
|
|
| 150 |
+ # detail (str): An optional detailed message, can be multiline output
|
|
| 151 |
+ # warning_token (str): An optional configurable warning assosciated with this warning,
|
|
| 152 |
+ # this will cause PluginError to be raised if this warning is configured as fatal.
|
|
| 153 |
+ # (*Since 1.4*)
|
|
| 154 |
+ #
|
|
| 155 |
+ # Raises:
|
|
| 156 |
+ # (:class:`.PluginError`): When warning_token is considered fatal by the project configuration
|
|
| 157 |
+ #
|
|
| 158 |
+ def warn(self, project, plugin, brief, *, detail=None, warning_token=None):
|
|
| 159 |
+ # TODO _prefix_warning should probably move somewhere else
|
|
| 160 |
+ from .plugin import _prefix_warning
|
|
| 161 |
+ if warning_token:
|
|
| 162 |
+ warning_token = _prefix_warning(plugin, warning_token)
|
|
| 163 |
+ brief = "[{}]: {}".format(warning_token, brief)
|
|
| 164 |
+ |
|
| 165 |
+ if project._warning_is_fatal(warning_token):
|
|
| 166 |
+ detail = detail if detail else ""
|
|
| 167 |
+ raise PluginError(message="{}\n{}".format(brief, detail), reason=warning_token)
|
|
| 168 |
+ |
|
| 169 |
+ unique_id = None
|
|
| 170 |
+ if plugin:
|
|
| 171 |
+ unique_id = plugin._get_unique_id()
|
|
| 172 |
+ |
|
| 173 |
+ message = Message(unique_id, MessageType.WARN, brief, detail=detail)
|
|
| 174 |
+ self.message(message)
|
|
| 175 |
+ |
|
| 145 | 176 |
# load()
|
| 146 | 177 |
#
|
| 147 | 178 |
# Loads the configuration files
|
| ... | ... | @@ -109,7 +109,11 @@ def complete_target(args, incomplete): |
| 109 | 109 |
if element_directory:
|
| 110 | 110 |
base_directory = os.path.join(base_directory, element_directory)
|
| 111 | 111 |
|
| 112 |
- return complete_path("File", incomplete, base_directory=base_directory)
|
|
| 112 |
+ complete_list = []
|
|
| 113 |
+ for p in complete_path("File", incomplete, base_directory=base_directory):
|
|
| 114 |
+ if p.endswith(".bst ") or p.endswith("/") or p.endswith(".conf "):
|
|
| 115 |
+ complete_list.append(p)
|
|
| 116 |
+ return complete_list
|
|
| 113 | 117 |
|
| 114 | 118 |
|
| 115 | 119 |
def override_completions(cmd, cmd_param, args, incomplete):
|
| ... | ... | @@ -145,11 +145,14 @@ def _extract_depends_from_node(node, *, key=None): |
| 145 | 145 |
|
| 146 | 146 |
depends = _yaml.node_get(node, list, key, default_value=[])
|
| 147 | 147 |
output_deps = []
|
| 148 |
+ invalid_elements = []
|
|
| 148 | 149 |
|
| 149 | 150 |
for index, dep in enumerate(depends):
|
| 150 | 151 |
dep_provenance = _yaml.node_get_provenance(node, key=key, indices=[index])
|
| 151 | 152 |
|
| 152 | 153 |
if isinstance(dep, str):
|
| 154 |
+ if not dep.endswith(".bst"):
|
|
| 155 |
+ invalid_elements.append(dep)
|
|
| 153 | 156 |
dependency = Dependency(dep, provenance=dep_provenance, dep_type=default_dep_type)
|
| 154 | 157 |
|
| 155 | 158 |
elif isinstance(dep, Mapping):
|
| ... | ... | @@ -97,6 +97,7 @@ class Loader(): |
| 97 | 97 |
# Returns: The toplevel LoadElement
|
| 98 | 98 |
def load(self, targets, rewritable=False, ticker=None, fetch_subprojects=False):
|
| 99 | 99 |
|
| 100 |
+ invalid_elements = []
|
|
| 100 | 101 |
for filename in targets:
|
| 101 | 102 |
if os.path.isabs(filename):
|
| 102 | 103 |
# XXX Should this just be an assertion ?
|
| ... | ... | @@ -106,6 +107,18 @@ class Loader(): |
| 106 | 107 |
"path to the base project directory: {}"
|
| 107 | 108 |
.format(filename, self._basedir))
|
| 108 | 109 |
|
| 110 |
+ if not filename.endswith(".bst") and not filename.endswith("/") and not filename.endswith(".conf"):
|
|
| 111 |
+ invalid_elements.append(filename)
|
|
| 112 |
+ |
|
| 113 |
+ if invalid_elements:
|
|
| 114 |
+ # TODO CoreWarnings should probably move somewhere else
|
|
| 115 |
+ from ..plugin import CoreWarnings
|
|
| 116 |
+ |
|
| 117 |
+ self._context.warn(self.project, None,
|
|
| 118 |
+ "Target elements '{}' do not have expected file extension `.bst` "
|
|
| 119 |
+ "Improperly named elements will not be discoverable by commands"
|
|
| 120 |
+ .format(invalid_elements),
|
|
| 121 |
+ warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
|
|
| 109 | 122 |
# First pass, recursively load files and populate our table of LoadElements
|
| 110 | 123 |
#
|
| 111 | 124 |
deps = []
|
| ... | ... | @@ -124,6 +137,15 @@ class Loader(): |
| 124 | 137 |
deps.append(Dependency(name, junction=junction))
|
| 125 | 138 |
profile_end(Topics.LOAD_PROJECT, target)
|
| 126 | 139 |
|
| 140 |
+ if invalid_elements:
|
|
| 141 |
+ # TODO CoreWarnings should probably move somewhere else
|
|
| 142 |
+ from ..plugin import CoreWarnings
|
|
| 143 |
+ |
|
| 144 |
+ self._context.warn(self.project, None,
|
|
| 145 |
+ "Target elements '{}' do not have expected file extension `.bst` "
|
|
| 146 |
+ "Improperly named elements will not be discoverable by commands"
|
|
| 147 |
+ .format(invalid_elements),
|
|
| 148 |
+ warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
|
|
| 127 | 149 |
#
|
| 128 | 150 |
# Now that we've resolve the dependencies, scan them for circular dependencies
|
| 129 | 151 |
#
|
| ... | ... | @@ -214,7 +236,7 @@ class Loader(): |
| 214 | 236 |
# Returns:
|
| 215 | 237 |
# (LoadElement): A loaded LoadElement
|
| 216 | 238 |
#
|
| 217 |
- def _load_file(self, filename, rewritable, ticker, fetch_subprojects, yaml_cache=None):
|
|
| 239 |
+ def _load_file(self, filename, rewritable, ticker, fetch_subprojects, yaml_cache=None, suffix_check=False):
|
|
| 218 | 240 |
|
| 219 | 241 |
# Silently ignore already loaded files
|
| 220 | 242 |
if filename in self._elements:
|
| ... | ... | @@ -270,6 +292,12 @@ class Loader(): |
| 270 | 292 |
|
| 271 | 293 |
# Load all dependency files for the new LoadElement
|
| 272 | 294 |
for dep in element.deps:
|
| 295 |
+ print("DEP: {}".format(dep.name))
|
|
| 296 |
+ invalid_elements = []
|
|
| 297 |
+ if not dep.name.endswith(".bst") and not dep.name.endswith("/") and not dep.name.endswith(".conf"):
|
|
| 298 |
+ invalid_elements.append(dep.name)
|
|
| 299 |
+ continue
|
|
| 300 |
+ |
|
| 273 | 301 |
if dep.junction:
|
| 274 | 302 |
self._load_file(dep.junction, rewritable, ticker, fetch_subprojects, yaml_cache)
|
| 275 | 303 |
loader = self._get_loader(dep.junction, rewritable=rewritable, ticker=ticker,
|
| ... | ... | @@ -278,12 +306,19 @@ class Loader(): |
| 278 | 306 |
loader = self
|
| 279 | 307 |
|
| 280 | 308 |
dep_element = loader._load_file(dep.name, rewritable, ticker, fetch_subprojects, yaml_cache)
|
| 281 |
- |
|
| 282 | 309 |
if _yaml.node_get(dep_element.node, str, Symbol.KIND) == 'junction':
|
| 283 | 310 |
raise LoadError(LoadErrorReason.INVALID_DATA,
|
| 284 | 311 |
"{}: Cannot depend on junction"
|
| 285 | 312 |
.format(dep.provenance))
|
| 286 |
- |
|
| 313 |
+ if invalid_elements:
|
|
| 314 |
+ # TODO CoreWarnings should probably move somewhere else
|
|
| 315 |
+ from ..plugin import CoreWarnings
|
|
| 316 |
+ |
|
| 317 |
+ self._context.warn(self.project, None,
|
|
| 318 |
+ "Target elements '{}' do not have expected file extension `.bst` "
|
|
| 319 |
+ "Improperly named elements will not be discoverable by commands"
|
|
| 320 |
+ .format(invalid_elements),
|
|
| 321 |
+ warning_token=CoreWarnings.BAD_ELEMENT_SUFFIX)
|
|
| 287 | 322 |
return element
|
| 288 | 323 |
|
| 289 | 324 |
# _check_circular_deps():
|
| ... | ... | @@ -516,7 +551,7 @@ class Loader(): |
| 516 | 551 |
return loader
|
| 517 | 552 |
|
| 518 | 553 |
try:
|
| 519 |
- self._load_file(filename, rewritable, ticker, fetch_subprojects)
|
|
| 554 |
+ self._load_file(filename, rewritable, ticker, fetch_subprojects, suffix_check=True)
|
|
| 520 | 555 |
except LoadError as e:
|
| 521 | 556 |
if e.reason != LoadErrorReason.MISSING_FILE:
|
| 522 | 557 |
# other load error
|
| ... | ... | @@ -621,15 +656,24 @@ class Loader(): |
| 621 | 656 |
# - (str): name of the element
|
| 622 | 657 |
# - (Loader): loader for sub-project
|
| 623 | 658 |
#
|
| 624 |
- def _parse_name(self, name, rewritable, ticker, fetch_subprojects=False):
|
|
| 659 |
+ def _parse_name(self, name, rewritable, ticker, fetch_subprojects=False, suffix_check=False):
|
|
| 625 | 660 |
# We allow to split only once since deep junctions names are forbidden.
|
| 626 | 661 |
# Users who want to refer to elements in sub-sub-projects are required
|
| 627 | 662 |
# to create junctions on the top level project.
|
| 628 | 663 |
junction_path = name.rsplit(':', 1)
|
| 629 | 664 |
if len(junction_path) == 1:
|
| 665 |
+ if suffix_check:
|
|
| 666 |
+ return None, junction_path[-1], self, "Pass"
|
|
| 630 | 667 |
return None, junction_path[-1], self
|
| 631 | 668 |
else:
|
| 632 | 669 |
self._load_file(junction_path[-2], rewritable, ticker, fetch_subprojects)
|
| 633 | 670 |
loader = self._get_loader(junction_path[-2], rewritable=rewritable, ticker=ticker,
|
| 634 | 671 |
fetch_subprojects=fetch_subprojects)
|
| 672 |
+ if suffix_check:
|
|
| 673 |
+ if not junction_path[-2].endswith(".bst") and not junction_path[-2].endswith("/") and not junction_path[-2].endswith(".conf"):
|
|
| 674 |
+ result = "Fail"
|
|
| 675 |
+ else:
|
|
| 676 |
+ result = "Pass"
|
|
| 677 |
+ return junction_path[-2], junction_path[-1], loader, result
|
|
| 678 |
+ |
|
| 635 | 679 |
return junction_path[-2], junction_path[-1], loader
|
| ... | ... | @@ -445,6 +445,9 @@ class Project(): |
| 445 | 445 |
self.config.options = OptionPool(self.element_path)
|
| 446 | 446 |
self.first_pass_config.options = OptionPool(self.element_path)
|
| 447 | 447 |
|
| 448 |
+ # Early initialise fatal warnings
|
|
| 449 |
+ self._fatal_warnings = _yaml.node_get(pre_config_node, list, 'fatal-warnings', default_value=[])
|
|
| 450 |
+ |
|
| 448 | 451 |
self.loader = Loader(self._context, self,
|
| 449 | 452 |
parent=parent_loader,
|
| 450 | 453 |
tempdir=tempdir)
|
| ... | ... | @@ -492,28 +492,8 @@ class Plugin(): |
| 492 | 492 |
self.__message(MessageType.INFO, brief, detail=detail)
|
| 493 | 493 |
|
| 494 | 494 |
def warn(self, brief, *, detail=None, warning_token=None):
|
| 495 |
- """Print a warning message, checks warning_token against project configuration
|
|
| 496 |
- |
|
| 497 |
- Args:
|
|
| 498 |
- brief (str): The brief message
|
|
| 499 |
- detail (str): An optional detailed message, can be multiline output
|
|
| 500 |
- warning_token (str): An optional configurable warning assosciated with this warning,
|
|
| 501 |
- this will cause PluginError to be raised if this warning is configured as fatal.
|
|
| 502 |
- (*Since 1.4*)
|
|
| 503 |
- |
|
| 504 |
- Raises:
|
|
| 505 |
- (:class:`.PluginError`): When warning_token is considered fatal by the project configuration
|
|
| 506 |
- """
|
|
| 507 |
- if warning_token:
|
|
| 508 |
- warning_token = _prefix_warning(self, warning_token)
|
|
| 509 |
- brief = "[{}]: {}".format(warning_token, brief)
|
|
| 510 |
- project = self._get_project()
|
|
| 511 |
- |
|
| 512 |
- if project._warning_is_fatal(warning_token):
|
|
| 513 |
- detail = detail if detail else ""
|
|
| 514 |
- raise PluginError(message="{}\n{}".format(brief, detail), reason=warning_token)
|
|
| 515 |
- |
|
| 516 |
- self.__message(MessageType.WARN, brief=brief, detail=detail)
|
|
| 495 |
+ context = self._get_context()
|
|
| 496 |
+ context.warn(self._get_project(), self, brief, detail=detail, warning_token=warning_token)
|
|
| 517 | 497 |
|
| 518 | 498 |
def log(self, brief, *, detail=None):
|
| 519 | 499 |
"""Log a message into the plugin's log file
|
| ... | ... | @@ -784,6 +764,12 @@ class CoreWarnings(): |
| 784 | 764 |
which is found to be invalid based on the configured track
|
| 785 | 765 |
"""
|
| 786 | 766 |
|
| 767 |
+ BAD_ELEMENT_SUFFIX = "bad-element-suffix"
|
|
| 768 |
+ """
|
|
| 769 |
+ This warning will be produced when an element whose name doesn not end in .bst
|
|
| 770 |
+ is referenced either on the command line or by another element
|
|
| 771 |
+ """
|
|
| 772 |
+ |
|
| 787 | 773 |
|
| 788 | 774 |
__CORE_WARNINGS = [
|
| 789 | 775 |
value
|
| ... | ... | @@ -66,6 +66,13 @@ PROJECT_ELEMENTS = [ |
| 66 | 66 |
"target.bst"
|
| 67 | 67 |
]
|
| 68 | 68 |
|
| 69 |
+INVALID_ELEMENTS = [
|
|
| 70 |
+ "target.foo"
|
|
| 71 |
+ "target.bst.bar"
|
|
| 72 |
+]
|
|
| 73 |
+ |
|
| 74 |
+MIXED_ELEMENTS = PROJECT_ELEMENTS + INVALID_ELEMENTS
|
|
| 75 |
+ |
|
| 69 | 76 |
|
| 70 | 77 |
def assert_completion(cli, cmd, word_idx, expected, cwd=None):
|
| 71 | 78 |
result = cli.run(cwd=cwd, env={
|
| ... | ... | @@ -85,6 +92,24 @@ def assert_completion(cli, cmd, word_idx, expected, cwd=None): |
| 85 | 92 |
assert words == expected
|
| 86 | 93 |
|
| 87 | 94 |
|
| 95 |
+def assert_completion_failed(cli, cmd, word_idx, expected, cwd=None):
|
|
| 96 |
+ result = cli.run(cwd=cwd, env={
|
|
| 97 |
+ '_BST_COMPLETION': 'complete',
|
|
| 98 |
+ 'COMP_WORDS': cmd,
|
|
| 99 |
+ 'COMP_CWORD': str(word_idx)
|
|
| 100 |
+ })
|
|
| 101 |
+ words = []
|
|
| 102 |
+ if result.output:
|
|
| 103 |
+ words = result.output.splitlines()
|
|
| 104 |
+ |
|
| 105 |
+ # The order is meaningless, bash will
|
|
| 106 |
+ # take the results and order it by its
|
|
| 107 |
+ # own little heuristics
|
|
| 108 |
+ words = sorted(words)
|
|
| 109 |
+ expected = sorted(expected)
|
|
| 110 |
+ assert words != expected
|
|
| 111 |
+ |
|
| 112 |
+ |
|
| 88 | 113 |
@pytest.mark.parametrize("cmd,word_idx,expected", [
|
| 89 | 114 |
('bst', 0, []),
|
| 90 | 115 |
('bst ', 1, MAIN_COMMANDS),
|
| ... | ... | @@ -226,6 +251,19 @@ def test_argument_element(datafiles, cli, project, cmd, word_idx, expected, subd |
| 226 | 251 |
assert_completion(cli, cmd, word_idx, expected, cwd=cwd)
|
| 227 | 252 |
|
| 228 | 253 |
|
| 254 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 255 |
+@pytest.mark.parametrize("project,cmd,word_idx,expected,subdir", [
|
|
| 256 |
+ |
|
| 257 |
+ # When element has invalid suffix
|
|
| 258 |
+ ('project', 'bst --directory ../ show ', 4, [e + ' ' for e in MIXED_ELEMENTS], 'files')
|
|
| 259 |
+])
|
|
| 260 |
+def test_argument_element_invalid(datafiles, cli, project, cmd, word_idx, expected, subdir):
|
|
| 261 |
+ cwd = os.path.join(str(datafiles), project)
|
|
| 262 |
+ if subdir:
|
|
| 263 |
+ cwd = os.path.join(cwd, subdir)
|
|
| 264 |
+ assert_completion_failed(cli, cmd, word_idx, expected, cwd=cwd)
|
|
| 265 |
+ |
|
| 266 |
+ |
|
| 229 | 267 |
@pytest.mark.parametrize("cmd,word_idx,expected", [
|
| 230 | 268 |
('bst he', 1, ['help ']),
|
| 231 | 269 |
('bst help ', 2, MAIN_COMMANDS),
|
No preview for this file type
| ... | ... | @@ -60,9 +60,34 @@ def test_build_checkout(datafiles, cli, strict, hardlinks): |
| 60 | 60 |
assert os.path.exists(filename)
|
| 61 | 61 |
|
| 62 | 62 |
|
| 63 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 64 |
+@pytest.mark.parametrize("strict,hardlinks", [
|
|
| 65 |
+ ("non-strict", "hardlinks"),
|
|
| 66 |
+])
|
|
| 67 |
+def test_build_invalid_suffix(datafiles, cli, strict, hardlinks):
|
|
| 68 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
| 69 |
+ checkout = os.path.join(cli.directory, 'checkout')
|
|
| 70 |
+ |
|
| 71 |
+ result = cli.run(project=project, args=strict_args(['build', 'target.foo'], strict))
|
|
| 72 |
+ result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
|
|
| 73 |
+ |
|
| 74 |
+ |
|
| 75 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 76 |
+@pytest.mark.parametrize("strict,hardlinks", [
|
|
| 77 |
+ ("non-strict", "hardlinks"),
|
|
| 78 |
+])
|
|
| 79 |
+def test_build_invalid_suffix_dep(datafiles, cli, strict, hardlinks):
|
|
| 80 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
| 81 |
+ checkout = os.path.join(cli.directory, 'checkout')
|
|
| 82 |
+ |
|
| 83 |
+ # target2.bst depends on an element called target.foo
|
|
| 84 |
+ result = cli.run(project=project, args=strict_args(['build', 'target2.bst'], strict))
|
|
| 85 |
+ result.assert_main_error(ErrorDomain.PLUGIN, "bad-element-suffix")
|
|
| 86 |
+ |
|
| 87 |
+ |
|
| 63 | 88 |
@pytest.mark.datafiles(DATA_DIR)
|
| 64 | 89 |
@pytest.mark.parametrize("deps", [("run"), ("none")])
|
| 65 |
-def test_build_checkout_deps(datafiles, cli, deps):
|
|
| 90 |
+def test_build_checkoue_deps(datafiles, cli, deps):
|
|
| 66 | 91 |
project = os.path.join(datafiles.dirname, datafiles.basename)
|
| 67 | 92 |
checkout = os.path.join(cli.directory, 'checkout')
|
| 68 | 93 |
|
| 1 |
+kind: stack
|
|
| 2 |
+description: |
|
|
| 3 |
+ |
|
| 4 |
+ Main stack target for the bst build test
|
| 1 |
+kind: stack
|
|
| 2 |
+description: |
|
|
| 3 |
+ |
|
| 4 |
+ Main stack target for the bst build test
|
|
| 5 |
+ |
|
| 6 |
+depends:
|
|
| 7 |
+- target.foo
|
| ... | ... | @@ -2,3 +2,6 @@ |
| 2 | 2 |
name: test
|
| 3 | 3 |
|
| 4 | 4 |
element-path: elements
|
| 5 |
+ |
|
| 6 |
+fatal-warnings:
|
|
| 7 |
+- bad-element-suffix
|
| ... | ... | @@ -33,7 +33,7 @@ def create_test_directory(*path, mode=0o644): |
| 33 | 33 |
@pytest.mark.skipif(IS_LINUX and not HAVE_BWRAP, reason='Only available with bubblewrap on Linux')
|
| 34 | 34 |
def test_deterministic_source_umask(cli, tmpdir, datafiles, kind, integration_cache):
|
| 35 | 35 |
project = str(datafiles)
|
| 36 |
- element_name = 'list'
|
|
| 36 |
+ element_name = 'list.bst'
|
|
| 37 | 37 |
element_path = os.path.join(project, 'elements', element_name)
|
| 38 | 38 |
repodir = os.path.join(str(tmpdir), 'repo')
|
| 39 | 39 |
sourcedir = os.path.join(project, 'source')
|
| ... | ... | @@ -108,7 +108,7 @@ def test_deterministic_source_local(cli, tmpdir, datafiles, integration_cache): |
| 108 | 108 |
"""Only user rights should be considered for local source.
|
| 109 | 109 |
"""
|
| 110 | 110 |
project = str(datafiles)
|
| 111 |
- element_name = 'test'
|
|
| 111 |
+ element_name = 'test.bst'
|
|
| 112 | 112 |
element_path = os.path.join(project, 'elements', element_name)
|
| 113 | 113 |
sourcedir = os.path.join(project, 'source')
|
| 114 | 114 |
|
