summaryrefslogtreecommitdiffstats
path: root/Tools/Scripts/webkitpy/common/checkout/scm.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/common/checkout/scm.py')
-rw-r--r--Tools/Scripts/webkitpy/common/checkout/scm.py60
1 files changed, 42 insertions, 18 deletions
diff --git a/Tools/Scripts/webkitpy/common/checkout/scm.py b/Tools/Scripts/webkitpy/common/checkout/scm.py
index 3f77043..421c0dc 100644
--- a/Tools/Scripts/webkitpy/common/checkout/scm.py
+++ b/Tools/Scripts/webkitpy/common/checkout/scm.py
@@ -36,6 +36,7 @@ import shutil
from webkitpy.common.system.executive import Executive, run_command, ScriptError
from webkitpy.common.system.deprecated_logging import error, log
+import webkitpy.common.system.ospath as ospath
from webkitpy.common.memoized import memoized
@@ -52,7 +53,7 @@ def find_checkout_root():
return None
-def default_scm():
+def default_scm(patch_directories=None):
"""Return the default SCM object as determined by the CWD and running code.
Returns the default SCM object for the current working directory; if the
@@ -62,10 +63,10 @@ def default_scm():
"""
cwd = os.getcwd()
- scm_system = detect_scm_system(cwd)
+ scm_system = detect_scm_system(cwd, patch_directories)
if not scm_system:
script_directory = os.path.dirname(os.path.abspath(__file__))
- scm_system = detect_scm_system(script_directory)
+ scm_system = detect_scm_system(script_directory, patch_directories)
if scm_system:
log("The current directory (%s) is not a WebKit checkout, using %s" % (cwd, scm_system.checkout_root))
else:
@@ -73,11 +74,14 @@ def default_scm():
return scm_system
-def detect_scm_system(path):
+def detect_scm_system(path, patch_directories=None):
absolute_path = os.path.abspath(path)
+ if patch_directories == []:
+ patch_directories = None
+
if SVN.in_working_directory(absolute_path):
- return SVN(cwd=absolute_path)
+ return SVN(cwd=absolute_path, patch_directories=patch_directories)
if Git.in_working_directory(absolute_path):
return Git(cwd=absolute_path)
@@ -141,16 +145,16 @@ class AmbiguousCommitError(Exception):
# SCM methods are expected to return paths relative to self.checkout_root.
class SCM:
- def __init__(self, cwd):
+ def __init__(self, cwd, executive=None):
self.cwd = cwd
self.checkout_root = self.find_checkout_root(self.cwd)
self.dryrun = False
+ self._executive = executive or Executive()
# A wrapper used by subclasses to create processes.
def run(self, args, cwd=None, input=None, error_handler=None, return_exit_code=False, return_stderr=True, decode_output=True):
# FIXME: We should set cwd appropriately.
- # FIXME: We should use Executive.
- return run_command(args,
+ return self._executive.run_command(args,
cwd=cwd,
input=input,
error_handler=error_handler,
@@ -262,7 +266,7 @@ class SCM:
def display_name(self):
self._subclass_must_implement()
- def create_patch(self, git_commit=None, changed_files=[]):
+ def create_patch(self, git_commit=None, changed_files=None):
self._subclass_must_implement()
def committer_email_for_revision(self, revision):
@@ -315,13 +319,20 @@ class SCM:
class SVN(SCM):
- # FIXME: We should move these values to a WebKit-specific config. file.
+ # FIXME: We should move these values to a WebKit-specific config file.
svn_server_host = "svn.webkit.org"
svn_server_realm = "<http://svn.webkit.org:80> Mac OS Forge"
- def __init__(self, cwd):
- SCM.__init__(self, cwd)
+ def __init__(self, cwd, patch_directories, executive=None):
+ SCM.__init__(self, cwd, executive)
self._bogus_dir = None
+ if patch_directories == []:
+ # FIXME: ScriptError is for Executive, this should probably be a normal Exception.
+ raise ScriptError(script_args=svn_info_args, message='Empty list of patch directories passed to SCM.__init__')
+ elif patch_directories == None:
+ self._patch_directories = [ospath.relpath(cwd, self.checkout_root)]
+ else:
+ self._patch_directories = patch_directories
@staticmethod
def in_working_directory(path):
@@ -427,7 +438,10 @@ class SVN(SCM):
return self.run(["svn", "delete", "--force", base], cwd=parent)
def changed_files(self, git_commit=None):
- return self.run_status_and_extract_filenames(self.status_command(), self._status_regexp("ACDMR"))
+ status_command = ["svn", "status"]
+ status_command.extend(self._patch_directories)
+ # ACDMR: Addded, Conflicted, Deleted, Modified or Replaced
+ return self.run_status_and_extract_filenames(status_command, self._status_regexp("ACDMR"))
def changed_files_for_revision(self, revision):
# As far as I can tell svn diff --summarize output looks just like svn status output.
@@ -463,10 +477,14 @@ class SVN(SCM):
return "svn"
# FIXME: This method should be on Checkout.
- def create_patch(self, git_commit=None, changed_files=[]):
+ def create_patch(self, git_commit=None, changed_files=None):
"""Returns a byte array (str()) representing the patch file.
Patch files are effectively binary since they may contain
files of multiple different encodings."""
+ if changed_files == []:
+ return ""
+ elif changed_files == None:
+ changed_files = []
return self.run([self.script_path("svn-create-patch")] + changed_files,
cwd=self.checkout_root, return_stderr=False,
decode_output=False)
@@ -574,8 +592,8 @@ class SVN(SCM):
# All git-specific logic should go here.
class Git(SCM):
- def __init__(self, cwd):
- SCM.__init__(self, cwd)
+ def __init__(self, cwd, executive=None):
+ SCM.__init__(self, cwd, executive)
self._check_git_architecture()
def _machine_is_64bit(self):
@@ -688,7 +706,10 @@ class Git(SCM):
return self.remote_merge_base()
def changed_files(self, git_commit=None):
+ # FIXME: --diff-filter could be used to avoid the "extract_filenames" step.
status_command = ['git', 'diff', '-r', '--name-status', '-C', '-M', "--no-ext-diff", "--full-index", self.merge_base(git_commit)]
+ # FIXME: I'm not sure we're returning the same set of files that SVN.changed_files is.
+ # Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
return self.run_status_and_extract_filenames(status_command, self._status_regexp("ADM"))
def _changes_files_for_commit(self, git_commit):
@@ -725,11 +746,14 @@ class Git(SCM):
def display_name(self):
return "git"
- def create_patch(self, git_commit=None, changed_files=[]):
+ def create_patch(self, git_commit=None, changed_files=None):
"""Returns a byte array (str()) representing the patch file.
Patch files are effectively binary since they may contain
files of multiple different encodings."""
- return self.run(['git', 'diff', '--binary', "--no-ext-diff", "--full-index", "-M", self.merge_base(git_commit), "--"] + changed_files, decode_output=False, cwd=self.checkout_root)
+ command = ['git', 'diff', '--binary', "--no-ext-diff", "--full-index", "-M", self.merge_base(git_commit), "--"]
+ if changed_files:
+ command += changed_files
+ return self.run(command, decode_output=False, cwd=self.checkout_root)
def _run_git_svn_find_rev(self, arg):
# git svn find-rev always exits 0, even when the revision or commit is not found.