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)) |
|