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

Side by Side Diff: gclient.py

Issue 99226: Pull gclient revision 72 and add the gclient unit test. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 11 years, 7 months 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 | Annotate | Revision Log
« no previous file with comments | « README.gclient ('k') | tests/README.gclient_test » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright 2008 Google Inc. All Rights Reserved. 3 # Copyright 2008 Google Inc. All Rights Reserved.
4 # 4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License. 6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at 7 # You may obtain a copy of the License at
8 # 8 #
9 # http://www.apache.org/licenses/LICENSE-2.0 9 # http://www.apache.org/licenses/LICENSE-2.0
10 # 10 #
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 import os 71 import os
72 import re 72 import re
73 import stat 73 import stat
74 import subprocess 74 import subprocess
75 import sys 75 import sys
76 import time 76 import time
77 import urlparse 77 import urlparse
78 import xml.dom.minidom 78 import xml.dom.minidom
79 import urllib 79 import urllib
80 80
81 def getText(nodelist):
82 """
83 Return the concatenated text for the children of a list of DOM nodes.
84 """
85 rc = []
86 for node in nodelist:
87 if node.nodeType == node.TEXT_NODE:
88 rc.append(node.data)
89 else:
90 rc.append(getText(node.childNodes))
91 return ''.join(rc)
92
93 81
94 SVN_COMMAND = "svn" 82 SVN_COMMAND = "svn"
95 83
96 84
97 # default help text 85 # default help text
98 DEFAULT_USAGE_TEXT = ( 86 DEFAULT_USAGE_TEXT = (
99 """usage: %prog <subcommand> [options] [--] [svn options/args...] 87 """usage: %prog <subcommand> [options] [--] [svn options/args...]
100 a wrapper for managing a set of client modules in svn. 88 a wrapper for managing a set of client modules in svn.
101 Version """ + __version__ + """ 89 Version """ + __version__ + """
102 90
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 }, 252 },
265 \"safesync_url\": \"%s\" 253 \"safesync_url\": \"%s\"
266 } 254 }
267 ] 255 ]
268 """) 256 """)
269 257
270 258
271 ## Generic utils 259 ## Generic utils
272 260
273 261
262 def getText(nodelist):
263 """
264 Return the concatenated text for the children of a list of DOM nodes.
265 """
266 rc = []
267 for node in nodelist:
268 if node.nodeType == node.TEXT_NODE:
269 rc.append(node.data)
270 else:
271 rc.append(getText(node.childNodes))
272 return ''.join(rc)
273
274
275 def ParseXML(output):
276 try:
277 return xml.dom.minidom.parseString(output)
278 except xml.parsers.expat.ExpatError:
279 return None
280
281
274 class Error(Exception): 282 class Error(Exception):
275 """gclient exception class.""" 283 """gclient exception class."""
276 pass 284 pass
277 285
278 class PrintableObject(object): 286 class PrintableObject(object):
279 def __str__(self): 287 def __str__(self):
280 output = '' 288 output = ''
281 for i in dir(self): 289 for i in dir(self):
282 if i.startswith('__'): 290 if i.startswith('__'):
283 continue 291 continue
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 585
578 Returns: 586 Returns:
579 Int head revision 587 Int head revision
580 """ 588 """
581 info = CaptureSVN(options, ["info", "--xml", url], os.getcwd()) 589 info = CaptureSVN(options, ["info", "--xml", url], os.getcwd())
582 dom = xml.dom.minidom.parseString(info) 590 dom = xml.dom.minidom.parseString(info)
583 return int(dom.getElementsByTagName('entry')[0].getAttribute('revision')) 591 return int(dom.getElementsByTagName('entry')[0].getAttribute('revision'))
584 592
585 593
586 class FileStatus: 594 class FileStatus:
587 def __init__(self, path, text_status, props, locked, history, switched, 595 def __init__(self, path, text_status, props, history):
588 repo_locked, out_of_date): 596 self.path = path
589 self.path = path.strip()
590 self.text_status = text_status 597 self.text_status = text_status
591 self.props = props 598 self.props = props
592 self.locked = locked
593 self.history = history 599 self.history = history
594 self.switched = switched
595 self.repo_locked = repo_locked
596 self.out_of_date = out_of_date
597 600
598 def __str__(self): 601 def __str__(self):
599 return (self.text_status + self.props + self.locked + self.history + 602 # Emulate svn status 1.5 output.
600 self.switched + self.repo_locked + self.out_of_date + 603 return (self.text_status + self.props + ' ' + self.history + ' ' +
601 self.path) 604 self.path)
602 605
603 606
604 def CaptureSVNStatus(options, path): 607 def CaptureSVNStatus(options, path):
605 """Runs 'svn status' on an existing path. 608 """Runs 'svn status' on an existing path.
606 609
607 Args: 610 Args:
608 path: The directory to run svn status. 611 path: The directory to run svn status.
609 612
610 Returns: 613 Returns:
611 An array of FileStatus corresponding to the output of 'svn status' 614 An array of FileStatus corresponding to the emulated output of 'svn status'
612 """ 615 version 1.5."""
613 info = CaptureSVN(options, ["status"], path) 616 dom = ParseXML(CaptureSVN(options, ["status", "--xml"], path))
614 result = [] 617 results = []
615 if not info: 618 if dom:
616 return result 619 # /status/target/entry/(wc-status|commit|author|date)
617 for line in info.splitlines(): 620 for target in dom.getElementsByTagName('target'):
618 if line: 621 base_path = target.getAttribute('path')
619 new_item = FileStatus(line[7:], line[0:1], line[1:2], line[2:3], 622 for entry in target.getElementsByTagName('entry'):
620 line[3:4], line[4:5], line[5:6], line[6:7]) 623 file = entry.getAttribute('path')
621 result.append(new_item) 624 wc_status = entry.getElementsByTagName('wc-status')
622 return result 625 assert len(wc_status) == 1
626 # Emulate svn 1.5 status ouput...
627 statuses = [' ' for i in range(7)]
628 # Col 0
629 xml_item_status = wc_status[0].getAttribute('item')
630 if xml_item_status == 'unversioned':
631 statuses[0] = '?'
632 elif xml_item_status == 'modified':
633 statuses[0] = 'M'
634 elif xml_item_status == 'added':
635 statuses[0] = 'A'
636 elif xml_item_status == 'conflicted':
637 statuses[0] = 'C'
638 elif not xml_item_status:
639 pass
640 else:
641 raise Exception('Unknown item status "%s"; please implement me!' %
642 xml_item_status)
643 # Col 1
644 xml_props_status = wc_status[0].getAttribute('props')
645 if xml_props_status == 'modified':
646 statuses[1] = 'M'
647 elif xml_props_status == 'conflicted':
648 statuses[1] = 'C'
649 elif (not xml_props_status or xml_props_status == 'none' or
650 xml_props_status == 'normal'):
651 pass
652 else:
653 raise Exception('Unknown props status "%s"; please implement me!' %
654 xml_props_status)
655 # Col 3
656 if wc_status[0].getAttribute('copied') == 'true':
657 statuses[3] = '+'
658 item = FileStatus(file, statuses[0], statuses[1], statuses[3])
659 results.append(item)
660 return results
623 661
624 662
625 ### SCM abstraction layer 663 ### SCM abstraction layer
626 664
627 665
628 class SCMWrapper(object): 666 class SCMWrapper(object):
629 """Add necessary glue between all the supported SCM. 667 """Add necessary glue between all the supported SCM.
630 668
631 This is the abstraction layer to bind to different SCM. Since currently only 669 This is the abstraction layer to bind to different SCM. Since currently only
632 subversion is supported, a lot of subersionism remains. This can be sorted out 670 subversion is supported, a lot of subersionism remains. This can be sorted out
633 once another SCM is supported.""" 671 once another SCM is supported."""
634 def __init__(self, url=None, root_dir=None, relpath=None, 672 def __init__(self, url=None, root_dir=None, relpath=None,
635 scm_name='svn'): 673 scm_name='svn'):
636 # TODO(maruel): Deduce the SCM from the url. 674 # TODO(maruel): Deduce the SCM from the url.
637 self.scm_name = scm_name 675 self.scm_name = scm_name
638 self.url = url 676 self.url = url
639 self._root_dir = root_dir 677 self._root_dir = root_dir
640 if self._root_dir: 678 if self._root_dir:
641 self._root_dir = self._root_dir.replace('/', os.sep).strip() 679 self._root_dir = self._root_dir.replace('/', os.sep)
642 self.relpath = relpath 680 self.relpath = relpath
643 if self.relpath: 681 if self.relpath:
644 self.relpath = self.relpath.replace('/', os.sep).strip() 682 self.relpath = self.relpath.replace('/', os.sep)
645 683
646 def FullUrlForRelativeUrl(self, url): 684 def FullUrlForRelativeUrl(self, url):
647 # Find the forth '/' and strip from there. A bit hackish. 685 # Find the forth '/' and strip from there. A bit hackish.
648 return '/'.join(self.url.split('/')[:4]) + url 686 return '/'.join(self.url.split('/')[:4]) + url
649 687
650 def RunCommand(self, command, options, args, file_list=None): 688 def RunCommand(self, command, options, args, file_list=None):
651 # file_list will have all files that are modified appended to it. 689 # file_list will have all files that are modified appended to it.
652 690
653 if file_list == None: 691 if file_list == None:
654 file_list = [] 692 file_list = []
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1678
1641 if "__main__" == __name__: 1679 if "__main__" == __name__:
1642 try: 1680 try:
1643 result = Main(sys.argv) 1681 result = Main(sys.argv)
1644 except Error, e: 1682 except Error, e:
1645 print "Error: %s" % str(e) 1683 print "Error: %s" % str(e)
1646 result = 1 1684 result = 1
1647 sys.exit(result) 1685 sys.exit(result)
1648 1686
1649 # vim: ts=2:sw=2:tw=80:et: 1687 # vim: ts=2:sw=2:tw=80:et:
OLDNEW
« no previous file with comments | « README.gclient ('k') | tests/README.gclient_test » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698