Rev 10: Merge with trunk. in http://people.canonical.com/~robertc/baz2.0/plugins/plugin_info/trunk

Robert Collins robertc at robertcollins.net
Mon Mar 1 01:44:30 GMT 2010


At http://people.canonical.com/~robertc/baz2.0/plugins/plugin_info/trunk

------------------------------------------------------------
revno: 10 [merge]
revision-id: robertc at robertcollins.net-20100301014425-hv196w58le2yn2ts
parent: jelmer at samba.org-20100111102416-plxkwxm7z05q94lp
parent: robertc at robertcollins.net-20100301013252-gx1fiqt8j59v36ju
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Mon 2010-03-01 12:44:25 +1100
message:
  Merge with trunk.
added:
  .testr.conf                    testr.conf-20100301005046-62rt3mlm003ty2ig-1
modified:
  NEWS                           news-20080229113630-0dhvipp22wlcjolw-2
  __init__.py                    __init__.py-20080229113630-0dhvipp22wlcjolw-4
  commands.py                    commands.py-20080229185857-m3j6ficrf7se6ms4-1
  extract.py                     extract.py-20080229115650-cgv523um54o9zvew-1
  tests/__init__.py              __init__.py-20080229113630-0dhvipp22wlcjolw-7
  tests/test_blackbox.py         test_blackbox.py-20080229185857-m3j6ficrf7se6ms4-2
  tests/test_extract.py          test_extract.py-20080229115650-cgv523um54o9zvew-2
=== added file '.testr.conf'
--- a/.testr.conf	1970-01-01 00:00:00 +0000
+++ b/.testr.conf	2010-03-01 00:50:56 +0000
@@ -0,0 +1,4 @@
+[DEFAULT]
+test_command=bzr selftest -s bp.plugin_info --subunit $IDOPTION
+test_id_option=--load-list $IDFILE
+

=== modified file 'NEWS'
--- a/NEWS	2009-08-05 04:45:21 +0000
+++ b/NEWS	2010-03-01 01:32:52 +0000
@@ -14,7 +14,9 @@
   FEATURES:
 
     * New command ``bzr plugin_info`` which will dump plugin details for any
-      number of URL's. (Robert Collins)
+      number of URL's. When given ``--python`` this command dumps out a python
+      script that can recreate the metadata for all the plugins it scanned.
+      (Robert Collins)
 
   IMPROVEMENTS:
 
@@ -28,8 +30,14 @@
 
   INTERNALS:
 
+    * PluginInfo can now output a python representation of itself.
+      (Robert Collins)
+
     * New class ``extract.PluginInfo`` for reporting extraction results.
       (Robert Collins)
 
     * New method ``extract.extract_info_local`` to extract data from an
       unpacked plugin on disk.
+
+    * New method ``extract.extract_info_url`` as the primary workhorse for
+      examining plugins. (Robert Collins)

=== modified file '__init__.py'
--- a/__init__.py	2010-01-11 10:24:16 +0000
+++ b/__init__.py	2010-03-01 01:44:25 +0000
@@ -20,7 +20,7 @@
 The command ``plugin-info`` provides information about plugins when given one
 or more local paths or URL's to plugin branches.
 
-:seealso: bzrlib.plugins.plugin_info.extract
+:seealso: bzrlib.plugins.plugin_info.extract for metadata extraction routines.
 """
 
 from bzrlib.commands import plugin_cmds

=== modified file 'commands.py'
--- a/commands.py	2008-02-29 19:00:41 +0000
+++ b/commands.py	2010-03-01 01:32:52 +0000
@@ -20,6 +20,7 @@
 from bzrlib.branch import Branch
 from bzrlib import errors
 import bzrlib.commands
+from bzrlib.option import Option
 from bzrlib.plugins.plugin_info.extract import *
 
 
@@ -31,16 +32,30 @@
     """
 
     takes_args = ['location+']
-
-    def run(self, location_list=[]):
+    takes_options = [
+        Option('python', help='output a python script with the plugin metadata.'),
+        ]
+
+
+    def dump_info(self, plugin_info):
+        if self.python:
+            self.outf.write(plugin_info.to_python())
+            self.outf.write('plugins.append(plugin)\n')
+        else:
+            self.outf.write(str(plugin_info))
+
+    def run(self, location_list=[], python=False):
+        self.python = python
+        if self.python:
+            self.outf.write('plugins = []\n')
         for url in location_list:
             try:
