[PATCH] Re: FEATURE REQ: Add option --dry-run to 'add'

Michael Ellerman michael at ellerman.id.au
Sat Sep 17 10:02:49 BST 2005


Hi guys,

Here's a patch to do --dry-run for add. It's a bit busy, as I've changed the 
API for smart_add() and hence all it's callers have to be updated, but I 
think this is the cleanest way to implement this. Otherwise we end up with 
smart_add() taking 15 parameters.

It includes tests for the action callbacks, as well as a blackbox test of "bzr 
add --dry-run ."

cheers

=== modified file 'bzrlib/add.py'
--- bzrlib/add.py
+++ bzrlib/add.py
@@ -36,14 +36,24 @@
     return expanded_file_list
 
 
-def add_reporter_null(path, kind, entry):
-    """Absorb add reports and do nothing."""
+def add_action_null(inv, path, kind):
+    """Absorb add actions and do nothing."""
     pass
 
-def add_reporter_print(path, kind, entry):
-    """Print a line to stdout for each file that's added."""
+def add_action_print(inv, path, kind):
+    """Print a line to stdout for each file that would be added."""
     print "added", quotefn(path)
-    
+
+def add_action_add(inv, path, kind):
+    """Add each file to the given inventory. Produce no output."""
+    entry = inv.add_path(path, kind=kind)
+    mutter("added %r kind %r file_id={%s}" % (path, kind, entry.file_id))
+
+def add_action_add_and_print(inv, path, kind):
+    """Add each file to the given inventory, and print a line to stdout."""
+    add_action_add(inv, path, kind)
+    add_action_print(inv, path, kind)
+
 def _prepare_file_list(file_list):
     """Prepare a file list for use by smart_add_*."""
     import sys
@@ -55,7 +65,7 @@
     return file_list
 
 
-def smart_add(file_list, recurse=True, reporter=add_reporter_null):
+def smart_add(file_list, recurse=True, action=add_action_add):
     """Add files to version, optionally recursing into directories.
 
     This is designed more towards DWIM for humans than API simplicity.
@@ -65,10 +75,10 @@
     """
     file_list = _prepare_file_list(file_list)
     b = Branch.open_containing(file_list[0])
-    return smart_add_branch(b, file_list, recurse, reporter)
+    return smart_add_branch(b, file_list, recurse, action)
 
         
-def smart_add_branch(branch, file_list, recurse=True, 
reporter=add_reporter_null):
+def smart_add_branch(branch, file_list, recurse=True, action=add_action_add):
     """Add files to version, optionally recursing into directories.
 
     This is designed more towards DWIM for humans than API simplicity.
@@ -127,7 +137,7 @@
         elif sub_tree:
             mutter("%r is a bzr tree" %f)
         else:
-            count += __add_one(branch, inv, rf, kind, reporter)
+            count += __add_one(branch, inv, rf, kind, action)
 
         if kind == 'directory' and recurse and not sub_tree:
             for subf in os.listdir(af):
@@ -148,7 +158,7 @@
 
     return count
 
-def __add_one(branch, inv, path, kind, reporter):
+def __add_one(branch, inv, path, kind, action):
     """Add a file or directory, automatically add unversioned parents."""
 
     # Nothing to do if path is already versioned.
@@ -158,10 +168,7 @@
         return 0
 
     # add parent
-    count = __add_one(branch, inv, dirname(path), 'directory', reporter)
-
-    entry = inv.add_path(path, kind=kind)
-    mutter("added %r kind %r file_id={%s}" % (path, kind, entry.file_id))
-    reporter(path, kind, entry)
+    count = __add_one(branch, inv, dirname(path), 'directory', action)
+    action(inv, path, kind)
 
     return count + 1

=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py
+++ bzrlib/builtins.py
@@ -152,12 +152,18 @@
     get added when you add a file in the directory.
     """
     takes_args = ['file*']
-    takes_options = ['verbose', 'no-recurse']
-    
-    def run(self, file_list, verbose=False, no_recurse=False):
+    takes_options = ['verbose', 'no-recurse', 'dry-run']
+    
+    def run(self, file_list, verbose=False, no_recurse=False, dry_run=False):
+        import bzrlib.add
+
         # verbose currently has no effect
-        from bzrlib.add import smart_add, add_reporter_print
-        smart_add(file_list, not no_recurse, add_reporter_print)
+
+        action = bzrlib.add.add_action_add_and_print
+        if dry_run:
+            action = bzrlib.add.add_action_print
+
+        bzrlib.add.smart_add(file_list, not no_recurse, action)
 
 
 

=== modified file 'bzrlib/commands.py'
--- bzrlib/commands.py
+++ bzrlib/commands.py
@@ -375,6 +375,7 @@
     'no-backup':              None,
     'merge-type':             get_merge_type,
     'pattern':                str,
