scripts/new_branch.py
changeset 105 b7a32c7e2a99
parent 104 5a2786fd5048
child 106 667451541623
equal deleted inserted replaced
104:5a2786fd5048 105:b7a32c7e2a99
     1 #!/usr/bin/python2.5
       
     2 #
       
     3 # Copyright 2008 the Melange authors.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (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
       
     8 #
       
     9 #   http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 """Script to make a Google App Engine "image" branch of a Melange application.
       
    18 
       
    19 For details:
       
    20   trunk/scripts/new_branch.py --help
       
    21 
       
    22 Default values for flags can be specified in valid Python syntax in the
       
    23 ~/.soc_scripts_settings file.  See settings.py for details.
       
    24 """
       
    25 
       
    26 __authors__ = [
       
    27   # alphabetical order by last name, please
       
    28   '"Todd Larsen" <tlarsen@google.com>',
       
    29 ]
       
    30 
       
    31 
       
    32 import sys
       
    33 
       
    34 import pysvn
       
    35 
       
    36 from trunk.scripts import app_image
       
    37 from trunk.scripts import settings
       
    38 from trunk.scripts import svn_helper
       
    39 
       
    40 
       
    41 def buildOptionList(defaults={}):
       
    42   """Returns a list of command-line settings.Options for this script.
       
    43 
       
    44   Args:
       
    45     defaults: dict of possible pre-loaded default values; default is empty
       
    46       dict (which is safe because it is not altered)
       
    47   """
       
    48   help_user = defaults.get('user', '<user>')
       
    49   user_help_msg = (
       
    50       'user name, used for default /users/%s/ branch' % help_user)
       
    51   dest_help_msg = (
       
    52       'if supplied, new name of branched app, users/%s/<dest>' % help_user)
       
    53   branch_help_msg = (
       
    54       'destination branch, defaults to <wc>/users/%s/<src|dest>' % help_user)
       
    55 
       
    56   def_repo = defaults.get('repo')
       
    57 
       
    58   if def_repo:
       
    59     repo_help_msg = 'SVN repository; default is %s' % def_repo
       
    60   else:
       
    61     repo_help_msg = 'SVN repository; REQUIRED if a default is missing'
       
    62 
       
    63   def_wc = defaults.get('wc')
       
    64 
       
    65   if def_wc:
       
    66     wc_help_msg = 'working copy directory; default is %s' % def_wc
       
    67   else:
       
    68     wc_help_msg = 'working copy directory; REQUIRED if a default is missing'
       
    69 
       
    70   return [
       
    71       settings.Option(
       
    72           '-R', '--repo', action='store', dest='repo',
       
    73           default=def_repo, help=repo_help_msg),
       
    74       settings.Option(
       
    75           '-w', '--wc', action='store', dest='wc',
       
    76           default=def_wc, help=wc_help_msg),
       
    77       settings.Option(
       
    78           '-s', '--src', action='store', dest='src', required=True,
       
    79           help='(REQUIRED) name of source app in /trunk/apps/ to branch'),
       
    80       settings.Option(
       
    81           '-d', '--dest', action='store', dest='dest', help=dest_help_msg),
       
    82       settings.Option(
       
    83           '-u', '--user', action='store', dest='user',
       
    84           default=defaults.get('user'), help=user_help_msg),
       
    85       settings.Option(
       
    86           '-b', '--branch', action='store', dest='branch',
       
    87           help=branch_help_msg),
       
    88       settings.Option(
       
    89           '-r', '--rev', type='int', action='store', dest='rev',
       
    90           default=None, help='optional revision number on which to branch'),
       
    91   ]
       
    92 
       
    93 
       
    94 def main(args):
       
    95   # create parser just for usage info before settings file is read successfully
       
    96   usage_parser = settings.OptionParser(option_list=buildOptionList())
       
    97 
       
    98   # attempt to read the common trunk/scripts settings file
       
    99   defaults = settings.readPythonSettingsOrDie(parser=usage_parser)
       
   100 
       
   101   # create the command-line options parser
       
   102   parser = settings.makeOptionParserOrDie(
       
   103       option_list=buildOptionList(defaults))
       
   104 
       
   105   # parse the command-line options
       
   106   options, args = settings.parseOptionsOrDie(parser, args)
       
   107 
       
   108   # ensure that various paths end with the / separator
       
   109   src, dest, user, repo, wc = svn_helper.formatDirPaths(
       
   110       options.src, options.dest, options.user, options.repo, options.wc)
       
   111 
       
   112   settings.checkCommonSvnOptionsOrDie(options, parser)
       
   113 
       
   114   branch = app_image.formDefaultAppBranchPath(options.branch, user, src, dest)
       
   115   branch_path = svn_helper.getExpandedWorkingCopyPath(branch, wc_root=wc)
       
   116 
       
   117   # setup a callback used by pysvn if it needs a log message (it actually
       
   118   # should not be needed, since nothing is being committed, but exceptions
       
   119   # were being raised by pysvn without it)
       
   120   def callbackGetLogMessage():
       
   121     return True, 'trunk/apps/%s application branched to %s' % (src, branch)
       
   122 
       
   123   client = svn_helper.getPySvnClient()
       
   124   client.callback_get_log_message = callbackGetLogMessage
       
   125 
       
   126   # validate choice of "image" branch location
       
   127   if not options.branch:
       
   128     users = svn_helper.lsDirs(repo + 'users/')
       
   129 
       
   130     if user not in users:
       
   131       return settings.printErrorsAndUsage(
       
   132           ['%susers/%s not found; existing users are:' % (repo, user),
       
   133            ' '.join(users)], parser)
       
   134 
       
   135   if svn_helper.exists(branch_path):
       
   136     return settings.printErrorsAndUsage(
       
   137         ['%s already exists;' % branch_path,
       
   138          'use merge_branch.py to update instead'],
       
   139         parser)
       
   140 
       
   141   # branch trunk/apps/<src> first, so parent destination directory will exist
       
   142   app_image.branchFromSrcApp(src, repo, branch_path, rev=options.rev)
       
   143   app_image.branchFromThirdParty(repo, branch_path, rev=options.rev)
       
   144   app_image.branchFromFramework(repo, branch_path, rev=options.rev)
       
   145 
       
   146   return 0
       
   147 
       
   148 
       
   149 if __name__ == '__main__':
       
   150   sys.exit(main(sys.argv))