99from copy import deepcopy
1010from typing import Dict , Generator , Optional , Tuple
1111
12- from tuf .api .metadata import Metadata , MetaFile , Signed
12+ from tuf .api .metadata import (
13+ Metadata ,
14+ MetaFile ,
15+ Root ,
16+ Signed ,
17+ Snapshot ,
18+ Targets ,
19+ Timestamp ,
20+ )
1321
1422logger = logging .getLogger (__name__ )
1523
@@ -57,8 +65,9 @@ def close(self, role: str, md: Metadata) -> None:
5765 def targets_infos (self ) -> Dict [str , MetaFile ]:
5866 """Returns the MetaFiles for current targets metadatas
5967
60- This property is used by snapshot() to update Snapshot.meta: Repository
61- implementations should override this property to enable snapshot().
68+ This property is used by do_snapshot() to update Snapshot.meta:
69+ Repository implementations should override this property to enable
70+ do_snapshot().
6271
6372 Note that there is a difference between this return value and
6473 Snapshot.meta: This dictionary reflects the targets metadata that
@@ -71,9 +80,9 @@ def targets_infos(self) -> Dict[str, MetaFile]:
7180 def snapshot_info (self ) -> MetaFile :
7281 """Returns the MetaFile for current snapshot metadata
7382
74- This property is used by timestamp () to update Timestamp.meta:
83+ This property is used by do_timestamp () to update Timestamp.meta:
7584 Repository implementations should override this property to enable
76- timestamp ().
85+ do_timestamp ().
7786 """
7887 raise NotImplementedError
7988
@@ -94,7 +103,71 @@ def edit(self, role: str) -> Generator[Signed, None, None]:
94103 yield md .signed
95104 self .close (role , md )
96105
97- def snapshot (self , force : bool = False ) -> Tuple [bool , Dict [str , MetaFile ]]:
106+ @contextmanager
107+ def edit_root (self ) -> Generator [Root , None , None ]:
108+ """Context manager for editing root metadata. See edit()"""
109+ with self .edit (Root .type ) as root :
110+ if not isinstance (root , Root ):
111+ raise RuntimeError ("Unexpected root type" )
112+ yield root
113+
114+ @contextmanager
115+ def edit_timestamp (self ) -> Generator [Timestamp , None , None ]:
116+ """Context manager for editing timestamp metadata. See edit()"""
117+ with self .edit (Timestamp .type ) as timestamp :
118+ if not isinstance (timestamp , Timestamp ):
119+ raise RuntimeError ("Unexpected timestamp type" )
120+ yield timestamp
121+
122+ @contextmanager
123+ def edit_snapshot (self ) -> Generator [Snapshot , None , None ]:
124+ """Context manager for editing snapshot metadata. See edit()"""
125+ with self .edit (Snapshot .type ) as snapshot :
126+ if not isinstance (snapshot , Snapshot ):
127+ raise RuntimeError ("Unexpected snapshot type" )
128+ yield snapshot
129+
130+ @contextmanager
131+ def edit_targets (
132+ self , rolename : str = Targets .type
133+ ) -> Generator [Targets , None , None ]:
134+ """Context manager for editing targets metadata. See edit()"""
135+ with self .edit (rolename ) as targets :
136+ if not isinstance (targets , Targets ):
137+ raise RuntimeError (f"Unexpected targets ({ rolename } ) type" )
138+ yield targets
139+
140+ def root (self ) -> Root :
141+ """Read current root metadata"""
142+ root = self .open (Root .type ).signed
143+ if not isinstance (root , Root ):
144+ raise RuntimeError ("Unexpected root type" )
145+ return root
146+
147+ def timestamp (self ) -> Timestamp :
148+ """Read current timestamp metadata"""
149+ timestamp = self .open (Timestamp .type ).signed
150+ if not isinstance (timestamp , Timestamp ):
151+ raise RuntimeError ("Unexpected timestamp type" )
152+ return timestamp
153+
154+ def snapshot (self ) -> Snapshot :
155+ """Read current snapshot metadata"""
156+ snapshot = self .open (Snapshot .type ).signed
157+ if not isinstance (snapshot , Snapshot ):
158+ raise RuntimeError ("Unexpected snapshot type" )
159+ return snapshot
160+
161+ def targets (self , rolename : str = Targets .type ) -> Targets :
162+ """Read current targets metadata"""
163+ targets = self .open (rolename ).signed
164+ if not isinstance (targets , Targets ):
165+ raise RuntimeError ("Unexpected targets type" )
166+ return targets
167+
168+ def do_snapshot (
169+ self , force : bool = False
170+ ) -> Tuple [bool , Dict [str , MetaFile ]]:
98171 """Update snapshot meta information
99172
100173 Updates the snapshot meta information according to current targets
@@ -115,7 +188,7 @@ def snapshot(self, force: bool = False) -> Tuple[bool, Dict[str, MetaFile]]:
115188 update_version = force
116189 removed : Dict [str , MetaFile ] = {}
117190
118- with self .edit ( "snapshot" ) as snapshot :
191+ with self .edit_snapshot ( ) as snapshot :
119192 for keyname , new_meta in self .targets_infos .items ():
120193 if keyname not in snapshot .meta :
121194 update_version = True
@@ -131,18 +204,20 @@ def snapshot(self, force: bool = False) -> Tuple[bool, Dict[str, MetaFile]]:
131204 removed [keyname ] = old_meta
132205
133206 if not update_version :
134- # prevent edit () from storing a new snapshot version
207+ # prevent edit_snapshot () from storing a new version
135208 raise AbortEdit ("Skip snapshot: No targets version changes" )
136209
137210 if not update_version :
138- # this is reachable as edit () handles AbortEdit
211+ # this is reachable as edit_snapshot () handles AbortEdit
139212 logger .debug ("Snapshot update not needed" ) # type: ignore[unreachable]
140213 else :
141214 logger .debug ("Snapshot v%d" , snapshot .version )
142215
143216 return update_version , removed
144217
145- def timestamp (self , force : bool = False ) -> Tuple [bool , Optional [MetaFile ]]:
218+ def do_timestamp (
219+ self , force : bool = False
220+ ) -> Tuple [bool , Optional [MetaFile ]]:
146221 """Update timestamp meta information
147222
148223 Updates timestamp according to current snapshot state
@@ -153,7 +228,7 @@ def timestamp(self, force: bool = False) -> Tuple[bool, Optional[MetaFile]]:
153228 """
154229 update_version = force
155230 removed = None
156- with self .edit ( "timestamp" ) as timestamp :
231+ with self .edit_timestamp ( ) as timestamp :
157232 if self .snapshot_info .version < timestamp .snapshot_meta .version :
158233 raise ValueError ("snapshot version rollback" )
159234
@@ -166,7 +241,7 @@ def timestamp(self, force: bool = False) -> Tuple[bool, Optional[MetaFile]]:
166241 raise AbortEdit ("Skip timestamp: No snapshot version changes" )
167242
168243 if not update_version :
169- # this is reachable as edit () handles AbortEdit
244+ # this is reachable as edit_timestamp () handles AbortEdit
170245 logger .debug ("Timestamp update not needed" ) # type: ignore[unreachable]
171246 else :
172247 logger .debug ("Timestamp v%d" , timestamp .version )
0 commit comments