+    'dry-run':                None,
     }
 
 SHORT_OPTIONS = {

=== modified file 'bzrlib/selftest/test_merge_core.py'
--- bzrlib/selftest/test_merge_core.py
+++ bzrlib/selftest/test_merge_core.py
@@ -470,13 +470,13 @@
 
     def test_trivial_star_merge(self):
         """Test that merges in a star shape Just Work.""" 
-        from bzrlib.add import smart_add_branch, add_reporter_null
+        from bzrlib.add import smart_add_branch
         from bzrlib.branch import copy_branch
         from bzrlib.merge import merge
         # John starts a branch
         self.build_tree(("original/", "original/file1", "original/file2"))
         branch = Branch.initialize("original")
-        smart_add_branch(branch, ["original"], True, add_reporter_null)
+        smart_add_branch(branch, ["original"])
         branch.commit("start branch.", verbose=False)
         # Mary branches it.
         self.build_tree(("mary/",))

=== modified file 'bzrlib/selftest/test_smart_add.py'
--- bzrlib/selftest/test_smart_add.py
+++ bzrlib/selftest/test_smart_add.py
@@ -13,7 +13,7 @@
         paths = ("original/", "original/file1", "original/file2")
         self.build_tree(paths)
         branch = Branch.initialize(".")
-        smart_add((".",), recurse=True)
+        smart_add((".",))
         for path in paths:
             self.assertNotEqual(branch.inventory.path2id(path), None)
 
@@ -24,7 +24,7 @@
         self.build_tree(paths)
         branch = Branch.initialize(".")
         os.chdir("original")
-        smart_add((".",), recurse=True)
+        smart_add((".",))
         for path in paths:
             self.assertNotEqual(branch.inventory.path2id(path), None)
 
@@ -42,7 +42,7 @@
 
     def test_add_above_tree_preserves_tree(self):
         """Test nested trees are not affect by an add above them."""
-        from bzrlib.add import smart_add, add_reporter_null
+        from bzrlib.add import smart_add
         
         paths = ("original/", "original/file1", "original/file2")
         child_paths = ("path",)
@@ -53,7 +53,7 @@
         self.build_tree(build_paths)
         branch = Branch.initialize(".")
         child_branch = Branch.initialize("original/child")
-        smart_add((".",), True, add_reporter_null)
+        smart_add((".",))
         for path in paths:
             self.assertNotEqual((path, branch.inventory.path2id(path)),
                                 (path, None))
@@ -140,21 +140,34 @@
         for path in paths:
             self.assertNotEqual(branch.inventory.path2id(path), None)
 
-class TestAddCallbacks(TestCaseInTempDir):
+class TestAddActions(TestCaseInTempDir):
 
-    def setUp(self):
-        from bzrlib.inventory import InventoryEntry
-        super(TestAddCallbacks, self).setUp()
-        self.entry = InventoryEntry("id", "name", "file", None)
+    def test_null(self):
+        from bzrlib.add import add_action_null
+        self.run_action(add_action_null, "", False)
 
-    def test_null_callback(self):
-        from bzrlib.add import add_reporter_null
-        add_reporter_null('path', 'file', self.entry)
+    def test_add(self):
+        from bzrlib.add import add_action_add
+        self.run_action(add_action_add, "", True)
 
-    def test_print_callback(self):
-        from bzrlib.add import add_reporter_print
+    def test_add_and_print(self):
+        from bzrlib.add import add_action_add_and_print
+        self.run_action(add_action_add_and_print, "added path\n", True)
+
+    def test_print(self):
+        from bzrlib.add import add_action_print
+        self.run_action(add_action_print, "added path\n", False)
+
+    def run_action(self, action, output, should_add):
         from StringIO import StringIO
+        from bzrlib.inventory import Inventory
+        inv = Inventory()
         stdout = StringIO()
-        self.apply_redirected(None, stdout, None, add_reporter_print,
-                              'path', 'file', self.entry)
-        self.assertEqual(stdout.getvalue(), "added path\n")
+
+        self.apply_redirected(None, stdout, None, action, inv, 'path', 
'file')
+        self.assertEqual(stdout.getvalue(), output)
+
+        if should_add:
+            self.assertNotEqual(inv.path2id('path'), None)
+        else:
+            self.assertEqual(inv.path2id('path'), None)

=== modified file 'bzrlib/selftest/versioning.py'
--- bzrlib/selftest/versioning.py
+++ bzrlib/selftest/versioning.py
@@ -120,6 +120,19 @@
         eq(list(b.unknowns()), ['inertiatic/esp'])
         run_bzr(['add', 'inertiatic/esp'])
         eq(list(b.unknowns()), [])
+
+    def test_add_dry_run(self):
+        """Test a dry run add, make sure nothing is added."""
+        from bzrlib.branch import Branch
+        from bzrlib.commands import run_bzr
+        eq = self.assertEqual
+
+        b = Branch.initialize('.')
+
+        self.build_tree(['inertiatic/', 'inertiatic/esp'])
+        eq(list(b.unknowns()), ['inertiatic'])
+        run_bzr(['add', '--dry-run', '.'])
+        eq(list(b.unknowns()), ['inertiatic'])
 
     def test_subdir_add(self):
         """Add in subdirectory should add only things from there down"""

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20050917/260b0533/attachment.pgp 


More information about the bazaar mailing list