mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
05dc27715d
This commit introduces some changes to how the revng pipeline handles serializing to disk. Specificaly: * Pipeline globals (specifically model.yml) are better handled if they are in a subdirectory. They are now saved in the "context" subdirectory. * In python:revng.api the pipeline is serialized whenever there is a non-reproducible change to the state (e.g. binary upload or model change). In the case of analyses this is done conservatively by checking that the diff produced is not empty. * The logic for computing a step's subdirectory has been moved to the pipeline runner, consequently if a step is asked to serialize it will not create any subdirectories. * Functionality for saving a single step/context has been exposed in Pipeline C. * Finally, all path concatenations are now handled by llvm::sys::path::append, for extra os-agnosticism.
65 lines
2.2 KiB
Python
65 lines
2.2 KiB
Python
#
|
|
# This file is distributed under the MIT License. See LICENSE.md for details.
|
|
#
|
|
|
|
from pathlib import Path
|
|
from typing import Dict, Generator, Optional, Union
|
|
|
|
from ._capi import _api, ffi
|
|
from .analysis import Analysis
|
|
from .container import Container, ContainerIdentifier
|
|
from .kind import Kind
|
|
from .utils import make_c_string, make_generator, make_python_string
|
|
|
|
|
|
class Step:
|
|
def __init__(self, step):
|
|
self._step = step
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
name = _api.rp_step_get_name(self._step)
|
|
return make_python_string(name)
|
|
|
|
def save(self, destination_directory: Union[Path, str]):
|
|
dest_dir = Path(destination_directory).resolve()
|
|
_dest_dir = make_c_string(str(dest_dir))
|
|
return _api.rp_step_save(self._step, _dest_dir)
|
|
|
|
def get_parent(self) -> Optional["Step"]:
|
|
_step = _api.rp_step_get_parent(self._step)
|
|
return Step(_step) if _step != ffi.NULL else None
|
|
|
|
def get_container(self, container_identifier: ContainerIdentifier) -> Optional[Container]:
|
|
_container = _api.rp_step_get_container(
|
|
self._step, container_identifier._container_identifier
|
|
)
|
|
return Container(_container, self.name) if _container != ffi.NULL else None
|
|
|
|
def get_artifacts_kind(self) -> Optional[Kind]:
|
|
_kind = _api.rp_step_get_artifacts_kind(self._step)
|
|
return Kind(_kind) if _kind != ffi.NULL else None
|
|
|
|
def get_artifacts_container(self) -> Optional[Container]:
|
|
_container = _api.rp_step_get_artifacts_container(self._step)
|
|
return Container(_container, self.name) if _container != ffi.NULL else None
|
|
|
|
def analyses_count(self) -> int:
|
|
return _api.rp_step_get_analyses_count(self._step)
|
|
|
|
def _get_analysis_from_index(self, idx: int) -> Optional[Analysis]:
|
|
_analysis = _api.rp_step_get_analysis(self._step, idx)
|
|
return Analysis(_analysis) if _analysis != ffi.NULL else None
|
|
|
|
def analyses(self) -> Generator[Analysis, None, None]:
|
|
return make_generator(self.analyses_count(), self._get_analysis_from_index)
|
|
|
|
def as_dict(self) -> Dict[str, str]:
|
|
ret = {"name": self.name}
|
|
|
|
parent = self.get_parent()
|
|
if parent is not None:
|
|
ret["parent"] = parent.name
|
|
|
|
return ret
|