How to use positional_args method in Slash

Best Python code snippet using slash

svn_cmd.py

Source:svn_cmd.py Github

copy

Full Screen

1'''2 ====================================================================3 Copyright (c) 2003-2009 Barry A Scott. All rights reserved.4 This software is licensed as described in the file LICENSE.txt,5 which you should have received as part of this distribution.6 ====================================================================7'''8import pysvn9import time10import sys11import os12import parse_datetime13import glob14import locale15import types16if sys.version_info.major == 2:17 # suport cp65001 aka utf-818 import codecs19 codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)20try:21 sorted( [] )22except NameError:23 def sorted( list_in ):24 list_out = list( list_in )25 list_out.sort()26 return list_out27if hasattr( types, 'StringTypes' ):28 StringTypes = types.StringTypes29else:30 StringTypes = [type( '' )]31if hasattr( types, 'DictType' ):32 DictType = types.DictType33else:34 DictType = type( {} )35class CommandError( Exception ):36 def __init__( self, reason ):37 Exception.__init__( self )38 self._reason = reason39 def reason( self ):40 return self._reason41 def __str__( self ):42 return self._reason43def main( args ):44 progname = os.path.basename( args[0] )45 pause = False46 if args[1:2] == ['--pause']:47 del args[1]48 pause = True49 # if the locale is not setup SVN can report errors handling non ascii file names50 initLocale()51 svn_cmd = SvnCommand( progname )52 rc = svn_cmd.dispatch( args[1:] )53 if pause:54 sys.stdin.readline()55 return rc56def initLocale():57 # init the locale58 if sys.platform in ['win32','cygwin']:59 locale.setlocale( locale.LC_ALL, '' )60 else:61 language_code, encoding = locale.getdefaultlocale()62 if language_code is None:63 language_code = 'en_GB'64 if encoding is None:65 encoding = 'UTF-8'66 if encoding.lower() == 'utf':67 encoding = 'UTF-8'68 try:69 # setlocale fails when params it does not understand are passed70 locale.setlocale( locale.LC_ALL, '%s.%s' % (language_code, encoding) )71 except locale.Error:72 # force a locale that will work73 locale.setlocale( locale.LC_ALL, 'en_GB.UTF-8' )74def fmtDateTime( t ):75 return time.strftime( '%d-%b-%Y %H:%M:%S', time.localtime( t ) )76wc_status_kind_map = {77pysvn.wc_status_kind.added: 'A',78pysvn.wc_status_kind.conflicted: 'C',79pysvn.wc_status_kind.deleted: 'D',80pysvn.wc_status_kind.external: 'X',81pysvn.wc_status_kind.ignored: 'I',82pysvn.wc_status_kind.incomplete: '!',83pysvn.wc_status_kind.missing: '!',84pysvn.wc_status_kind.merged: 'G',85pysvn.wc_status_kind.modified: 'M',86pysvn.wc_status_kind.none: ' ',87pysvn.wc_status_kind.normal: ' ',88pysvn.wc_status_kind.obstructed: '~',89pysvn.wc_status_kind.replaced: 'R',90pysvn.wc_status_kind.unversioned: '?',91}92wc_notify_action_map = {93pysvn.wc_notify_action.add: 'A',94pysvn.wc_notify_action.commit_added: 'A',95pysvn.wc_notify_action.commit_deleted: 'D',96pysvn.wc_notify_action.commit_modified: 'M',97pysvn.wc_notify_action.commit_postfix_txdelta: None,98pysvn.wc_notify_action.commit_replaced: 'R',99pysvn.wc_notify_action.copy: 'c',100pysvn.wc_notify_action.delete: 'D',101pysvn.wc_notify_action.failed_revert: 'F',102pysvn.wc_notify_action.resolved: 'R',103pysvn.wc_notify_action.restore: 'R',104pysvn.wc_notify_action.revert: 'R',105pysvn.wc_notify_action.skip: 'skip',106pysvn.wc_notify_action.status_completed: None,107pysvn.wc_notify_action.status_external: 'X',108pysvn.wc_notify_action.update_add: 'A',109pysvn.wc_notify_action.update_completed: None,110pysvn.wc_notify_action.update_delete: 'D',111pysvn.wc_notify_action.update_external: 'X',112pysvn.wc_notify_action.update_update: 'U',113pysvn.wc_notify_action.annotate_revision: 'A',114}115# new in svn 1.4?116if hasattr( pysvn.wc_notify_action, 'locked' ):117 wc_notify_action_map[ pysvn.wc_notify_action.locked ] = 'locked'118 wc_notify_action_map[ pysvn.wc_notify_action.unlocked ] = 'unlocked'119 wc_notify_action_map[ pysvn.wc_notify_action.failed_lock ] = 'failed_lock'120 wc_notify_action_map[ pysvn.wc_notify_action.failed_unlock ] = 'failed_unlock'121# new in svn 1.5122if hasattr( pysvn.wc_notify_action, 'exists' ):123 wc_notify_action_map[ pysvn.wc_notify_action.exists ] = 'exists'124 wc_notify_action_map[ pysvn.wc_notify_action.changelist_set ] = 'changelist_set'125 wc_notify_action_map[ pysvn.wc_notify_action.changelist_clear ] = 'changelist_clear'126 wc_notify_action_map[ pysvn.wc_notify_action.changelist_moved ] = 'changelist_moved'127 wc_notify_action_map[ pysvn.wc_notify_action.foreign_merge_begin ] = 'foreign_merge_begin'128 wc_notify_action_map[ pysvn.wc_notify_action.merge_begin ] = 'merge_begin'129 wc_notify_action_map[ pysvn.wc_notify_action.update_replace ] = 'update_replace'130# new in svn 1.6131if hasattr( pysvn.wc_notify_action, 'property_added' ):132 wc_notify_action_map[ pysvn.wc_notify_action.property_added ] = 'property_added'133 wc_notify_action_map[ pysvn.wc_notify_action.property_modified ] = 'property_modified'134 wc_notify_action_map[ pysvn.wc_notify_action.property_deleted ] = 'property_deleted'135 wc_notify_action_map[ pysvn.wc_notify_action.property_deleted_nonexistent ] = 'property_deleted_nonexistent'136 wc_notify_action_map[ pysvn.wc_notify_action.revprop_set ] = 'revprop_set'137 wc_notify_action_map[ pysvn.wc_notify_action.revprop_deleted ] = 'revprop_deleted'138 wc_notify_action_map[ pysvn.wc_notify_action.merge_completed ] = 'merge_completed'139 wc_notify_action_map[ pysvn.wc_notify_action.tree_conflict ] = 'tree_conflict'140 wc_notify_action_map[ pysvn.wc_notify_action.failed_external ] = 'failed_external'141# new in svn 1.7142if hasattr( pysvn.wc_notify_action, 'update_started' ):143 wc_notify_action_map[ pysvn.wc_notify_action.update_started ] = 'update_started'144 wc_notify_action_map[ pysvn.wc_notify_action.update_skip_obstruction ] = 'update_skip_obstruction'145 wc_notify_action_map[ pysvn.wc_notify_action.update_skip_working_only ] = 'update_skip_working_only'146 wc_notify_action_map[ pysvn.wc_notify_action.update_external_removed ] = 'update_external_removed'147 wc_notify_action_map[ pysvn.wc_notify_action.update_shadowed_add ] = 'update_shadowed_add'148 wc_notify_action_map[ pysvn.wc_notify_action.update_shadowed_update ] = 'update_shadowed_update'149 wc_notify_action_map[ pysvn.wc_notify_action.update_shadowed_delete ] = 'update_shadowed_delete'150 wc_notify_action_map[ pysvn.wc_notify_action.merge_record_info ] = 'merge_record_info'151 wc_notify_action_map[ pysvn.wc_notify_action.upgraded_path ] = 'upgraded_path'152 wc_notify_action_map[ pysvn.wc_notify_action.merge_record_info_begin ] = 'merge_record_info_begin'153 wc_notify_action_map[ pysvn.wc_notify_action.merge_elide_info ] = 'merge_elide_info'154 wc_notify_action_map[ pysvn.wc_notify_action.patch ] = 'patch'155 wc_notify_action_map[ pysvn.wc_notify_action.patch_applied_hunk ] = 'patch_applied_hunk'156 wc_notify_action_map[ pysvn.wc_notify_action.patch_rejected_hunk ] = 'patch_rejected_hunk'157 wc_notify_action_map[ pysvn.wc_notify_action.patch_hunk_already_applied ] = 'patch_hunk_already_applied'158 wc_notify_action_map[ pysvn.wc_notify_action.commit_copied ] = 'commit_copied'159 wc_notify_action_map[ pysvn.wc_notify_action.commit_copied_replaced ] = 'commit_copied_replaced'160 wc_notify_action_map[ pysvn.wc_notify_action.url_redirect ] = 'url_redirect'161 wc_notify_action_map[ pysvn.wc_notify_action.path_nonexistent ] = 'path_nonexistent'162 wc_notify_action_map[ pysvn.wc_notify_action.exclude ] = 'exclude'163 wc_notify_action_map[ pysvn.wc_notify_action.failed_conflict ] = 'failed_conflict'164 wc_notify_action_map[ pysvn.wc_notify_action.failed_missing ] = 'failed_missing'165 wc_notify_action_map[ pysvn.wc_notify_action.failed_out_of_date ] = 'failed_out_of_date'166 wc_notify_action_map[ pysvn.wc_notify_action.failed_no_parent ] = 'failed_no_parent'167# new in svn 1.7.1+?168if hasattr( pysvn.wc_notify_action, 'failed_locked' ):169 wc_notify_action_map[ pysvn.wc_notify_action.failed_locked ] = 'failed_locked'170 wc_notify_action_map[ pysvn.wc_notify_action.failed_forbidden_by_server ] = 'failed_forbidden_by_server'171 wc_notify_action_map[ pysvn.wc_notify_action.skip_conflicted ] = 'skip_conflicted'172# new in svn 1.8173if hasattr( pysvn.wc_notify_action, 'update_broken_lock' ):174 wc_notify_action_map[ pysvn.wc_notify_action.update_broken_lock ] = 'update_broken_lock'175 wc_notify_action_map[ pysvn.wc_notify_action.failed_obstruction ] = 'failed_obstruction'176 wc_notify_action_map[ pysvn.wc_notify_action.conflict_resolver_starting ] = 'conflict_resolver_starting'177 wc_notify_action_map[ pysvn.wc_notify_action.conflict_resolver_done ] = 'conflict_resolver_done'178 wc_notify_action_map[ pysvn.wc_notify_action.left_local_modifications ] = 'left_local_modifications'179 wc_notify_action_map[ pysvn.wc_notify_action.foreign_copy_begin ] = 'foreign_copy_begin'180 wc_notify_action_map[ pysvn.wc_notify_action.move_broken ] = 'move_broken'181# new in svn 1.9182if hasattr( pysvn.wc_notify_action, 'cleanup_external' ):183 wc_notify_action_map[ pysvn.wc_notify_action.cleanup_external ] = 'cleanup_external'184 wc_notify_action_map[ pysvn.wc_notify_action.failed_requires_target ] = 'failed_requires_target'185 wc_notify_action_map[ pysvn.wc_notify_action.info_external ] = 'info_external'186 wc_notify_action_map[ pysvn.wc_notify_action.commit_finalizing ] = 'commit_finalizing'187class SvnCommand:188 def __init__( self, progname ):189 self.progname = progname190 self.client = None191 self.revision_update_complete = None192 self.notify_message_list = []193 self.pysvn_testing = False194 self.debug_enabled = False195 self.next_log_message = None196 def debug( self, msg, args=() ):197 if self.debug_enabled:198 print( 'Debug: %s' % (msg % args) )199 def initClient( self, config_dir ):200 self.client = pysvn.Client( config_dir )201 self.client.exception_style = 1202 self.client.commit_info_style = 1203 self.client.callback_get_login = self.callback_getLogin204 self.client.callback_get_log_message = self.callback_getLogMessage205 self.client.callback_notify = self.callback_notify206 self.client.callback_cancel = self.callback_cancel207 if hasattr( self.client, 'callback_conflict_resolver' ):208 self.client.callback_conflict_resolver = self.callback_conflict_resolver209 self.client.callback_cancel = self.callback_cancel210 self.client.callback_ssl_client_cert_password_prompt = self.callback_ssl_client_cert_password_prompt211 self.client.callback_ssl_client_cert_prompt = self.callback_ssl_client_cert_prompt212 self.client.callback_ssl_server_prompt = self.callback_ssl_server_prompt213 self.client.callback_ssl_server_trust_prompt = self.callback_ssl_server_trust_prompt214 def callback_ssl_client_cert_password_prompt( self ):215 print( 'callback_ssl_client_cert_password_prompt' )216 def callback_ssl_client_cert_prompt( self ):217 print( 'callback_ssl_client_cert_prompt' )218 def callback_ssl_server_prompt( self ):219 print( 'callback_ssl_server_prompt' )220 def callback_ssl_server_trust_prompt( self, trust_data ):221 for key,value in trust_data.items():222 print( '%s: %s' % (key, value) )223 print('')224 answer = ''225 while answer.lower() not in ['p','t','r']:226 sys.stdout.write( '(P)ermanent accept, (T)emporary accept or (R)eject: ' )227 answer = sys.stdin.readline().strip()228 if answer.lower() == 'p':229 return True, trust_data['failures'], True230 if answer.lower() == 't':231 return True, trust_data['failures'], False232 return False, 0, False233 def callback_cancel( self ):234 return False235 def callback_notify( self, arg_dict ):236 if arg_dict['action'] == pysvn.wc_notify_action.update_completed:237 self.revision_update_complete = arg_dict['revision']238 elif arg_dict['path'] != '' and wc_notify_action_map[ arg_dict['action'] ] is not None:239 msg = '%s %s' % (wc_notify_action_map[ arg_dict['action'] ], arg_dict['path'])240 if self.pysvn_testing != '99.99.99':241 self.notify_message_list.append( msg )242 else:243 print( msg )244 def callback_conflict_resolver( self, arg_dict ):245 print( 'callback_conflict_resolver' )246 for key in sorted( arg_dict.keys() ):247 value = arg_dict[ key ]248 if type(value) == DictType:249 value = '{%s}' % (', '.join( ['%r: %r' % (key, value) for key, value in sorted( value.items() )] ),)250 elif type(value) not in StringTypes:251 value = repr(value)252 print( ' %s: %s' % (key, value) )253 return pysvn.wc_conflict_choice.postpone, None, False254 def callback_getLogin( self, realm, username, may_save ):255 print( 'May save: %s ' % may_save )256 print( 'Realm: %s ' % realm )257 if username:258 print( 'Username: %s' % username )259 else:260 sys.stdout.write( 'Username: ' )261 username = sys.stdin.readline().strip()262 if len(username) == 0:263 return 0, '', '', False264 sys.stdout.write( 'Password: ' )265 password = sys.stdin.readline().strip()266 save_password = 'x'267 while save_password.lower() not in ['y','ye','yes','n', 'no','']:268 sys.stdout.write( 'Save password? [y/n] ' )269 save_password = sys.stdin.readline().strip()270 return 1, username, password, save_password in ['y','ye','yes']271 def getLogMessage( self ):272 if self.next_log_message is not None:273 message = self.next_log_message274 self.next_log_message = None275 return message276 sys.stdout.write( 'Log message\n' )277 sys.stdout.write( '--- -------\n' )278 message = sys.stdin.read()279 return message280 def callback_getLogMessage( self ):281 return True, self.getLogMessage()282 def dispatch( self, argv ):283 try:284 args = SvnArguments( argv )285 cmd_name = 'cmd_%s' % args.getCommandName( 'help' )286 self.initClient( args.getOptionalValue( '--config-dir', '' ) )287 self.client.set_auth_cache( args.getBooleanOption( '--no-auth-cache', False ) )288 self.pysvn_testing = args.getOptionalValue( '--pysvn-testing', '99.99.99' )289 self.debug_enabled = args.getBooleanOption( '--debug', True )290 getattr( self, cmd_name, self.cmd_help )( args )291 self.printNotifyMessages()292 except pysvn.ClientError as e:293 self.printNotifyMessages()294 print( e.args[0] )295 return 1296 except CommandError as e:297 self.printNotifyMessages()298 print( e.reason() )299 return 1300 return 0301 def printNotifyMessages( self ):302 # different versions of SVN notify messages in different orders303 # by sorting before printing we hope to have one set of regression304 # test data for multiple versions of SVN305 self.notify_message_list.sort()306 for msg in self.notify_message_list:307 print( msg )308 self.notify_message_list = []309 def cmd_version( self, args ):310 print( 'PYSVN Version: %r' % (pysvn.version,) )311 print( 'SVN Version: %r' % (pysvn.svn_version,) )312 if hasattr( pysvn, 'svn_api_version' ):313 print( 'SVN API Version: %r' % (pysvn.svn_api_version,) )314 print( 'pysvn._pysvn %r' % (pysvn._pysvn,) )315 def cmd_is_url( self, args ):316 path = args.getPositionalArgs( 1 )[0]317 is_url = self.client.is_url( path )318 if is_url:319 print( 'url %s' % path )320 else:321 print( 'path %s' % path )322 def cmd_add( self, args ):323 recurse = args.getBooleanOption( '--non-recursive', False )324 force = args.getBooleanOption( '--force', False )325 326 self.client.add( args.getPositionalArgs( 1 ), recurse=recurse, force=force )327 def cmd_add_to_changelist( self, args ):328 if not hasattr( self.client, add_to_changelist ):329 print( 'Error: add_to_changelist is not supported by this version of Subversion' )330 return331 path, changelist = args.getPositionalArgs( 2, 2 )332 self.client.add_to_changelist( path, changelist )333 def cmd_annotate( self, args ):334 start_revision, end_revision = args.getOptionalRevisionPair( '--revision', '0', 'head' )335 positional_args = args.getPositionalArgs( 1, 1 )336 all_lines = self.client.annotate( 337 positional_args[0],338 revision_start=start_revision,339 revision_end=end_revision )340 self.printNotifyMessages()341 for line in all_lines:342 print( '%d| r%d | %s | %s | %s' %343 (line['number']+1344 ,line['revision'].number345 ,line['author']346 ,line['date']347 ,line['line']) )348 cmd_ann = cmd_annotate349 def cmd_annotate2( self, args ):350 if not hasattr( self.client, 'annotate2' ):351 print( 'annotate2 is not available in this version of subversion' )352 return353 start_revision, end_revision = args.getOptionalRevisionPair( '--revision', '0', 'head' )354 positional_args = args.getPositionalArgs( 1, 1 )355 all_lines = self.client.annotate2(356 positional_args[0],357 revision_start=start_revision,358 revision_end=end_revision )359 self.printNotifyMessages()360 for line in all_lines:361 print( '%d| r%d | %s' %362 (line['number']+1363 ,line['revision'].number364 ,line['line']) )365 if line['merged_revision'] is not None:366 print( ' Merged from r%d %s' %367 (line['merged_revision']368 ,line['merged_path']) )369 cmd_ann2 = cmd_annotate2370 def cmd_cat( self, args ):371 revision = args.getOptionalRevision( '--revision', 'head' )372 text = self.client.cat( args.getPositionalArgs( 1, 1 )[0], revision=revision )373 print( text.decode( 'utf-8' ).replace( '\r\n', '\n' ) )374 def cmd_checkout( self, args ):375 recurse = args.getBooleanOption( '--non-recursive', False )376 positional_args = args.getPositionalArgs( 1, 2 )377 if len(positional_args) == 1:378 positional_args.append( os.path.basename( positional_args[0] ) )379 self.revision_update_complete = None380 self.client.checkout( positional_args[0], positional_args[1], recurse=recurse )381 self.printNotifyMessages()382 if self.revision_update_complete is not None:383 print( 'Checked out revision %s' % self.revision_update_complete.number )384 else:385 print( 'Checked out unknown revision - checkout failed?' )386 cmd_co = cmd_checkout387 def cmd_cleanup( self, args ):388 positional_args = args.getPositionalArgs( 0, 1 )389 if len(positional_args) == 0:390 positional_args.append( '.' )391 self.client.cleanup( positional_args[0] )392 def cmd_checkin( self, args ):393 msg = args.getOptionalValue( '--message', '' )394 recurse = args.getBooleanOption( '--non-recursive', False )395 positional_args = args.getPositionalArgs( 0 )396 if len(positional_args) == 0:397 positional_args.append( '.' )398 if msg == '':399 msg = self.getLogMessage()400 commit_info = self.client.checkin( positional_args, msg, recurse=recurse )401 rev = commit_info["revision"]402 self.printNotifyMessages()403 if commit_info['post_commit_err'] is not None:404 print( commit_info['post_commit_err'] )405 if rev is None:406 print( 'Nothing to commit' )407 elif rev.number > 0:408 print( 'Revision %s' % rev.number )409 else:410 print( 'Commit failed' )411 cmd_commit = cmd_checkin412 cmd_ci = cmd_checkin413 def cmd_copy( self, args ):414 positional_args = args.getPositionalArgs( 2, 2 )415 self.client.copy( positional_args[0], positional_args[1] )416 cmd_cp = cmd_copy417 def cmd_diff( self, args ):418 recurse = args.getBooleanOption( '--non-recursive', False )419 revision1, revision2 = args.getOptionalRevisionPair( '--revision', 'base', 'working' )420 positional_args = args.getPositionalArgs( 0, 1 )421 if len(positional_args) == 0:422 positional_args.append( '.' )423 if 'TEMP' in os.environ:424 tmpdir = os.environ['TEMP']425 elif 'TMPDIR' in os.environ:426 tmpdir = os.environ['TMPDIR']427 elif 'TMP' in os.environ:428 tmpdir = os.environ['TMP']429 elif os.path.exists( '/usr/tmp' ):430 tmpdir = '/usr/tmp'431 elif os.path.exists( '/tmp' ):432 tmpdir = '/tmp'433 else:434 print( 'No tmp dir!' )435 return436 self.debug( 'cmd_diff %r, %r, %r, %r, %r' % (tmpdir, positional_args[0], recurse, revision1, revision2) )437 diff_text = self.client.diff( tmpdir, positional_args[0], recurse=recurse,438 revision1=revision1, revision2=revision2,439 diff_options=['-u'] )440 print( diff_text.replace( '\r\n', '\n' ) )441 def cmd_export( self, args ):442 force = args.getBooleanOption( '--force', False )443 revision_url = args.getOptionalRevision( '--revision', 'head' )444 revision_wc = args.getOptionalRevision( '--revision', 'working' )445 native_eol = args.getOptionalValue( '--native-eol', None )446 positional_args = args.getPositionalArgs( 2, 2 )447 if self.client.is_url( positional_args[0] ):448 revision = revision_url449 else:450 revision = revision_wc451 self.client.export( positional_args[0], positional_args[1], revision=revision, force=force, native_eol=native_eol )452 def cmd_info( self, args ):453 positional_args = args.getPositionalArgs( 0, 1 )454 if len(positional_args) == 0:455 positional_args.append( '.' )456 path = positional_args[0]457 458 entry = self.client.info( path )459 print( 'Path: %s' % path )460 if entry.name and entry.name != 'svn:this_dir':461 print( 'Name: %s' % entry.name )462 if entry.url:463 print( 'Url: %s' % entry.url )464 if entry.repos and self.pysvn_testing >= '01.03.00':465 print( 'Repository: %s' % entry.repos )466 if entry.uuid:467 print( 'Repository UUID: %s' % entry.uuid )468 if entry.revision.kind == pysvn.opt_revision_kind.number:469 print( 'Revision: %s' % entry.revision.number )470 if entry.kind == pysvn.node_kind.file:471 print( 'Node kind: file' )472 elif entry.kind == pysvn.node_kind.dir:473 print( 'Node kind: directory' )474 elif entry.kind == pysvn.node_kind.none:475 print( 'Node kind: none' )476 else:477 print( 'Node kind: unknown' )478 if entry.schedule == pysvn.wc_schedule.normal:479 print( "Schedule: normal" )480 elif entry.schedule == pysvn.wc_schedule.add:481 print( "Schedule: add" )482 elif entry.schedule == pysvn.wc_schedule.delete:483 print( "Schedule: delete" )484 elif entry.schedule == pysvn.wc_schedule.replace:485 print( "Schedule: replace" )486 if entry.is_copied:487 if entry.copyfrom_url:488 print( 'Copied From URL: %s' % entry.copyfrom_url )489 if entry.copyfrom_rev.number:490 print( 'Copied From Rev: %s' % entry.copyfrom_rev.number )491 if entry.commit_author:492 print( 'Last Changed Author: %s' % entry.commit_author )493 if entry.commit_revision.number:494 print( 'Last Changed Rev: %s' % entry.commit_revision.number )495 if entry.commit_time:496 print( 'Last Changed Date: %s' % fmtDateTime( entry.commit_time ) )497 if entry.text_time:498 print( 'Text Last Updated: %s' % fmtDateTime( entry.text_time ) )499 if entry.properties_time and self.pysvn_testing == '99.99.99':500 print( 'Properties Last Updated: %s' % fmtDateTime( entry.properties_time ) )501 if entry.checksum:502 print( 'Checksum: %s' % entry.checksum )503 def cmd_info2( self, args ):504 recurse = args.getBooleanOption( '--recursive', True )505 revision_url = args.getOptionalRevision( '--revision', 'head' )506 revision_path = args.getOptionalRevision( '--revision', 'unspecified' )507 positional_args = args.getPositionalArgs( 0, 1 )508 if len(positional_args) == 0:509 positional_args.append( '.' )510 path = positional_args[0]511 if self.client.is_url( path ):512 revision = revision_url513 else:514 revision = revision_path515 all_entries = self.client.info2( path, revision=revision, recurse=recurse )516 for path, info in all_entries:517 print('')518 print( 'Path: %s' % path )519 if info.URL:520 print( 'Url: %s' % info.URL )521 if info.rev:522 print( 'Revision: %s' % info.rev.number )523 if info.repos_root_URL and self.pysvn_testing >= '01.03.00':524 print( 'Repository root_URL: %s' % info.repos_root_URL )525 if info.repos_UUID:526 print( 'Repository UUID: %s' % info.repos_UUID )527 if info.last_changed_author:528 print( 'Last changed author: %s' % info.last_changed_author )529 if info.last_changed_date:530 print( 'Last Changed Date: %s' % fmtDateTime( info.last_changed_date ) )531 if info.last_changed_rev.kind == pysvn.opt_revision_kind.number:532 print( 'Last changed revision: %s' % info.last_changed_rev.number )533 if info.kind == pysvn.node_kind.file:534 print( 'Node kind: file' )535 elif info.kind == pysvn.node_kind.dir:536 print( 'Node kind: directory' )537 elif info.kind == pysvn.node_kind.none:538 print( 'Node kind: none' )539 else:540 print( 'Node kind: unknown' )541 if info.lock:542 print( 'Lock Owner: %s' % info.lock.owner )543 print( 'Lock Creation Date: %s' % fmtDateTime( info.lock.creation_date ) )544 if info.lock.expiration_date is not None:545 print( 'Lock Expiration Date: %s' % fmtDateTime( info.lock.expiration_date ) )546 print( 'Lock Token: %s' % info.lock.token )547 print( 'Lock Comment:' )548 if info.lock.comment not in ['', None]:549 print( info.lock.comment )550 if info.wc_info:551 wc_info = info.wc_info552 if wc_info.schedule == pysvn.wc_schedule.normal:553 print( "Schedule: normal" )554 elif wc_info.schedule == pysvn.wc_schedule.add:555 print( "Schedule: add" )556 elif wc_info.schedule == pysvn.wc_schedule.delete:557 print( "Schedule: delete" )558 elif wc_info.schedule == pysvn.wc_schedule.replace:559 print( "Schedule: replace" )560 if wc_info.copyfrom_url:561 print( 'Copied From URL: %s' % wc_info.copyfrom_url )562 print( 'Copied From Rev: %s' % wc_info.copyfrom_rev.number )563 if wc_info.text_time:564 print( 'Text Last Updated: %s' % fmtDateTime( wc_info.text_time ) )565 if wc_info.prop_time and self.pysvn_testing == '99.99.99':566 print( 'Properties Last Updated: %s' % fmtDateTime( wc_info.prop_time ) )567 if wc_info.checksum:568 print( 'Checksum: %s' % wc_info.checksum )569 def cmd_import( self, args ):570 msg = args.getOptionalValue( '--message', '' )571 recurse = args.getBooleanOption( '--non-recursive', False )572 positional_args = args.getPositionalArgs( 2, 2 )573 self.client.import_( positional_args[0], positional_args[1], msg, recurse=recurse )574 def cmd_lock( self, args ):575 msg = args.getOptionalValue( '--message', '' )576 force = args.getBooleanOption( '--force', True )577 positional_args = args.getPositionalArgs( 1, 1 )578 self.client.lock( positional_args[0], msg, force );579 def cmd_log( self, args ):580 start_revision, end_revision = args.getOptionalRevisionPair( '--revision', 'head', '0' )581 limit = args.getOptionalValue( '--limit', 0 )582 verbose = args.getBooleanOption( '--verbose', True )583 positional_args = args.getPositionalArgs( 1, 1 )584 all_logs = self.client.log( positional_args[0],585 revision_start=start_revision,586 revision_end=end_revision,587 discover_changed_paths=verbose,588 limit=limit )589 for log in all_logs:590 print( '-'*60 )591 print( 'rev %d: %s | %s | %d lines' %592 (log.revision.number593 ,log.author594 ,fmtDateTime( log.date )595 ,len( log.message.split('\n') )) )596 if len( log.changed_paths ) > 0:597 print( 'Changed paths:' )598 for change_info in log.changed_paths:599 if change_info.copyfrom_path is None:600 print( ' %s %s' % (change_info.action, change_info.path) )601 else:602 print( ' %s %s (from %s:%d)' %603 (change_info.action604 ,change_info.path605 ,change_info.copyfrom_path606 ,change_info.copyfrom_revision.number) )607 print( log.message )608 print( '-'*60 )609 def cmd_ls( self, args ):610 recurse = args.getBooleanOption( '--recursive', True )611 revision = args.getOptionalRevision( '--revision', 'head' )612 verbose = args.getBooleanOption( '--verbose', True )613 positional_args = args.getPositionalArgs( 0 )614 if len(positional_args) == 0:615 positional_args.append( '.' )616 for arg in positional_args:617 all_entries = self.client.ls( arg, revision=revision, recurse=recurse )618 all_entries.sort( key=self.__sortKeyLsList )619 if verbose:620 for entry in all_entries:621 args = {}622 args.update( entry )623 args['time_str'] = fmtDateTime( entry.time )624 args['created_rev_num'] = entry.created_rev.number625 if args['size'] is None:626 args['size'] = '-'627 else:628 args['size'] = '%d' % (args['size'],)629 print( '%(created_rev_num)7d %(last_author)-10s %(size)6s %(time_str)s %(name)s' % args )630 else:631 for entry in all_entries:632 print( '%(name)s' % entry )633 def __sortKeyLsList( self, entry ):634 return entry['name']635 def cmd_list( self, args ):636 recurse = args.getBooleanOption( '--recursive', True )637 revision = args.getOptionalRevision( '--revision', 'head' )638 verbose = args.getBooleanOption( '--verbose', True )639 fetch_locks = args.getBooleanOption( '--fetch-locks', True )640 include_externals = args.getBooleanOption( '--include-externals', True )641 search_pattern = args.getOptionalValue( '--search', None )642 positional_args = args.getPositionalArgs( 0 )643 if len(positional_args) == 0:644 positional_args.append( '.' )645 for arg in positional_args:646 if self.pysvn_testing >= '01.10.00':647 all_entries = self.client.list( arg, revision=revision, recurse=recurse, fetch_locks=fetch_locks, include_externals=include_externals, patterns=search_pattern )648 elif self.pysvn_testing >= '01.08.00':649 all_entries = self.client.list( arg, revision=revision, recurse=recurse, fetch_locks=fetch_locks, include_externals=include_externals )650 else:651 all_entries = self.client.list( arg, revision=revision, recurse=recurse, fetch_locks=fetch_locks )652 if verbose:653 for entry_tuple in all_entries:654 entry = entry_tuple[0]655 lock_info = entry_tuple[1]656 args = {}657 args.update( entry )658 args['time_str'] = fmtDateTime( entry.time )659 args['created_rev_num'] = entry.created_rev.number660 if args['size'] is None:661 args['size'] = '-'662 else:663 args['size'] = '%d' % (args['size'],)664 print( '%(created_rev_num)7d %(last_author)-10s %(size)6s %(time_str)s %(path)s' % args )665 if lock_info is not None:666 print( ' Lock owner: %s' % (lock_info.owner,) )667 print( ' Lock comment: %s' % (lock_info.comment,) )668 if lock_info.creation_date is not None:669 print( ' Lock created: %s' % (time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime( lock_info.creation_date ) ),) )670 if lock_info.expiration_date is not None:671 print( ' Lock expires: %s' % (time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime( lock_info.expiration_date ) ),) )672 if self.pysvn_testing >= '01.08.00' and include_externals and entry_tuple[2] is not None:673 print( ' External target %s' % (entry_tuple[3],) )674 print( ' External URL %s' % (entry_tuple[2],) )675 else:676 for entry_tuple in all_entries:677 print( '%(path)s' % entry_tuple[0] )678 def cmd_merge( self, args ):679 recurse = args.getBooleanOption( '--recursive', True )680 dry_run = args.getBooleanOption( '--dry-run', False )681 notice_ancestry = args.getBooleanOption( '--notice-ancestry', False )682 # need to figure out which variaty of the merge command this is683 if args.haveOption( '--revision' ):684 # its merge -r N:M SOURCE [WCPATH]685 revision1, revision2 = args.getMandatoryRevisionPair( '--revision' )686 positional_args = args.getPositionalArgs( 1, 2 )687 if len(positional_args) == 1:688 positional_args.append( '.' )689 path1 = positional_args[0]690 path2 = positional_args[0]691 wcpath = positional_args[1]692 else:693 # its merge sourceURL1[@N] sourceURL2[@M] [WCPATH]694 positional_args = args.getPositionalArgs( 2, 3 )695 if len(positional_args) == 2:696 positional_args.append( '.' )697 path1, rev1 = self.parsePathWithRevision( positional_args[0] )698 path2, rev2 = self.parsePathWithRevision( positional_args[1] )699 wcpath = positional_args[2]700 self.client.merge( path1, revision1, path2, revision2, wcpath,701 recurse=recurse, dry_run=dry_run, notice_ancestry=notice_ancestry )702 def cmd_mkdir( self, args ):703 if args.haveOption( '--message' ):704 msg = args.getOptionalValue( '--message', '' )705 if msg == '':706 msg = self.getLogMessage()707 else:708 msg = ''709 self.client.mkdir( args.getPositionalArgs( 1, 1 )[0], msg )710 def cmd_move( self, args ):711 positional_args = args.getPositionalArgs( 2, 2 )712 self.client.move( positional_args[0], positional_args[1] )713 cmd_mv = cmd_move714 def cmd_patch( self, args ):715 dry_run = args.getBooleanOption( '--dry-run', True )716 reverse = args.getBooleanOption( '--reverse', True )717 ignore_whitespace = args.getBooleanOption( '--ignore-whitespace', True )718 remove_tempfiles = not args.getBooleanOption( '--no-remove-tempfiles', True )719 patch_path, wc_dir_path = args.getPositionalArgs( 2, 2 )720 abs_patch_path = os.path.abspath( patch_path )721 abs_wc_dir_path = os.path.abspath( wc_dir_path )722 self.client.patch( abs_patch_path, abs_wc_dir_path,723 dry_run=dry_run,724 reverse=reverse,725 ignore_whitespace=ignore_whitespace,726 remove_tempfiles=remove_tempfiles )727 def key_props_by_path( self, a ):728 return a[0]729 def cmd_proplist( self, args ):730 recurse = args.getBooleanOption( '--recursive', True )731 revision = args.getOptionalRevision( '--revision', 'working' )732 verbose = args.getBooleanOption( '--verbose', True )733 positional_args = args.getPositionalArgs( 0, 0 )734 if len(positional_args) == 0:735 positional_args.append( '.' )736 for arg in positional_args:737 if self.client.is_url( arg ):738 revision = args.getOptionalRevision( '--revision', 'head' )739 all_props = self.client.proplist( arg, revision=revision, recurse=recurse )740 all_props.sort( key=self.key_props_by_path )741 for path, props in all_props:742 print( "Properties on '%s':" % path )743 prop_names = sorted( props.keys() )744 for name in prop_names:745 if verbose:746 print( ' %s: %s' % (name, props[name]) )747 else:748 print( ' %s' % name )749 750 cmd_pl = cmd_proplist751 def cmd_propget( self, args ):752 recurse = args.getBooleanOption( '--recursive', True )753 revision = args.getOptionalRevision( '--revision', 'working' )754 if self.pysvn_testing >= '01.08.00' and args.getBooleanOption( '--show-inherited-props' ):755 get_inherited_props = True756 else:757 get_inherited_props = False758 positional_args = args.getPositionalArgs( 1, 2 )759 if len(positional_args) == 1:760 positional_args.append( '.' )761 if self.client.is_url( positional_args[0] ):762 revision = args.getOptionalRevision( '--revision', 'head' )763 if get_inherited_props:764 props, inherited_props = self.client.propget(765 positional_args[0], positional_args[1],766 revision=revision,767 recurse=recurse,768 get_inherited_props=True )769 else:770 props = self.client.propget(771 positional_args[0], positional_args[1],772 revision=revision,773 recurse=recurse )774 inherited_props = {}775 prop_names = sorted( props.keys() )776 for name in prop_names:777 print( '%s: %s' % (name, props[name]) )778 if len(inherited_props) > 0:779 print( 'Inherited props' )780 prop_names = sorted( inherited_props.keys() )781 for name in prop_names:782 print( '%s: %s' % (name, inherited_props[name]) )783 cmd_pg = cmd_propget784 def cmd_propset( self, args ):785 recurse = args.getBooleanOption( '--recursive', True )786 revision = args.getOptionalRevision( '--revision', 'working' )787 positional_args = args.getPositionalArgs( 2, 3 )788 if len(positional_args) == 2:789 positional_args.append( '.' )790 if self.client.is_url( positional_args[0] ):791 revision = args.getOptionalRevision( '--revision', 'head' )792 self.client.propset( positional_args[0], positional_args[1], positional_args[2], revision=revision, recurse=recurse )793 cmd_ps = cmd_propset794 def cmd_propdel( self, args ):795 recurse = args.getBooleanOption( '--recursive', True )796 revision = args.getOptionalRevision( '--revision', 'working' )797 positional_args = args.getPositionalArgs( 1, 2 )798 if len(positional_args) == 1:799 positional_args.append( '.' )800 if self.client.is_url( positional_args[0] ):801 revision = args.getOptionalRevision( '--revision', 'head' )802 self.client.propdel( positional_args[0], positional_args[1], revision=revision, recurse=recurse )803 cmd_pd = cmd_propdel804 def cmd_propset_local( self, args ):805 skip_checks = args.getBooleanOption( '--skip-checks', True )806 changelist = args.getOptionalValue( '--change-list', None )807 positional_args = args.getPositionalArgs( 3, 3 )808 if changelist is not None:809 changelist = [s.strip() for s in changelist.split(',')]810 self.client.propset_local( positional_args[0], positional_args[1], positional_args[2], skip_checks=skip_checks, changelist=changelist )811 else:812 self.client.propset_local( positional_args[0], positional_args[1], positional_args[2], skip_checks=skip_checks )813 def cmd_propdel_local( self, args ):814 changelist = args.getOptionalValue( '--change-list', None )815 positional_args = args.getPositionalArgs( 2, 2 )816 if changelist is not None:817 changelist = [s.strip() for s in changelist.split(',')]818 self.client.propdel_local( positional_args[0], positional_args[1], changelist=changelist )819 else:820 self.client.propdel_local( positional_args[0], positional_args[1] )821 def cmd_propset_remote( self, args ):822 self.next_log_message = args.getOptionalValue( '--message', None )823 skip_checks = args.getBooleanOption( '--skip-checks', True )824 revision = args.getOptionalRevision( '--revision', '0' )825 positional_args = args.getPositionalArgs( 3, 3 )826 if args.haveOption( '--revision' ):827 self.client.propset_remote( positional_args[0], positional_args[1], positional_args[2], skip_checks=skip_checks, base_revision_for_url=revision )828 else:829 self.client.propset_remote( positional_args[0], positional_args[1], positional_args[2], skip_checks=skip_checks )830 def cmd_propdel_remote( self, args ):831 self.next_log_message = args.getOptionalValue( '--message', None )832 revision = args.getOptionalRevision( '--revision', '0' )833 positional_args = args.getPositionalArgs( 2, 2 )834 self.client.propdel_remote( positional_args[0], positional_args[1], base_revision_for_url=revision )835 def cmd_revproplist( self, args ):836 revision = args.getOptionalRevision( '--revision', 'head' )837 verbose = args.getBooleanOption( '--verbose', False )838 positional_args = args.getPositionalArgs( 0, 1 )839 if len(positional_args) == 0:840 positional_args.append( '.' )841 rev, prop_dict = self.client.revproplist( positional_args[0], revision=revision )842 print( 'Revision: %s' % rev.number )843 prop_keys = prop_dict.keys()844 for key in sorted( prop_keys ):845 print( '%s: %s' % (key, prop_dict[ key ]) )846 cmd_rpl = cmd_revproplist847 def cmd_revpropget( self, args ):848 revision = args.getOptionalRevision( '--revision', 'head' )849 positional_args = args.getPositionalArgs( 1, 2 )850 if len(positional_args) == 1:851 positional_args.append( '.' )852 rev, value = self.client.revpropget( positional_args[0], positional_args[1], revision=revision )853 print( 'Revision: %s' % rev.number )854 print( '%s: %s' % (positional_args[0], value) )855 cmd_rpg = cmd_revpropget856 def cmd_revpropset( self, args ):857 force = args.getBooleanOption( '--force', False )858 revision = args.getOptionalRevision( '--revision', 'head' )859 positional_args = args.getPositionalArgs( 2, 3 )860 if len(positional_args) == 2:861 positional_args.append( '.' )862 rev = self.client.revpropset( positional_args[0], positional_args[1], positional_args[2], revision=revision, force=force )863 cmd_rps = cmd_revpropset864 def cmd_revpropdel( self, args ):865 force = args.getBooleanOption( '--force', False )866 revision = args.getOptionalRevision( '--revision', 'head' )867 positional_args = args.getPositionalArgs( 1, 2 )868 if len(positional_args) == 1:869 positional_args.append( '.' )870 self.client.revpropdel( positional_args[0], positional_args[1], revision=revision, force=force )871 cmd_rpd = cmd_revpropdel872 def cmd_remove( self, args ):873 force = args.getBooleanOption( '--force', True )874 positional_args = args.getPositionalArgs( 1, 0 )875 self.client.remove( positional_args, force=force )876 cmd_rm = cmd_remove877 def cmd_remove_from_changelists( self, args ):878 if not hasattr( self.client, remove_from_changelists ):879 print( 'Error: remove_from_changelists is not supported by this version of Subversion' )880 return881 path = args.getPositionalArgs( 1, 1 )[0]882 self.client.remove_from_changelists( path )883 def cmd_resolved( self, args ):884 recurse = args.getBooleanOption( '--recursive', True )885 positional_args = args.getPositionalArgs( 1, 1 )886 self.client.resolved( positional_args[0], recurse=recurse )887 def cmd_revert( self, args ):888 recurse = args.getBooleanOption( '--recursive', True )889 positional_args = args.getPositionalArgs( 1, 1 )890 self.client.revert( positional_args[0], recurse=recurse )891 def key_by_path( self, a ):892 return a.path893 def cmd_status( self, args ):894 recurse = args.getBooleanOption( '--non-recursive', False )895 verbose = args.getBooleanOption( '--verbose', True )896 quiet = args.getBooleanOption( '--quiet', True )897 ignore = args.getBooleanOption( '--no-ignore', False )898 update = args.getBooleanOption( '--show-updates', True )899 positional_args = args.getPositionalArgs( 0 )900 if len(positional_args) == 0:901 all_entries = self.client.status( '', recurse=recurse, get_all=verbose, ignore=ignore, update=update )902 self._cmd_status_print( all_entries, verbose, update, ignore, quiet )903 else:904 for arg in positional_args:905 all_entries = self.client.status( arg, recurse=recurse, get_all=verbose, ignore=ignore, update=update )906 self._cmd_status_print( all_entries, verbose, update, ignore, quiet )907 def _cmd_status_print( self, all_entries, detailed, update, ignore, quiet ):908 all_entries.sort( key=self.key_by_path )909 for entry in all_entries:910 if entry.text_status == pysvn.wc_status_kind.ignored and ignore:911 continue912 if entry.text_status == pysvn.wc_status_kind.unversioned and quiet:913 continue914 state = '%s%s%s%s%s' % (wc_status_kind_map[ entry.text_status ],915 wc_status_kind_map[ entry.prop_status ],916 ' L'[ entry.is_locked ],917 ' +'[ entry.is_copied ],918 ' S'[ entry.is_switched ])919 if( entry.repos_text_status != pysvn.wc_status_kind.none920 or entry.repos_prop_status != pysvn.wc_status_kind.none ):921 odd_status = '%s%s' % (wc_status_kind_map[ entry.repos_text_status ],922 wc_status_kind_map[ entry.repos_prop_status ])923 else:924 odd_status = ' '925 lock_state = ' '926 if entry.entry is not None and hasattr( entry.entry, 'lock_token' ):927 if entry.entry.lock_token is not None:928 lock_state = 'K'929 if hasattr( entry, 'repos_lock' ) and entry.repos_lock is not None:930 lock_state = 'O'931 if entry.entry is not None and detailed:932 print( '%s%s %s %6d %6d %-14s %s' %933 (state,934 lock_state,935 odd_status,936 entry.entry.revision.number,937 entry.entry.commit_revision.number,938 entry.entry.commit_author,939 entry.path) )940 elif detailed:941 print( '%s%s %s %6s %6s %-14s %s' %942 (state,943 lock_state,944 odd_status,945 '',946 '',947 '',948 entry.path) )949 elif update:950 print( '%s%s %s %s' %951 (state,952 lock_state,953 odd_status,954 entry.path) )955 else:956 if( entry.text_status != pysvn.wc_status_kind.normal957 or entry.prop_status != pysvn.wc_status_kind.normal958 or lock_state.strip() != ''):959 print( '%s%s %s' % (state, lock_state, entry.path) )960 cmd_st = cmd_status961 cmd_stat = cmd_status962 def cmd_status2( self, args ):963 recurse = args.getBooleanOption( '--non-recursive', False )964 verbose = args.getBooleanOption( '--verbose', True )965 quiet = args.getBooleanOption( '--quiet', True )966 ignore = args.getBooleanOption( '--no-ignore', False )967 update = args.getBooleanOption( '--show-updates', True )968 positional_args = args.getPositionalArgs( 0 )969 if len(positional_args) == 0:970 all_entries = self.client.status2( '', recurse=recurse, get_all=verbose, ignore=ignore, update=update )971 self._cmd_status2_print( all_entries, verbose, update, ignore, quiet )972 else:973 for arg in positional_args:974 all_entries = self.client.status2( arg, recurse=recurse, get_all=verbose, ignore=ignore, update=update )975 self._cmd_status2_print( all_entries, verbose, update, ignore, quiet )976 def _cmd_status2_print( self, all_entries, detailed, update, ignore, quiet ):977 all_entries.sort( key=self.key_by_path )978 for entry in all_entries:979 if entry.text_status == pysvn.wc_status_kind.ignored and ignore:980 continue981 if entry.text_status == pysvn.wc_status_kind.unversioned and quiet:982 continue983 if entry.text_status == pysvn.wc_status_kind.none and quiet:984 continue985 if entry.text_status == pysvn.wc_status_kind.none:986 text_status = '?'987 else:988 text_status = wc_status_kind_map[ entry.text_status ]989 state = '%s%s%s%s%s' % (text_status,990 wc_status_kind_map[ entry.prop_status ],991 ' L'[ entry.wc_is_locked ],992 ' +'[ entry.is_copied ],993 ' S'[ entry.is_switched ])994 if( entry.repos_text_status != pysvn.wc_status_kind.none995 or entry.repos_prop_status != pysvn.wc_status_kind.none ):996 odd_status = '%s%s' % (wc_status_kind_map[ entry.repos_text_status ],997 wc_status_kind_map[ entry.repos_prop_status ])998 else:999 odd_status = ' '1000 lock_state = ' '1001 if entry.lock is not None and entry.lock.token is not None:1002 lock_state = 'K'1003 if entry.repos_lock is not None:1004 lock_state = 'O'1005 # convert from abs to rel path1006 cwd = os.getcwd()1007 if entry.path == cwd:1008 path = '.'1009 elif entry.path.startswith( cwd + '/' ):1010 path = entry.path[len(cwd)+1:]1011 else:1012 path = entry.path1013 if detailed and entry.is_versioned:1014 print( '%s%s %s %6d %6d %-14s %s' %1015 (state,1016 lock_state,1017 odd_status,1018 entry.revision.number,1019 entry.changed_revision.number,1020 entry.changed_author,1021 path) )1022 elif detailed:1023 print( '%s%s %s %6s %6s %-14s %s' %1024 (state,1025 lock_state,1026 odd_status,1027 '',1028 '',1029 '',1030 path) )1031 elif update:1032 print( '%s%s %s %s' %1033 (state,1034 lock_state,1035 odd_status,1036 path) )1037 else:1038 if( entry.text_status != pysvn.wc_status_kind.normal1039 or entry.prop_status != pysvn.wc_status_kind.normal1040 or lock_state.strip() != ''):1041 print( '%s%s %s' % (state, lock_state, path) )1042 def cmd_switch( self, args ):1043 recurse = args.getBooleanOption( '--non-recursive', False )1044 revision = args.getOptionalRevision( '--revision', 'head' )1045 positional_args = args.getPositionalArgs( 1, 2 )1046 if len(positional_args) == 1:1047 positional_args.append( '.' )1048 self.client.switch( positional_args[0], positional_args[1],1049 recurse=recurse, revision=revision )1050 def cmd_relocate( self, args ):1051 recurse = args.getBooleanOption( '--non-recursive', False )1052 positional_args = args.getPositionalArgs( 2, 3 )1053 if len(positional_args) == 2:1054 positional_args.append( '.' )1055 self.client.relocate( positional_args[0], positional_args[1],1056 positional_args[2], recurse=recurse )1057 def cmd_unlock( self, args ):1058 force = args.getBooleanOption( '--force', False )1059 positional_args = args.getPositionalArgs( 1, 1 )1060 self.client.unlock( positional_args[0], force );1061 def cmd_update( self, args ):1062 recurse = args.getBooleanOption( '--non-recursive', False )1063 positional_args = args.getPositionalArgs( 0 )1064 if len(positional_args) == 0:1065 positional_args.append( '.' )1066 rev_list = self.client.update( positional_args[0], recurse=recurse )1067 self.printNotifyMessages()1068 if type(rev_list) == type([]) and len(rev_list) != 1:1069 print( 'rev_list = %r' % [rev.number for rev in rev_list] )1070 if self.revision_update_complete is not None:1071 print( 'Updated to revision %s' % self.revision_update_complete.number )1072 else:1073 print( 'Updated to unknown revision - update failed?' )1074 cmd_up = cmd_update1075 def cmd_vacuum( self, args ):1076 remove_unversioned_items = args.getBooleanOption( '--remove-unversioned-items', True )1077 remove_ignored_items = args.getBooleanOption( '--remove-ignored-items', True )1078 fix_recorded_timestamps = args.getBooleanOption( '--fix-recorded-timestamps', True )1079 vacuum_pristines = args.getBooleanOption( '--vacuum-pristines', True )1080 include_externals = args.getBooleanOption( '--include-externals', True )1081 positional_args = args.getPositionalArgs( 0, 1 )1082 if len(positional_args) == 0:1083 positional_args.append( '.' )1084 self.client.vacuum(1085 positional_args[0],1086 remove_unversioned_items=remove_unversioned_items,1087 remove_ignored_items=remove_ignored_items,1088 fix_recorded_timestamps=fix_recorded_timestamps,1089 vacuum_pristines=vacuum_pristines,1090 include_externals=include_externals1091 )1092 def cmd_help( self, args ):1093 print( 'Version: pysvn %d.%d.%d-%d' % pysvn.version,'svn %d.%d.%d-%s' % pysvn.svn_version )1094 valid_cmd_names = [name for name in SvnCommand.__dict__.keys() if name.find('cmd_') == 0]1095 valid_cmd_names.sort()1096 print( 'Available subcommands:' )1097 index = 01098 line = ''1099 for name in valid_cmd_names:1100 line = line + (' %-12s' % name[4:])1101 if index % 4 == 3:1102 print( line )1103 line = ''1104 index += 11105# key is long option name, value is 1 if need next arg as value1106long_opt_info = {1107 # svn_cmd.py control1108 '--pause': 0,1109 '--pysvn-testing': 1, # modify behaviour to assist testing pysvn1110 '--debug': 0, # do debug stuff1111 # command options1112 '--auto-props': 0, # enable automatic properties1113 '--change-list': 1, # changelist1114 '--config-dir': 1, # read user configuration files from directory ARG1115 '--diff-cmd': 1, # use ARG as diff command1116 '--diff3-cmd': 1, # use ARG as merge command1117 '--dry-run': 0, # try operation but make no changes1118 '--editor-cmd': 1, # use ARG as external editor1119 '--encoding': 1, # treat value as being in charset encoding ARG1120 '--extensions': 1, # pass ARG as bundled options to GNU diff1121 '--fetch-locks': 0, # as list to fetch lock info1122 '--file': 1, # read data from file ARG1123 '--fix-recorded-timestamps': 0,1124 '--force': 0, # force operation to run1125 '--force-log': 0, # force validity of log message source1126 '--include-externals': 0,1127 '--include-externals': 0, # include external information in list() output1128 '--incremental': 0, # give output suitable for concatenation1129 '--limit': 1, # number of logs to fetch1130 '--message': 1, # specify commit message ARG1131 '--native-eol': 1, # native eol ARG1132 '--new': 1, # use ARG as the newer target1133 '--no-auth-cache': 0, # do not cache authentication tokens1134 '--no-auto-props': 0, # disable automatic properties1135 '--no-diff-deleted': 0, # do not print differences for deleted files1136 '--no-ignore': 0, # disregard default and svn:ignore property ignores1137 '--no-remove-tempfiles': 0, # do not remove temp files1138 '--non-interactive': 0, # do no interactive prompting1139 '--non-recursive': 0, # operate on single directory only1140 '--notice-ancestry': 0, # notice ancestry when calculating differences1141 '--old': 1, # use ARG as the older target1142 '--password': 1, # specify a password ARG1143 '--quiet': 0, # print as little as possible1144 '--recursive': 0, # descend recursively1145 '--relocate': 0, # relocate via URL-rewriting1146 '--remove-ignored-items': 0,1147 '--remove-unversioned-items': 0,1148 '--revision': 1, # revision X or X:Y range. X or Y can be one of:1149 '--revprop': 0, # operate on a revision property (use with -r)1150 '--search': 2, # search for pattern1151 '--show-inherited-props': 0, # show inherited props1152 '--show-updates': 0, # display update information1153 '--skip-checks': 0, # skip-checks1154 '--strict': 0, # use strict semantics1155 '--targets': 1, # pass contents of file ARG as additional args1156 '--username': 1, # specify a username ARG1157 '--vacuum-pristines': 0,1158 '--verbose': 0, # print extra information1159 '--version': 0, # print client version info1160 '--xml': 0, # output in xml1161}1162# map short name to long1163short_opt_info = {1164 '-F': '--file',1165 '-N': '--non-recursive',1166 '-R': '--recursive',1167 '-m': '--message',1168 '-q': '--quiet',1169 '-r': '--revision',1170 '-u': '--show-updates',1171 '-v': '--verbose',1172 '-x': '--extensions',1173}1174#1175# Usage:1176# Construct with a commnad list1177# call getCommandName()1178# call getBooleanOption() and getOptionalValue() as needed1179# finally call getPositionalArgs()1180#1181#1182class SvnArguments:1183 def __init__( self, all_args ):1184 self.positional_args = []1185 self.named_options = {}1186 self.used_named_options = {}1187 need_next_arg = 01188 name = ''1189 for arg in all_args:1190 if need_next_arg > 1:1191 self.named_options.setdefault( name, [] ).append( arg )1192 need_next_arg = 01193 elif need_next_arg:1194 self.named_options[ name ] = arg1195 need_next_arg = 01196 elif self._isOption( arg ):1197 name, need_next_arg = self._optionInfo( arg )1198 if not need_next_arg:1199 self.named_options[ name ] = None1200 else:1201 expanded_arg = glob.glob( arg )1202 if len(expanded_arg) > 0:1203 self.positional_args.extend( expanded_arg )1204 else:1205 self.positional_args.append( arg )1206 if need_next_arg:1207 raise CommandError( 'Missing arg to option %s' % name )1208 def _isOption( self, arg ):1209 return arg[0] == '-'1210 def _optionInfo( self, opt ):1211 # return long_name, arg_needed1212 long_opt = short_opt_info.get( opt, opt )1213 if long_opt in long_opt_info:1214 return long_opt, long_opt_info[ long_opt ]1215 raise CommandError( 'unknown option %s' % opt )1216 def _checkOptionsUsed( self ):1217 # check all options have been used1218 for opt_name in self.named_options.keys():1219 if opt_name not in self.used_named_options:1220 raise CommandError( 'unused option %s' % opt_name )1221 def parsePathWithRevision( self, path_rev, default_rev ):1222 if '@' in path_rev:1223 path = path_rev[:path_rev.find('@')]1224 rev = self._parseRevisionArg( path_rev[path_rev.find('@')+1:] )1225 else:1226 path = path_rev1227 rev = self._parseRevisionArg( default_rev )1228 return path, rev1229 def _parseRevisionArg( self, rev_string ):1230 if rev_string.lower() == 'base':1231 return pysvn.Revision( pysvn.opt_revision_kind.base )1232 if rev_string.lower() == 'head':1233 return pysvn.Revision( pysvn.opt_revision_kind.head )1234 if rev_string.lower() == 'working':1235 return pysvn.Revision( pysvn.opt_revision_kind.working )1236 if rev_string.lower() == 'committed':1237 return pysvn.Revision( pysvn.opt_revision_kind.committed )1238 if rev_string.lower() == 'prev':1239 return pysvn.Revision( pysvn.opt_revision_kind.prev )1240 if rev_string.lower() == 'unspecified':1241 return pysvn.Revision( pysvn.opt_revision_kind.unspecified )1242 if rev_string[0] == '{' and rev_string[-1] == '}':1243 try:1244 date = parse_datetime.parse_time( rev_string[1:-2] )1245 return pysvn.Revision( pysvn.opt_revision_kind.date, date )1246 except parse_datetime.DateTimeSyntaxError as e:1247 raise CommandError( e.reason() )1248 # either a rev number or a date1249 try:1250 return pysvn.Revision( pysvn.opt_revision_kind.number, int(rev_string) )1251 except ValueError:1252 pass1253 raise CommandError( 'Cannot parse %s as a revision value' % rev_string )1254 def _splitRevisionString( self, rev_string ):1255 # split the string at the first : that is not inside a {} pair1256 if rev_string[0] == '{':1257 # the : may be after the closing }1258 close_paren_index = rev_string.find( '}' )1259 if close_paren_index == -1:1260 # error leave to others to report1261 return [rev_string]1262 if close_paren_index == len(rev_string ):1263 # its just one revision1264 return [rev_string]1265 if rev_string[close_paren_index+1] == ':':1266 return [rev_string[:close_paren_index+1], rev_string[close_paren_index+2:]]1267 # another error case1268 return [rev_string]1269 else:1270 return rev_string.split(':',1)1271 def getCommandName( self, default_command ):1272 if len(self.positional_args) > 0:1273 return self.positional_args.pop( 0 )1274 else:1275 return default_command1276 def haveOption( self, opt_name ):1277 return opt_name in self.named_options1278 def getBooleanOption( self, opt_name, present_value=True ):1279 if opt_name in self.named_options:1280 self.used_named_options[ opt_name ] = None1281 return present_value1282 else:1283 return not present_value1284 def getOptionalValue( self, opt_name, default ):1285 if opt_name in self.named_options:1286 self.used_named_options[ opt_name ] = None1287 return self.named_options[ opt_name ]1288 else:1289 return default1290 def getOptionalRevision( self, opt_name, start_default ):1291 if opt_name in self.named_options:1292 self.used_named_options[ opt_name ] = None1293 rev_string = self.named_options[ opt_name ]1294 return self._parseRevisionArg( rev_string )1295 else:1296 return self._parseRevisionArg( start_default )1297 def getMandatoryRevisionPair( self, opt_name ):1298 # parse a M:N or M as revision pair1299 if opt_name not in self.named_options:1300 raise CommandError( 'mandatory %s required' % opt_name )1301 self.used_named_options[ opt_name ] = None1302 rev_strings = self._splitRevisionString( self.named_options[ opt_name ] )1303 if len(rev_strings) == 1:1304 raise CommandError( 'mandatory %s requires a pair of revisions' % opt_name )1305 return [self._parseRevisionArg( rev_strings[0] ),1306 self._parseRevisionArg( rev_strings[1] )]1307 def getOptionalRevisionPair( self, opt_name, start_default, end_default=None ):1308 # parse a M:N or M as revision pair1309 if opt_name in self.named_options:1310 self.used_named_options[ opt_name ] = None1311 rev_strings = self._splitRevisionString( self.named_options[ opt_name ] )1312 if len(rev_strings) == 1:1313 if end_default is None:1314 # M means M:M1315 rev_strings.append( rev_strings[0] )1316 else:1317 # M means M:end_default1318 rev_strings.append( end_default )1319 return [self._parseRevisionArg( rev_strings[0] ),1320 self._parseRevisionArg( rev_strings[1] )]1321 else:1322 return (self._parseRevisionArg( start_default ),1323 self._parseRevisionArg( end_default ))1324 def getPositionalArgs( self, min_args, max_args=0 ):1325 # check min and max then return the list1326 if len(self.positional_args) < min_args:1327 raise CommandError( 'too few arguments - need at least %d' % min_args )1328 if max_args != 0 and len(self.positional_args) > max_args:1329 raise CommandError( 'too many arguments - need no more then %d' % max_args )1330 # as this is the last call on the args object we check the option where all used1331 self._checkOptionsUsed()1332 return self.positional_args1333if __name__ == '__main__':...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Slash automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful