Commits

Anonymous committed 4caaaf8

Added rope.refactor.multiproject

Comments (0)

Files changed (8)

 New Features
 ============
 
-* Asking the user about unsure occurrences
-* Better handling of symlinks in project path
-
-`Rename.get_changes()` has been changed so that the `unsure` optional
-parameter can be a function.  If it is not `None`, for each unsure
-occurrence this function is called with an instance of
-`rope.refactor.occurrence.Occurrence`; if it returns `True` the
-occurrence is renamed.
-
 
 Getting Started
 ===============

docs/dev/issues.txt

 Cross-Project Refactorings
 ==========================
 
-We might want to perform a refactoring on more than one project.
+We can add a new `MultiProjectRefactoring` class::
 
-Approach #1
------------
+  class MultiProjectRefactoring(object):
 
-Adding `ProjectBag`::
+      def __init__(self, refactoring, projects):
+          """Create a multiproject proxy for the main refactoring
 
-  class ProjectBag(object):
-      pass
+          `projects` are other project.
 
-  class PyCoreBag(object):
-      pass
+          """
 
-  class HistoryBag(object):
-      pass
+      def __call__(self, project, *args, **kwds):
+          """Create the refactoring"""
 
+      def get_all_changes(self, *args, **kwds):
+          """Get a project to changes dict"""
 
 Issues:
 
-* Implementing `ProjectBag` and `PyCoreBag`
-* Changing checks like ``resource.project == resource.no_project()``
-  with ``resource.project != project``
-* When saving objects SOI we should consider resource in other
-  projects like `NoProject` resources
-* Using history on different projects
-
-Approach #2
------------
-
-Passing all projects to refactorings:
-
-Approach #3
------------
-
-Actually we can do that even now.  What we should do is to add the
-dependency projects to the class path and try to apply the refactoring
-for each dependent project.  The dependencies don't change but the
-dependants do.  After that we can apply the refactoring on the
-dependencies.
+* Resources from other projects should be considered out of project
+* Undoing
+* Specifying the main project
+* Adding ``rope.refactor.multiproject.perform``
 
 
 Distributing Refactorings

docs/dev/todo.txt

 
 
 * Performing refactorings across multiple projects
-
-
-> Public Release 0.7.1 : November 28, 2007
 ===========
 
 
+> Public Release 0.7.1 : November 28, 2007
+
+
 - Better handling of symlinks in project path : November 27, 2007
 
 
 """rope, a python refactoring library"""
 
 INFO = __doc__
-VERSION = '0.7.1'
+VERSION = '0.7.2'
 COPYRIGHT = """\
 Copyright (C) 2006-2007 Ali Gholami Rudi
 

rope/refactor/multiproject.py

+class MultiProjectRefactoring(object):
+
+    def __init__(self, refactoring, projects):
+        """Create a multiproject proxy for the main refactoring
+
+        `projects` are other project.
+
+        """
+        self.refactoring = refactoring
+        self.projects = projects
+
+    def __call__(self, project, *args, **kwds):
+        """Create the refactoring"""
+        self.project = project
+        self.main_refactoring = self.refactoring(project, *args, **kwds)
+        self.other_refactorings = [self.refactoring(other, *args, **kwds)
+                                   for project in self.projects]
+        return self
+
+    def get_all_changes(self, *args, **kwds):
+        """Get a project to changes dict"""
+        result = []
+        for project, refactoring in zip(self.projects,
+                                        self.other_refactorings):
+            result.append((project, refactoring.get_changes(*args, **kwds)))
+        result.append((self.project,
+                       self.main_refactoring.get_changes(*args, **kwds)))
+        return result
+
+    def __getattr__(self, name):
+        return getattr(self.main_refactoring, name)
+
+
+def perform(project_changes):
+    for project, changes in project_changes:
+        project.do(changes)

ropetest/refactor/multiprojecttest.py

+import unittest
+
+import rope.base.codeanalyze
+import rope.refactor.occurrences
+from rope.refactor import multiproject, rename
+from ropetest import testutils
+
+
+class MultiProjectRefactoringTest(unittest.TestCase):
+
+    def setUp(self):
+        super(MultiProjectRefactoringTest, self).setUp()
+        self.project1 = testutils.sample_project(foldername='testproject1')
+        self.project2 = testutils.sample_project(
+            foldername='testproject2', python_path=self.project1.address)
+        self.mod1 = self.project1.root.create_file('mod1.py')
+        self.mod2 = self.project2.root.create_file('mod2.py')
+
+    def tearDown(self):
+        testutils.remove_project(self.project1)
+        testutils.remove_project(self.project2)
+        super(MultiProjectRefactoringTest, self).tearDown()
+
+    def test_simple_rename(self):
+        self.mod1.write('var = 1\n')
+        refactoring = multiproject.MultiProjectRefactoring(
+            rename.Rename, [])
+        renamer = refactoring(self.project1, self.mod1, 1)
+        multiproject.perform(renamer.get_all_changes('newvar'))
+        self.assertEquals('newvar = 1\n', self.mod1.read())
+
+
+if __name__ == '__main__':
+    unittest.main()

ropetest/testutils.py

 import rope.base.project
 
 
-def sample_project(root=None, **kwds):
+def sample_project(root=None, foldername=None, **kwds):
     if root is None:
         root = 'sample_project'
+        if foldername:
+            root = foldername
         # HACK: Using ``/dev/shm/`` for faster tests
         if os.name == 'posix' and os.path.isdir('/dev/shm'):
             root = '/dev/shm/' + root