28 from .
import PosixStorage, RepositoryCfg, safeFileIo, ParentsMismatch
37 Loader = yaml.UnsafeLoader
38 except AttributeError:
42 def _write(butlerLocation, cfg):
43 """Serialize a RepositoryCfg to a location.
45 When the location is the same as cfg.root, the RepositoryCfg is to be written at the root location of
46 the repository. In that case, root is not written in the serialized cfg; it is implicit in the
47 location of the cfg. This allows the cfg to move from machine to machine without modification.
51 butlerLocation : ButlerLocation
52 The location to write the RepositoryCfg.
53 cfg : RepositoryCfg instance
54 The RepositoryCfg to be serialized.
56 def setRoot(cfg, loc):
57 loc = os.path.split(loc)[0]
58 if loc
is None or cfg.root == loc:
65 loc = butlerLocation.storage.root
66 parseRes = urllib.parse.urlparse(loc
if loc
is not None else cfg.root)
67 loc = os.path.join(parseRes.path, butlerLocation.getLocations()[0])
69 with safeFileIo.SafeLockedFileForRead(loc)
as f:
70 existingCfg = _doRead(f, parseRes.path)
71 if existingCfg == cfg:
75 if e.errno != errno.ENOENT:
78 existingCfg = _doRead(f, parseRes.path)
79 if existingCfg
is None:
80 cfgToWrite = setRoot(cfg, loc)
82 if existingCfg == cfg:
86 existingCfg.extend(cfg)
87 cfgToWrite = setRoot(existingCfg, loc)
88 except ParentsMismatch
as e:
89 raise RuntimeError(
"Can not extend existing repository cfg because: {}".format(e))
90 yaml.dump(cfgToWrite, f)
94 def _doRead(fileObject, uri):
95 """Get a persisted RepositoryCfg from an open file object.
99 fileObject : an open file object
100 the file that contains the RepositoryCfg.
102 path to the repositoryCfg
106 A RepositoryCfg instance or None
108 repositoryCfg = yaml.load(fileObject, Loader=Loader)
109 if repositoryCfg
is not None:
110 if repositoryCfg.root
is None:
111 repositoryCfg.root = uri
115 def _read(butlerLocation):
116 """Deserialize a RepositoryCfg from a location.
120 butlerLocation : ButlerLocation
121 The lcoation from which to read the RepositoryCfg.
126 The deserialized RepoistoryCfg.
131 Raised if no repositoryCfg exists at the location.
134 loc = butlerLocation.storage.root
135 fileLoc = os.path.join(loc, butlerLocation.getLocations()[0])
137 with safeFileIo.SafeLockedFileForRead(fileLoc)
as f:
138 repositoryCfg = _doRead(f, loc)
140 if e.errno != errno.ENOENT:
145 PosixStorage.registerFormatters(RepositoryCfg, _read, _write)