[Pkg-bazaar-commits] ./bzr/unstable r677: - draft 'meta' command by john
Martin Pool
mbp at sourcefrog.net
Fri Apr 10 08:20:40 UTC 2009
------------------------------------------------------------
revno: 677
committer: Martin Pool <mbp at sourcefrog.net>
timestamp: Mon 2005-06-13 22:14:52 +1000
message:
- draft 'meta' command by john
added:
patches/meta-data-in-inventory.patch
-------------- next part --------------
=== added file 'patches/meta-data-in-inventory.patch'
--- a/patches/meta-data-in-inventory.patch 1970-01-01 00:00:00 +0000
+++ b/patches/meta-data-in-inventory.patch 2005-06-13 12:14:52 +0000
@@ -0,0 +1,300 @@
+*** modified file 'bzrlib/commands.py'
+--- bzrlib/commands.py
++++ bzrlib/commands.py
+@@ -1175,7 +1175,68 @@
+ b = Branch('.')
+ statcache.update_cache(b.base, b.read_working_inventory())
+
+-
++class cmd_meta(Command):
++ """Get or set the meta information properties about a file.
++
++ bzr meta FILENAME # Display all meta information
++ bzr meta FILENAME prop # Display the value of meta-info named prop, return error if not found
++ bzr meta FILENAME --set prop value # Set the value of prop to value
++ echo "the value" | bzr meta FILENAME --set prop # Set the value to whatever is read from stdin
++ bzr meta FILENAME --unset prop # Remove the property
++
++ bzr meta FILENAME --revision=10 # Display the meta information for a given revision
++ (Not supported yet)
++ """
++ hidden = True
++ takes_args = ['filename', 'property?', 'value?']
++ takes_options = ['revision', 'set', 'unset']
++
++ def run(self, filename, property=None, value=None, revision=None, set=False, unset=False):
++ if isinstance(revision, list) and len(revision) > 1:
++ raise BzrCommandError('bzr meta takes at most 1 revision.')
++ if revision is not None and (set or unset):
++ raise BzrCommandError('Cannot set/unset meta information in an old version.')
++ if set and unset:
++ raise BzrCommandError('Cannot set and unset at the same time')
++ if not set and value:
++ raise BzrCommandError('You must supply --set if you want to set the value of a property.')
++
++ b = Branch(filename)
++ inv = b.inventory
++ file_id = inv.path2id(b.relpath(filename))
++ inv_entry = inv[file_id]
++ if not property:
++ meta = inv_entry.meta
++ if meta: # Not having meta is the same as having an empty meta
++ keys = meta.properties.keys()
++ keys.sort()
++ # The output really needs to be parseable
++ for key in keys:
++ print '%s: %r' % (key, meta.properties[key])
++ else:
++ meta = inv_entry.meta
++ if set:
++ if value is None:
++ value = sys.stdin.read()
++ if not meta:
++ from bzrlib.inventory import Meta
++ inv_entry.meta = Meta({property:value})
++ else:
++ inv_entry.meta.properties[property] = value
++ b.inventory = inv # This should cause it to be saved
++ elif unset:
++ if not meta or not meta.properties.has_key(property):
++ return 3 # Cannot unset a property that doesn't exist
++ # I wonder if this should be a different return code
++ del inv_entry.meta.properties[property]
++ b.inventory = inv
++ else:
++ if not meta or not meta.properties.has_key(property):
++ return 3 # Missing property
++ # Probably this should not be print, but
++ # sys.stdout.write() so that you get back exactly
++ # what was given. But I'm leaving it this way for now
++ print meta.properties[property]
+
+ # list of all available options; the rhs can be either None for an
+ # option that takes no argument, or a constructor function that checks
+@@ -1196,6 +1257,8 @@
+ 'verbose': None,
+ 'version': None,
+ 'email': None,
++ 'set': None,
++ 'unset': None,
+ }
+
+ SHORT_OPTIONS = {
+
+*** modified file 'bzrlib/diff.py'
+--- bzrlib/diff.py
++++ bzrlib/diff.py
+@@ -226,8 +226,10 @@
+ new_tree.get_file(file_id).readlines(),
+ to_file)
+
+- for old_path, new_path, file_id, kind, text_modified in delta.renamed:
++ for old_path, new_path, file_id, kind, text_modified, meta_modified in delta.renamed:
+ print '*** renamed %s %r => %r' % (kind, old_path, new_path)
++ if meta_modified:
++ print '## Meta-info modified'
+ if text_modified:
+ diff_file(old_label + old_path,
+ old_tree.get_file(file_id).readlines(),
+@@ -235,9 +237,11 @@
+ new_tree.get_file(file_id).readlines(),
+ to_file)
+
+- for path, file_id, kind in delta.modified:
++ for path, file_id, kind, text_modified, meta_modified in delta.modified:
+ print '*** modified %s %r' % (kind, path)
+- if kind == 'file':
++ if meta_modified:
++ print '## Meta-info modified'
++ if kind == 'file' and text_modified:
+ diff_file(old_label + path,
+ old_tree.get_file(file_id).readlines(),
+ new_label + path,
+@@ -316,7 +320,7 @@
+
+ if self.renamed:
+ print >>to_file, 'renamed:'
+- for oldpath, newpath, fid, kind, text_modified in self.renamed:
++ for oldpath, newpath, fid, kind, text_modified, meta_modified in self.renamed:
+ if show_ids:
+ print >>to_file, ' %s => %s %s' % (oldpath, newpath, fid)
+ else:
+@@ -324,7 +328,16 @@
+
+ if self.modified:
+ print >>to_file, 'modified:'
+- show_list(self.modified)
++ for path, fid, kind, text_modified, meta_modified in self.modified:
++ if kind == 'directory':
++ path += '/'
++ elif kind == 'symlink':
++ path += '@'
++
++ if show_ids:
++ print >>to_file, ' %-30s %s' % (path, fid)
++ else:
++ print >>to_file, ' ', path
+
+ if show_unchanged and self.unchanged:
+ print >>to_file, 'unchanged:'
+@@ -388,6 +401,14 @@
+ ## mutter("no text to check for %r %r" % (file_id, kind))
+ text_modified = False
+
++ old_meta = old_inv[file_id].meta
++ new_meta = new_inv[file_id].meta
++
++ if old_meta != new_meta:
++ meta_modified = True
++ else:
++ meta_modified = False
++
+ # TODO: Can possibly avoid calculating path strings if the
+ # two files are unchanged and their names and parents are
+ # the same and the parents are unchanged all the way up.
+@@ -395,9 +416,10 @@
+
+ if old_path != new_path:
+ delta.renamed.append((old_path, new_path, file_id, kind,
+- text_modified))
+- elif text_modified:
+- delta.modified.append((new_path, file_id, kind))
++ text_modified, meta_modified))
++ elif text_modified or meta_modified:
++ delta.modified.append((new_path, file_id, kind,
++ text_modified, meta_modified))
+ elif want_unchanged:
+ delta.unchanged.append((new_path, file_id, kind))
+ else:
+
+*** modified file 'bzrlib/inventory.py'
+--- bzrlib/inventory.py
++++ bzrlib/inventory.py
+@@ -33,6 +33,67 @@
+ import bzrlib
+ from bzrlib.osutils import uuid, quotefn, splitpath, joinpath, appendpath
+ from bzrlib.trace import mutter
++
++class Meta(XMLMixin):
++ """Meta information about a single inventory entry.
++
++ This is basically just a set of key->value pairs.
++
++ In general, bzr does not handle this information, it only provides
++ a location for plugins and other data sources to store this data.
++
++ """
++ def __init__(self, properties):
++ self.properties = properties
++
++ def __eq__(self, other):
++ if other is None:
++ return False
++ if not isinstance(other, Meta):
++ return NotImplemented
++
++ return (self.properties == other.properties)
++
++ def __ne__(self, other):
++ return not (self == other)
++
++ def __hash__(self):
++ raise ValueError('not hashable')
++
++ def from_element(cls, elt):
++ assert elt.tag == 'meta'
++
++ properties = {}
++ for child in elt:
++ if child.tag == 'property':
++ if child.text is None:
++ properties[child.get('name')] = ''
++ else:
++ properties[child.get('name')] = child.text
++ self = cls(properties)
++ return self
++
++ from_element = classmethod(from_element)
++
++ def to_element(self):
++ e = Element('meta')
++ keys = self.properties.keys()
++ keys.sort()
++
++ # The blah.text is just to make things look pretty in the files
++ # We may want to remove it
++ if len(keys) > 0:
++ e.text = '\n'
++
++ for key in keys:
++ prop = Element('property')
++ prop.set('name', key)
++ prop.text=self.properties[key]
++ prop.tail='\n'
++ e.append(prop)
++
++ return e
++
+
+ class InventoryEntry(XMLMixin):
+ """Description of a versioned file.
+@@ -100,6 +161,7 @@
+
+ text_sha1 = None
+ text_size = None
++ meta = None
+
+ def __init__(self, file_id, name, kind, parent_id, text_id=None):
+ """Create an InventoryEntry
+@@ -124,6 +186,7 @@
+ self.kind = kind
+ self.text_id = text_id
+ self.parent_id = parent_id
++ self.meta = None
+ if kind == 'directory':
+ self.children = {}
+ elif kind == 'file':
+@@ -146,6 +209,10 @@
+ other.text_size = self.text_size
+ # note that children are *not* copied; they're pulled across when
+ # others are added
++ if self.meta:
++ other.meta = Meta(self.meta.properties)
++ else:
++ other.meta = None
+ return other
+
+
+@@ -182,6 +249,9 @@
+ e.set('parent_id', self.parent_id)
+
+ e.tail = '\n'
++
++ if self.meta:
++ e.append(self.meta.to_element())
+
+ return e
+
+@@ -205,6 +275,11 @@
+ v = elt.get('text_size')
+ self.text_size = v and int(v)
+
++ self.meta = None
++ for child in elt:
++ if child.tag == 'meta':
++ self.meta = Meta.from_element(child)
++
+ return self
+
+
+@@ -220,7 +295,8 @@
+ and (self.text_size == other.text_size) \
+ and (self.text_id == other.text_id) \
+ and (self.parent_id == other.parent_id) \
+- and (self.kind == other.kind)
++ and (self.kind == other.kind) \
++ and (self.meta == other.meta)
+
+
+ def __ne__(self, other):
+
More information about the Pkg-bazaar-commits
mailing list