29 from .
import iterify, doImport, Storage, ParentsMismatch
30 from past.builtins
import basestring
34 """RepositoryCfg stores the configuration of a repository. Its contents are persisted to the repository 35 when the repository is created in persistent storage. Thereafter the the RepositoryCfg should not change. 40 The mapper associated with the repository. The string should be importable to a class object. 42 Arguments & values to pass to the mapper when initializing it. 44 URIs to the locaiton of the parent RepositoryCfgs of this repository. 46 Policy associated with this repository, overrides all other policy data (which may be loaded from 47 policies in derived packages). 49 Butler internal use only. This flag is used to indicate to the init funciton that the repository class 50 is being deserialized and should not perform certain operations that normally happen in other uses of 53 yaml_tag =
u"!RepositoryCfg_v1" 55 def __init__(self, root, mapper, mapperArgs, parents, policy):
58 self.
_mapperArgs = {}
if mapperArgs
is None else mapperArgs
66 """Constructor for 'version 1' of the serlized RepositoryCfg. 68 If new parameters are added to RepositoryCfg they will have to be checked for in d; if they are there 69 then their value should be used and if they are not there a default value must be used in place. 71 In case the structure of the serialzed file must be changed in a way that invalidates some of the 73 1. Increment the version number (after _v1) in the yaml_tag of this class. 74 2. Add a new constructor (similar to this one) to deserialze new serializations of this class. 75 3. Registered the new constructor for the new version with yaml, the same way it is done at the bottom 77 4. All constructors for the older version(s) of persisted RepositoryCfg must be changed to adapt 78 the old keys to their new uses and create the current (new) version of a repository cfg, or raise a 79 RuntimeError in the case that older versions of serialized RepositoryCfgs can not be adapted. 80 There is an example of migrating from a fictitious v0 to v1 in tests/repositoryCfg.py 82 d = loader.construct_mapping(node)
83 cfg =
RepositoryCfg(root=d[
'_root'], mapper=d[
'_mapper'], mapperArgs=d[
'_mapperArgs'],
84 parents=[], policy=d.get(
'_policy',
None))
88 cfg._parents = d[
'_parents']
89 if cfg._parents
is None:
97 return self.
root == other.root
and \
104 return not self.
__eq__(other)
107 """Extend this RepositoryCfg with extendable values from the other RepositoryCfg. 109 Currently the only extendable value is parents; see `extendParents` for more detials about extending 114 other : RepositoryCfg 115 A RepositoryCfg instance to update values from. 120 If non-extendable parameters do not match a RuntimeError will be raised. 121 (If this RepositoryCfg's parents can not be extended with the parents of the other repository, 122 extendParents will raise). 124 if (self.
root != other.root
or 125 self.
mapper != other.mapper
or 127 self.
policy != other.policy):
128 raise RuntimeError(
"{} can not be extended with cfg:{}".
format(self, other))
131 def _extendsParents(self, newParents):
132 """Query if a list of parents starts with the same list of parents as this RepositoryCfg's parents, 133 with new parents at the end. 137 newParents : list of string and/or RepositoryCfg 138 A list of parents that contains all the parents that would be in this RepositoryCfg. 139 This must include parents that may already be in this RepositoryCfg's parents list. Paths must be 140 in absolute form (not relative). 145 True if the beginning of the new list matches this RepositoryCfg's parents list, False if not. 147 doesExtendParents =
False 148 return doesExtendParents
151 """Determine if a parents list matches our parents list, with extra items at the end. If a list of 152 parents does not match but the mismatch is because of new parents at the end of the list, then they 153 can be added to the cfg. 157 newParents : list of string 158 A list of parents that contains all the parents that are to be recorded into this RepositoryCfg. 159 This must include parents that may already be in this RepositoryCfg's parents list 169 if all(x == y
for (x, y)
in zip(self.
_parents, newParents)):
170 if len(self.
_parents) < len(newParents):
173 elif len(self.
_parents) == len(newParents):
180 raise ParentsMismatch((
"The beginning of the passed-in parents list: {} does not match the " +
181 "existing parents list in this RepositoryCfg: {}").
format(
190 if root
is not None and self.
_root is not None:
191 raise RuntimeError(
"Explicity clear root (set to None) before changing the value of root.")
201 raise RuntimeError(
"Should not set mapper over previous not-None value.")
219 def _normalizeParents(root, newParents):
220 """Eliminate symlinks in newParents and get the relative path (if one exists) from root to each parent 225 newParents : list containing strings and RepoistoryCfg instances 226 Same as in `addParents`. 230 list of strings and RepositoryCfg instances. 231 Normalized list of parents 233 newParents =
iterify(newParents)
234 for i
in range(len(newParents)):
235 if isinstance(newParents[i], RepositoryCfg):
236 newParents[i] = copy.copy(newParents[i])
237 parentRoot = newParents[i].root
238 newParents[i].root =
None 239 newParents[i].root = Storage.relativePath(root, parentRoot)
241 newParents[i] = Storage.relativePath(root, newParents[i])
245 def _denormalizeParents(root, parents):
246 def getAbs(root, parent):
247 if isinstance(parent, RepositoryCfg):
248 parentRoot = parent.root
250 parent.root = Storage.absolutePath(root, parentRoot)
252 parent = Storage.absolutePath(root, parent)
254 return [getAbs(root, parent)
for parent
in parents]
257 """Add a parent or list of parents to this RepositoryCfg 261 newParents : string or RepositoryCfg instance, or list of these. 262 If string, newParents should be a path or URI to the parent 263 repository. If RepositoryCfg, newParents should be a RepositoryCfg 264 that describes the parent repository in part or whole. 267 for newParent
in newParents:
279 mapper=repositoryArgs.mapper,
280 mapperArgs=repositoryArgs.mapperArgs,
282 policy=repositoryArgs.policy)
286 """Checks that a repositoryArgs instance will work with this repositoryCfg. This is useful 287 when loading an already-existing repository that has a persisted cfg, to ensure that the args that are 288 passed into butler do not conflict with the persisted cfg.""" 289 if repositoryArgs.root
is not None and self.
_root != repositoryArgs.root:
292 repoArgsMapper = repositoryArgs.mapper
294 if isinstance(repoArgsMapper, basestring):
295 repoArgsMapper =
doImport(repoArgsMapper)
296 if isinstance(cfgMapper, basestring):
298 if repoArgsMapper
is not None and repoArgsMapper != cfgMapper:
301 if self.
_mapperArgs is not None and repositoryArgs.mapperArgs
is not None:
303 if self.
_mapperArgs[key] != repositoryArgs.mapperArgs[key]:
305 if repositoryArgs.policy
and repositoryArgs.policy != self.
_policy:
311 return "%s(root=%r, mapper=%r, mapperArgs=%r, parents=%s, policy=%s)" % (
312 self.__class__.__name__,
320 loaderList = [yaml.Loader, ]
322 loaderList.append(yaml.FullLoader)
323 except AttributeError:
326 loaderList.append(yaml.UnsafeLoader)
327 except AttributeError:
330 for loader
in loaderList:
331 yaml.add_constructor(
u"!RepositoryCfg_v1", RepositoryCfg.v1Constructor, Loader=loader)
def matchesArgs(self, repositoryArgs)
def _normalizeParents(root, newParents)
def __init__(self, root, mapper, mapperArgs, parents, policy)
def addParents(self, newParents)
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
daf::base::PropertySet * set
def _denormalizeParents(root, parents)
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def v1Constructor(loader, node)
def extendParents(self, newParents)
def makeFromArgs(repositoryArgs)