Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Side by Side Diff: gclient_scm.py

Issue 507070: Add gclient_scm.GitWrapper.pack() (Closed)
Patch Set: Cleaner path join Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Gclient-specific SCM-specific operations.""" 5 """Gclient-specific SCM-specific operations."""
6 6
7 import logging 7 import logging
8 import os 8 import os
9 import posixpath
9 import re 10 import re
10 import subprocess 11 import subprocess
11 12
12 import scm 13 import scm
13 import gclient_utils 14 import gclient_utils
14 15
15 16
17 class DiffFilterer(object):
18 """Simple class which tracks which file is being diffed and
19 replaces instances of its file name in the original and
20 working copy lines of the svn diff output."""
21 index_string = "Index: "
22 original_prefix = "--- "
23 working_prefix = "+++ "
24
25 def __init__(self, relpath):
26 # Note that we always use '/' as the path separator to be
27 # consistent with svn's cygwin-style output on Windows
28 self._relpath = relpath.replace("\\", "/")
29 self._current_file = ""
30 self._replacement_file = ""
31
32 def SetCurrentFile(self, file):
33 self._current_file = file
34 # Note that we always use '/' as the path separator to be
35 # consistent with svn's cygwin-style output on Windows
36 self._replacement_file = posixpath.join(self._relpath, file)
37
38 def ReplaceAndPrint(self, line):
39 print(line.replace(self._current_file, self._replacement_file))
40
41 def Filter(self, line):
42 if (line.startswith(self.index_string)):
43 self.SetCurrentFile(line[len(self.index_string):])
44 self.ReplaceAndPrint(line)
45 else:
46 if (line.startswith(self.original_prefix) or
47 line.startswith(self.working_prefix)):
48 self.ReplaceAndPrint(line)
49 else:
50 print line
51
52
16 ### SCM abstraction layer 53 ### SCM abstraction layer
17 54
18 # Factory Method for SCM wrapper creation 55 # Factory Method for SCM wrapper creation
19 56
20 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'): 57 def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'):
21 # TODO(maruel): Deduce the SCM from the url. 58 # TODO(maruel): Deduce the SCM from the url.
22 scm_map = { 59 scm_map = {
23 'svn' : SVNWrapper, 60 'svn' : SVNWrapper,
24 'git' : GitWrapper, 61 'git' : GitWrapper,
25 } 62 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 if file_list is None: 99 if file_list is None:
63 file_list = [] 100 file_list = []
64 101
65 commands = ['cleanup', 'export', 'update', 'revert', 'revinfo', 102 commands = ['cleanup', 'export', 'update', 'revert', 'revinfo',
66 'status', 'diff', 'pack', 'runhooks'] 103 'status', 'diff', 'pack', 'runhooks']
67 104
68 if not command in commands: 105 if not command in commands:
69 raise gclient_utils.Error('Unknown command %s' % command) 106 raise gclient_utils.Error('Unknown command %s' % command)
70 107
71 if not command in dir(self): 108 if not command in dir(self):
72 raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % ( 109 raise gclient_utils.Error('Command %s not implemented in %s wrapper' % (
73 command, self.scm_name)) 110 command, self.scm_name))
74 111
75 return getattr(self, command)(options, args, file_list) 112 return getattr(self, command)(options, args, file_list)
76 113
77 114
78 class GitWrapper(SCMWrapper, scm.GIT): 115 class GitWrapper(SCMWrapper, scm.GIT):
79 """Wrapper for Git""" 116 """Wrapper for Git"""
80 117
81 def cleanup(self, options, args, file_list): 118 def cleanup(self, options, args, file_list):
82 """Cleanup working copy.""" 119 """Cleanup working copy."""
83 __pychecker__ = 'unusednames=args,file_list,options' 120 __pychecker__ = 'unusednames=args,file_list,options'
84 self._Run(['prune'], redirect_stdout=False) 121 self._Run(['prune'], redirect_stdout=False)
85 self._Run(['fsck'], redirect_stdout=False) 122 self._Run(['fsck'], redirect_stdout=False)
86 self._Run(['gc'], redirect_stdout=False) 123 self._Run(['gc'], redirect_stdout=False)
87 124
88 def diff(self, options, args, file_list): 125 def diff(self, options, args, file_list):
89 __pychecker__ = 'unusednames=args,file_list,options' 126 __pychecker__ = 'unusednames=args,file_list,options'
90 merge_base = self._Run(['merge-base', 'HEAD', 'origin']) 127 merge_base = self._Run(['merge-base', 'HEAD', 'origin'])
91 self._Run(['diff', merge_base], redirect_stdout=False) 128 self._Run(['diff', merge_base], redirect_stdout=False)
92 129
93 def export(self, options, args, file_list): 130 def export(self, options, args, file_list):
94 __pychecker__ = 'unusednames=file_list,options' 131 __pychecker__ = 'unusednames=file_list,options'
95 assert len(args) == 1 132 assert len(args) == 1
96 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) 133 export_path = os.path.abspath(os.path.join(args[0], self.relpath))
97 if not os.path.exists(export_path): 134 if not os.path.exists(export_path):
98 os.makedirs(export_path) 135 os.makedirs(export_path)
99 self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path], 136 self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path],
100 redirect_stdout=False) 137 redirect_stdout=False)
101 138
139 def pack(self, options, args, file_list):
140 """Generates a patch file which can be applied to the root of the
141 repository."""
142 __pychecker__ = 'unusednames=file_list,options'
143 path = os.path.join(self._root_dir, self.relpath)
144 merge_base = self._Run(['merge-base', 'HEAD', 'origin'])
145 command = ['diff', merge_base]
146 filterer = DiffFilterer(self.relpath)
147 self.RunAndFilterOutput(command, path, False, False, filterer.Filter)
148
102 def update(self, options, args, file_list): 149 def update(self, options, args, file_list):
103 """Runs git to update or transparently checkout the working copy. 150 """Runs git to update or transparently checkout the working copy.
104 151
105 All updated files will be appended to file_list. 152 All updated files will be appended to file_list.
106 153
107 Raises: 154 Raises:
108 Error: if can't get URL for relative path. 155 Error: if can't get URL for relative path.
109 """ 156 """
110 157
111 if args: 158 if args:
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) 318 export_path = os.path.abspath(os.path.join(args[0], self.relpath))
272 try: 319 try:
273 os.makedirs(export_path) 320 os.makedirs(export_path)
274 except OSError: 321 except OSError:
275 pass 322 pass
276 assert os.path.exists(export_path) 323 assert os.path.exists(export_path)
277 command = ['export', '--force', '.'] 324 command = ['export', '--force', '.']
278 command.append(export_path) 325 command.append(export_path)
279 self.Run(command, os.path.join(self._root_dir, self.relpath)) 326 self.Run(command, os.path.join(self._root_dir, self.relpath))
280 327
328 def pack(self, options, args, file_list):
329 """Generates a patch file which can be applied to the root of the
330 repository."""
331 __pychecker__ = 'unusednames=file_list,options'
332 path = os.path.join(self._root_dir, self.relpath)
333 command = ['diff']
334 command.extend(args)
335
336 filterer = DiffFilterer(self.relpath)
337 self.RunAndFilterOutput(command, path, False, False, filterer.Filter)
338
281 def update(self, options, args, file_list): 339 def update(self, options, args, file_list):
282 """Runs SCM to update or transparently checkout the working copy. 340 """Runs SCM to update or transparently checkout the working copy.
283 341
284 All updated files will be appended to file_list. 342 All updated files will be appended to file_list.
285 343
286 Raises: 344 Raises:
287 Error: if can't get URL for relative path. 345 Error: if can't get URL for relative path.
288 """ 346 """
289 # Only update if git is not controlling the directory. 347 # Only update if git is not controlling the directory.
290 checkout_path = os.path.join(self._root_dir, self.relpath) 348 checkout_path = os.path.join(self._root_dir, self.relpath)
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 command = ['status'] 516 command = ['status']
459 command.extend(args) 517 command.extend(args)
460 if not os.path.isdir(path): 518 if not os.path.isdir(path):
461 # svn status won't work if the directory doesn't exist. 519 # svn status won't work if the directory doesn't exist.
462 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " 520 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory "
463 "does not exist." 521 "does not exist."
464 % (' '.join(command), path)) 522 % (' '.join(command), path))
465 # There's no file list to retrieve. 523 # There's no file list to retrieve.
466 else: 524 else:
467 self.RunAndGetFileList(options, command, path, file_list) 525 self.RunAndGetFileList(options, command, path, file_list)
468
469 def pack(self, options, args, file_list):
470 """Generates a patch file which can be applied to the root of the
471 repository."""
472 __pychecker__ = 'unusednames=file_list,options'
473 path = os.path.join(self._root_dir, self.relpath)
474 command = ['diff']
475 command.extend(args)
476 # Simple class which tracks which file is being diffed and
477 # replaces instances of its file name in the original and
478 # working copy lines of the svn diff output.
479 class DiffFilterer(object):
480 index_string = "Index: "
481 original_prefix = "--- "
482 working_prefix = "+++ "
483
484 def __init__(self, relpath):
485 # Note that we always use '/' as the path separator to be
486 # consistent with svn's cygwin-style output on Windows
487 self._relpath = relpath.replace("\\", "/")
488 self._current_file = ""
489 self._replacement_file = ""
490
491 def SetCurrentFile(self, file):
492 self._current_file = file
493 # Note that we always use '/' as the path separator to be
494 # consistent with svn's cygwin-style output on Windows
495 self._replacement_file = self._relpath + '/' + file
496
497 def ReplaceAndPrint(self, line):
498 print(line.replace(self._current_file, self._replacement_file))
499
500 def Filter(self, line):
501 if (line.startswith(self.index_string)):
502 self.SetCurrentFile(line[len(self.index_string):])
503 self.ReplaceAndPrint(line)
504 else:
505 if (line.startswith(self.original_prefix) or
506 line.startswith(self.working_prefix)):
507 self.ReplaceAndPrint(line)
508 else:
509 print line
510
511 filterer = DiffFilterer(self.relpath)
512 self.RunAndFilterOutput(command, path, False, False, filterer.Filter)
OLDNEW
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698