-                self.outf.write(str(extract_info_local(url)))
+                self.dump_info(extract_info_local(url))
             except IOError:
                 try:
                     branch = Branch.open(url)
                 except errors.NotBranchError:
                     raise
                 else:
-                    self.outf.write(str(extract_info_branch(branch)))
+                    self.dump_info(extract_info_branch(branch))
             self.outf.write('\n')

=== modified file 'extract.py'
--- a/extract.py	2009-08-05 04:45:21 +0000
+++ b/extract.py	2010-03-01 01:32:52 +0000
@@ -1,5 +1,5 @@
 # plugin_info, a plugin for working with information about plugins.
-# Copyright (C) 2008 Canonical Limited.
+# Copyright (C) 2008, 2010 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -15,11 +15,20 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 # 
 
-"""Extraction of plugin data from a plugin."""
-
-__all__ = ['extract_info_branch', 'extract_info_local', 'PluginInfo']
-
-from bzrlib import osutils
+"""Extraction of plugin data from a plugin.
+
+The primary entry point to this module is extract_info_url which will attempt
+to do the right thing when given a url (including directory service lookups).
+"""
+
+__all__ = [
+    'extract_info_branch',
+    'extract_info_local',
+    'extract_info_url',
+    'PluginInfo',
+    ]
+
+from bzrlib import branch, directory_service, osutils
 
 
 def extract_info_branch(branch):
@@ -68,6 +77,20 @@
     return result
 
 
+def extract_info_url(url):
+    """Extract info from a plugin at url.
+
+    :param url: A URL to probe. Directory service lookups will be done on it.
+    :return: A PluginInfo for the plugin at url.
+    """
+    # TODO: for local branches use extract_info_local ?:- what if they are
+    # treeless branches?
+    b = branch.Branch.open(url)
+    result = extract_info_branch(b)
+    result.location = url
+    return result
+
+
 class PluginInfo(object):
     """Information about a plugin."""
 
@@ -101,3 +124,20 @@
             'transports(%s).'
             % (self.name, version_string, self.location, command_string, control_string,
                checkout_string, branch_string, repository_string, transports_string))
+
+    def to_python(self):
+        """Represent this PluginInfo as a python source fragment."""
+        result = []
+        result.append('plugin = PluginInfo()\n')
+        result.append('plugin.name = %r\n' % (self.name,))
+        result.append('plugin.location = %s\n' % (self.location,))
+        result.append('plugin.version_info = %s\n' % (self.version_info,))
+        result.append('plugin.minimum_bzr_version = %s\n' % (self.minimum_bzr_version,))
+        result.append('plugin.maximum_bzr_version = %s\n' % (self.maximum_bzr_version,))
+        result.append('plugin.commands = %s\n' % (self.commands,))
+        result.append('plugin.control_formats = %s\n' % (self.control_formats,))
+        result.append('plugin.checkout_formats = %s\n' % (self.checkout_formats,))
+        result.append('plugin.branch_formats = %s\n' % (self.branch_formats,))
+        result.append('plugin.repository_formats = %s\n' % (self.repository_formats,))
+        result.append('plugin.transports = %s\n' % (self.transports,))
+        return ''.join(result)

=== modified file 'tests/__init__.py'
--- a/tests/__init__.py	2008-02-29 19:00:41 +0000
+++ b/tests/__init__.py	2010-03-01 01:15:55 +0000
@@ -1,5 +1,5 @@
 # plugin_info, a plugin for working with information about plugins.
-# Copyright (C) 2006 Canonical Limited.
+# Copyright (C) 2008 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published

=== modified file 'tests/test_blackbox.py'
--- a/tests/test_blackbox.py	2009-08-05 04:45:21 +0000
+++ b/tests/test_blackbox.py	2010-03-01 01:32:52 +0000
@@ -1,5 +1,5 @@
 # plugin_info, a plugin for working with information about plugins.
-# Copyright (C) 2008 Canonical Limited.
+# Copyright (C) 2008, 2010 Canonical Limited.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as published
@@ -18,6 +18,7 @@
 """Tests for the commands supplied by plugin-info."""
 
 from bzrlib.tests import TestCaseWithTransport
