scripts/export_image.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 export a Google App Engine "image" of a Melange application.
       
    18 
       
    19 For details:
       
    20   trunk/scripts/export_image.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 os
       
    33 import sys
       
    34 
       
    35 import pysvn
       
    36 
       
    37 from trunk.scripts import app_image
       
    38 from trunk.scripts import settings
       
    39 from trunk.scripts import svn_helper
       
    40 
       
    41 
       
    42 def buildOptionList(defaults={}):
       
    43   """Returns a list of command-line settings.Options for this script.
       
    44 
       
    45   Args:
       
    46     defaults: dict of possible pre-loaded default values; default is empty
       
    47       dict (which is safe because it is not altered)
       
    48   """
       
    49   def_repo = defaults.get('repo')
       
    50 
       
    51   if def_repo:
       
    52     repo_help_msg = 'SVN repository; default is %s' % def_repo
       
    53   else:
       
    54     repo_help_msg = 'SVN repository; REQUIRED if a default is missing'
       
    55 
       
    56   return [
       
    57       settings.Option(
       
    58           '-R', '--repo', action='store', dest='repo',
       
    59           default=def_repo, help=repo_help_msg),
       
    60       settings.Option(
       
    61           '-s', '--src', action='store', dest='src', required=True,
       
    62           help='(REQUIRED) name of source app in /trunk/apps/ to export'),
       
    63       settings.Option(
       
    64           '-i', '--image', action='store', dest='image', required=True,
       
    65           help='(REQUIRED) exported image destination'),
       
    66       settings.Option(
       
    67           '-r', '--rev', type='int', action='store', dest='rev',
       
    68           default=None, help='optional revision number on which to export'),
       
    69   ]
       
    70 
       
    71 
       
    72 def main(args):
       
    73   # create parser just for usage info before settings file is read successfully
       
    74   usage_parser = settings.OptionParser(option_list=buildOptionList())
       
    75 
       
    76   # attempt to read the common trunk/scripts settings file
       
    77   defaults = settings.readPythonSettingsOrDie(parser=usage_parser)
       
    78 
       
    79   # create the command-line options parser
       
    80   parser = settings.makeOptionParserOrDie(
       
    81       option_list=buildOptionList(defaults))
       
    82 
       
    83   # parse the command-line options
       
    84   options, args = settings.parseOptionsOrDie(parser, args)
       
    85 
       
    86   # ensure that various paths end with the / separator
       
    87   src, image, repo = svn_helper.formatDirPaths(
       
    88       options.src, options.image, options.repo)
       
    89 
       
    90   # expand and make "OS-agnostic" the proposed App Engine image path
       
    91   # (which is why no working copy path is needed or supplied)
       
    92   image = svn_helper.getExpandedWorkingCopyPath(image)
       
    93 
       
    94   setup_errors = []
       
    95 
       
    96   if os.path.exists(image):
       
    97     setup_errors.extend(
       
    98         ['--image destination directory must not already exist:',
       
    99          '  %s' % image])
       
   100 
       
   101   # dirname() called twice because image always ends with os.sep as a result
       
   102   # of svn_helper.getExpandedWorkingCopyPath()
       
   103   parent_dir = os.path.dirname(os.path.dirname(image))
       
   104 
       
   105   if not os.path.isdir(parent_dir):
       
   106     try:
       
   107       os.makedirs(parent_dir)
       
   108       print 'Created --image parent directory:\n %s\n' % parent_dir
       
   109     except (IOError, OSError), fs_err:
       
   110       setup_errors.extend(
       
   111           ['--image parent directory could not be created:',
       
   112            '  %s' % parent_dir,
       
   113            '  %s: %s' % (fs_err.__class__.__name__,
       
   114                        ' '.join([str(arg) for arg in fs_err.args]))])
       
   115 
       
   116   if not options.repo:
       
   117     setup_errors.extend(
       
   118         ['--repo must be supplied or have a settings file default'])
       
   119 
       
   120   if setup_errors:
       
   121     return settings.printErrorsAndUsage(setup_errors, parser)
       
   122 
       
   123   def callbackGetLogMessage():
       
   124     return True, 'trunk/apps/%s application exported to %s' % (src, image)
       
   125 
       
   126   client = svn_helper.getPySvnClient()
       
   127   # this should never actually be called, but just in case...
       
   128   client.callback_get_log_message = callbackGetLogMessage
       
   129 
       
   130   # export trunk/apps/<src> first, so image root directory will exist
       
   131   app_image.exportFromSrcApp(src, repo, image, rev=options.rev)
       
   132   app_image.exportFromThirdParty(repo, image, rev=options.rev)
       
   133   app_image.exportFromFramework(repo, image, rev=options.rev)
       
   134 
       
   135   return 0
       
   136 
       
   137 
       
   138 if __name__ == '__main__':
       
   139   sys.exit(main(sys.argv))