diff --git a/src/machinable/interface.py b/src/machinable/interface.py index d9b66b3d..3de9e4ee 100644 --- a/src/machinable/interface.py +++ b/src/machinable/interface.py @@ -289,6 +289,17 @@ def push_related(self, key: str, value: "Interface") -> None: self.__related__[key] = value self._relation_cache[key] = True + def is_staged(self): + return self.__model__.uuid[-12:] != "0" * 12 + + def stage(self): + self.__model__.context = context = self.compute_context() + self.__model__.uuid = update_uuid_payload(self.__model__.uuid, context) + + # ensure that configuration and predicate has been computed + assert self.config is not None + self.__model__.predicate = self.compute_predicate() + def is_committed(self) -> bool: from machinable.index import Index @@ -307,12 +318,8 @@ def commit(self) -> Self: # allow on_before_commit to abort return self - self.__model__.context = context = self.compute_context() - self.__model__.uuid = update_uuid_payload(self.__model__.uuid, context) - - # ensure that configuration and predicate has been computed - assert self.config is not None - self.__model__.predicate = self.compute_predicate() + if not self.is_staged(): + self.stage() if self.on_commit() is False: # allow on_commit to abort diff --git a/tests/test_interface.py b/tests/test_interface.py index 0f9df5c2..3ba0f146 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -191,6 +191,11 @@ def test_interface_commit(tmp_storage): with Project("./tests/samples/project"): Interface.make("interface.dummy").commit() + i = Interface() + assert not i.is_staged() + i.commit() + assert i.is_staged() + def tes_interface_save_file(tmp_storage): component = Interface().commit()