+from testtools.matchers import DocTestMatches
 
 
 class TestPluginInfo(TestCaseWithTransport):
@@ -36,16 +37,55 @@
 bzr_transports = ["hg+ssh://"]
 """
 
-    def test_extract_info_branch(self):
+    def setup_plugins(self):
         tree = self.make_branch_and_tree('plugin')
         self.build_tree_contents([('plugin/setup.py', self.sample_setup())])
         tree.add(['setup.py'])
         tree.commit('yay history')
         self.build_tree(['plugin2/'])
         self.build_tree_contents([('plugin2/setup.py', self.sample_setup())])
+
+    def test_extract_info_branch(self):
+        self.setup_plugins()
         out, err = self.run_bzr(['plugin-info', 'plugin', 'plugin2'])
         self.assertEqual(
 """foo_bar(1.2.3dev0) from plugin supplies commands("a-command"), control formats("bzr-meta"), checkout formats("dirstate"), branch formats("branch 6"), repository formats("packs"), transports("hg+ssh://").
 foo_bar(1.2.3dev0) from plugin2 supplies commands("a-command"), control formats("bzr-meta"), checkout formats("dirstate"), branch formats("branch 6"), repository formats("packs"), transports("hg+ssh://").
 """, out)
         self.assertEqual('', err)
+
+    def test_extract_info_python(self):
+        self.setup_plugins()
+        out, err = self.run_bzr(['plugin-info', 'plugin', 'plugin2', '--python'])
+        self.assertThat(out, DocTestMatches("""plugins = []
+plugin = PluginInfo()
+plugin.name = 'foo_bar'
+plugin.location = plugin
+plugin.version_info = (1, 2, 3, 'dev', 0)
+plugin.minimum_bzr_version = (1, 2, 0)
+plugin.maximum_bzr_version = (1, 3, 0)
+plugin.commands = ['a-command']
+plugin.control_formats = {'bzr-meta': {'.bzr/branch-format': 'Bazaar-NG meta directory, format 1\\n'}}
+plugin.checkout_formats = {'Bazaar Working Tree Format 4 (bzr 0.15)\\n': 'dirstate'}
+plugin.branch_formats = {'Bazaar Branch Format 6 (bzr 0.15)\\n': 'branch 6'}
+plugin.repository_formats = {'Bazaar pack repository format 1 (needs bzr 0.92)\\n': 'packs'}
+plugin.transports = ['hg+ssh://']
+plugins.append(plugin)
+<BLANKLINE>
+plugin = PluginInfo()
+plugin.name = 'foo_bar'
+plugin.location = plugin2
+plugin.version_info = (1, 2, 3, 'dev', 0)
+plugin.minimum_bzr_version = (1, 2, 0)
+plugin.maximum_bzr_version = (1, 3, 0)
+plugin.commands = ['a-command']
+plugin.control_formats = {'bzr-meta': {'.bzr/branch-format': 'Bazaar-NG meta directory, format 1\\n'}}
+plugin.checkout_formats = {'Bazaar Working Tree Format 4 (bzr 0.15)\\n': 'dirstate'}
+plugin.branch_formats = {'Bazaar Branch Format 6 (bzr 0.15)\\n': 'branch 6'}
+plugin.repository_formats = {'Bazaar pack repository format 1 (needs bzr 0.92)\\n': 'packs'}
+plugin.transports = ['hg+ssh://']
+plugins.append(plugin)
+<BLANKLINE>
+"""))
+        self.assertEqual('', err)
+

=== modified file 'tests/test_extract.py'
--- a/tests/test_extract.py	2009-08-05 04:45:21 +0000
+++ b/tests/test_extract.py	2010-03-01 01:32:52 +0000
@@ -19,12 +19,28 @@
 
 from copy import copy
 
+from bzrlib import directory_service
 from bzrlib.plugins.plugin_info.extract import *
 from bzrlib.tests import TestCaseWithTransport
 
 
 class TestPluginInfo(TestCaseWithTransport):
 
+    def sample_plugin(self):
+        plugin = PluginInfo()
+        plugin.name = "plugin_info"
+        plugin.commands = ["foo"]
+        plugin.version_info = (1, 2, 0, 'dev', 0)
+        plugin.minimum_bzr_version = (1, 0, 0)
+        plugin.maximum_bzr_version = None
+        plugin.control_formats = {"svn":{"ignored":None}}
+        plugin.checkout_formats = {"signature":"dirstate"}
+        plugin.branch_formats = {"signature":"format 6"}
+        plugin.repository_formats = {"signature":"packs"}
+        plugin.transports = ["hg+ssh://"]
+        plugin.location = "http://bazaar-vcs.org/plugin-info/"
+        return plugin
+
     def test_construct(self):
         plugin = PluginInfo()
 
@@ -42,21 +58,27 @@
         self.assertEqual({}, plugin.repository_formats)
 
     def test_str(self):
-        plugin = PluginInfo()
-        plugin.name = "plugin_info"
-        plugin.commands = ["foo"]
-        plugin.version_info = (1, 2, 0, 'dev', 0)
-        plugin.minimum_bzr_version = (1, 0, 0)
-        plugin.maximum_bzr_version = None
-        plugin.control_formats = {"svn":{"ignored":None}}
-        plugin.checkout_formats = {"signature":"dirstate"}
-        plugin.branch_formats = {"signature":"format 6"}
-        plugin.repository_formats = {"signature":"packs"}
-        plugin.transports = ["hg+ssh://"]
-        plugin.location = "http://bazaar-vcs.org/plugin-info/"
+        plugin = self.sample_plugin()
         self.assertEqual('plugin_info(1.2.0dev0) from http://bazaar-vcs.org/plugin-info/ supplies commands("foo"), control formats("svn"), checkout formats("dirstate"), branch formats("format 6"), repository formats("packs"), transports("hg+ssh://").',
             str(plugin))
 
+    def test_python(self):
+        # A plugin info can be turned into a python source fragment.
+        plugin = self.sample_plugin()
+        self.assertEqual("""plugin = PluginInfo()
+plugin.name = 'plugin_info'
+plugin.location = http://bazaar-vcs.org/plugin-info/
+plugin.version_info = (1, 2, 0, 'dev', 0)
+plugin.minimum_bzr_version = (1, 0, 0)
+plugin.maximum_bzr_version = None
+plugin.commands = ['foo']
+plugin.control_formats = {'svn': {'ignored': None}}
+plugin.checkout_formats = {'signature': 'dirstate'}
+plugin.branch_formats = {'signature': 'format 6'}
+plugin.repository_formats = {'signature': 'packs'}
+plugin.transports = ['hg+ssh://']
+""", plugin.to_python())
+
     def test___eq__(self):
         plugin_expected = PluginInfo()
         plugin_expected.name = "1"
@@ -135,6 +157,13 @@
 bzr_transports = ["hg+ssh://"]
 """
 
