mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Swift: make codegen resilient to formatting errors
More in general, the managed renderer flow does things more sensibly in case an exception is thrown: * it will not remove any file * it will drop already written files from the registry, so that codegen won't be skipped for those files during the next run
This commit is contained in:
@@ -103,12 +103,18 @@ class RenderManager(Renderer):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
for f in self._existing - self._skipped - self.written:
|
||||
self._hashes.pop(self._get_path(f), None)
|
||||
f.unlink(missing_ok=True)
|
||||
log.info(f"removed {f.name}")
|
||||
for f in self.written:
|
||||
self._hashes[self._get_path(f)].post = self._hash_file(f)
|
||||
if exc_val is None:
|
||||
for f in self._existing - self._skipped - self.written:
|
||||
self._hashes.pop(self._get_path(f), None)
|
||||
f.unlink(missing_ok=True)
|
||||
log.info(f"removed {f.name}")
|
||||
for f in self.written:
|
||||
self._hashes[self._get_path(f)].post = self._hash_file(f)
|
||||
else:
|
||||
# if an error was encountered, drop already written files from the registry
|
||||
# so that they get the chance to be regenerated again during the next run
|
||||
for f in self.written:
|
||||
self._hashes.pop(self._get_path(f), None)
|
||||
self._dump_registry()
|
||||
|
||||
def _do_write(self, mnemonic: str, contents: str, output: pathlib.Path):
|
||||
|
||||
@@ -192,6 +192,45 @@ def test_managed_render_with_modified_stub_file_not_marked_as_generated(pystache
|
||||
assert_file(registry, "")
|
||||
|
||||
|
||||
class MyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def test_managed_render_exception_drops_written_from_registry(pystache_renderer, sut):
|
||||
data = mock.Mock(spec=("template",))
|
||||
text = "some text"
|
||||
pystache_renderer.render_name.side_effect = (text,)
|
||||
output = paths.swift_dir / "some/output.txt"
|
||||
registry = paths.swift_dir / "a/registry.list"
|
||||
write(output, text)
|
||||
write(registry, "a a a\n"
|
||||
f"some/output.txt whatever {hash(text)}\n"
|
||||
"b b b")
|
||||
|
||||
with pytest.raises(MyError):
|
||||
with sut.manage(generated=(), stubs=(), registry=registry) as renderer:
|
||||
renderer.render(data, output)
|
||||
raise MyError
|
||||
|
||||
assert_file(registry, "a a a\nb b b\n")
|
||||
|
||||
|
||||
def test_managed_render_exception_does_not_erase(pystache_renderer, sut):
|
||||
output = paths.swift_dir / "some/output.txt"
|
||||
stub = paths.swift_dir / "some/stub.txt"
|
||||
registry = paths.swift_dir / "a/registry.list"
|
||||
write(output)
|
||||
write(stub, "// generated bla bla")
|
||||
write(registry)
|
||||
|
||||
with pytest.raises(MyError):
|
||||
with sut.manage(generated=(output,), stubs=(stub,), registry=registry) as renderer:
|
||||
raise MyError
|
||||
|
||||
assert output.is_file()
|
||||
assert stub.is_file()
|
||||
|
||||
|
||||
def test_render_with_extensions(pystache_renderer, sut):
|
||||
data = mock.Mock(spec=("template", "extensions"))
|
||||
data.template = "test_template"
|
||||
|
||||
Reference in New Issue
Block a user