Submitter | Durham Goode |
---|---|
Date | Aug. 14, 2013, 9:02 p.m. |
Message ID | <84ac4b920802805474d2.1376514123@dev350.prn1.facebook.com> |
Download | mbox | patch |
Permalink | /patch/2176/ |
State | Changes Requested |
Headers | show |
Comments
Durham Goode <durham@fb.com> writes: > # HG changeset patch > # User Durham Goode <durham@fb.com> > # Date 1375827328 25200 > # Tue Aug 06 15:15:28 2013 -0700 > # Node ID 84ac4b920802805474d203b5b5dc1cd4aa861256 > # Parent 3e34e7b223d10bbe8814f82d7a1f53575fe09096 > schemas: add schemas to repositories > > This adds the concept of schemas to repositories. A schema is a > key/value pair indicating alternative means of accessing the remote > repository. When reading this I wonder how this differs from the pushkey system? That's also a key/value store and as we've discussed, it could be used for "schemas" too. Noting the advantage of a new key/value store would probably be a good idea. > For example, the largefiles extension might provide a schema such as: > > largefiles = http://some.cdn.com/myrepo > > When a user interacts with the repository, if the client knows how to > handle the largefiles schema, it will read the url and obtain > largefiles from the url. Thus letting you serve large files from a > CDN. > > The next patch will allow querying schemas via the wire protocol. > > diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py > --- a/mercurial/localrepo.py > +++ b/mercurial/localrepo.py > @@ -661,6 +661,47 @@ > bt[bn] = self._branchtip(heads) > return bt > > + @repofilecache('schemas') > + def schemas(self): > + try: > + file = self.opener('schemas') > + except IOError, inst: > + if inst.errno != errno.ENOENT: > + raise > + return {} This pattern is also in abstractvfs.tryread. Maybe that could be used instead somehow? > + try: > + schemas = {} > + lines = file.readlines() > + for line in lines: > + if line.find('=') > 0: > + k, v = line.split('=', 1) > + schemas[k.strip()] = v[:-1].strip() > + > + return schemas > + finally: > + file.close() > + > + def registerschema(self, name, url): > + existingschemas = self.schemas > + existingschemas[name] = url > + try: > + file = self.opener('schemas', 'w') > + except IOError, inst: > + if inst.errno != errno.ENOENT: > + raise > + return Isn't this pattern only used when reading (not writing) a possibly missing file? Here you end up not serializing the schemes if a directory on the path to <repo>/.hg/schemes doesn't exist -- which seems unlikely :) > + try: > + serialized = "" > + for k, v in existingschemas.iteritems(): > + if len(k) > 0 and len(v) > 0: I think 'if k and v:' is the usual style here.
Patch
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -661,6 +661,47 @@ bt[bn] = self._branchtip(heads) return bt + @repofilecache('schemas') + def schemas(self): + try: + file = self.opener('schemas') + except IOError, inst: + if inst.errno != errno.ENOENT: + raise + return {} + + try: + schemas = {} + lines = file.readlines() + for line in lines: + if line.find('=') > 0: + k, v = line.split('=', 1) + schemas[k.strip()] = v[:-1].strip() + + return schemas + finally: + file.close() + + def registerschema(self, name, url): + existingschemas = self.schemas + existingschemas[name] = url + try: + file = self.opener('schemas', 'w') + except IOError, inst: + if inst.errno != errno.ENOENT: + raise + return + + try: + serialized = "" + for k, v in existingschemas.iteritems(): + if len(k) > 0 and len(v) > 0: + serialized += "%s = %s\n" % (k, v) + + file.write(serialized) + finally: + file.close() + def lookup(self, key): return self[key].node()