+    def setup_plugin(self):
+        tree = self.make_branch_and_tree('plugin')
+        self.build_tree_contents([('plugin/setup.py', self.sample_setup())])
+        tree.add(['setup.py'])
+        tree.commit('yay history')
+        return tree
+
     def expected_plugin(self):
         expected_plugin = PluginInfo()
         expected_plugin.name = "foo_bar"
@@ -163,10 +192,23 @@
         self.assertEqual(expected_plugin, plugin)
 
     def test_extract_info_branch(self):
-        tree = self.make_branch_and_tree('plugin')
-        self.build_tree_contents([('plugin/setup.py', self.sample_setup())])
-        tree.add(['setup.py'])
-        tree.commit('yay history')
+        tree = self.setup_plugin()
         expected_plugin = self.expected_plugin()
         expected_plugin.location = tree.branch.base
         self.assertEqual(expected_plugin, extract_info_branch(tree.branch))
+
+    def test_extract_info_url_handles_directory_lookup(self):
+        self.setup_plugin()
+        class LocalDirectory:
+            def look_up(self, name, url):
+                return 'plugin'
+        directory_service.directories.register('pl:', LocalDirectory, '')
+        def unregister():
+            d = directory_service.directories
+            d.remove('pl:')
+            del d._help_dict['pl:']
+            del d._info_dict['pl:']
+        self.addCleanup(unregister)
+        expected_plugin = self.expected_plugin()
+        expected_plugin.location = 'pl:'
+        self.assertEqual(expected_plugin, extract_info_url('pl:'))




More information about the bazaar-commits mailing list