diff options
author | David Seikel | 2011-06-04 00:17:28 +1000 |
---|---|---|
committer | David Seikel | 2011-06-04 00:17:28 +1000 |
commit | 492eaaf4eec82327116f2605e3d8becf94bec1b3 (patch) | |
tree | dcddd674cb4861445c3ec5aaa59325b99a437614 /linden/scripts | |
parent | Set the real bare minimum prim size to 0.00001, as 0 sized objects cause bugs. (diff) | |
parent | Fixing the menu to actually use its color options reveals how broken the whol... (diff) | |
download | meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.zip meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.gz meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.bz2 meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.xz |
Merge branch 'next' of git://github.com/jacek/imprudence into next
Conflicts (manually merged):
linden/indra/llcommon/llversionviewer.h
linden/indra/llvfs/lldir.cpp
linden/indra/llvfs/lldir_mac.cpp
linden/indra/newview/CMakeLists.txt
linden/indra/newview/English.lproj/InfoPlist.strings
linden/indra/newview/Info-Imprudence.plist
linden/indra/newview/Info-meta-impy.plist
linden/indra/newview/llappviewer.cpp
linden/indra/newview/llpanellogin.cpp
linden/indra/newview/packaging/mac/Info.plist.in
linden/indra/newview/res/viewerRes.rc
linden/indra/newview/skins/default/xui/en-us/floater_about.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml
linden/indra/newview/skins/default/xui/zh/menu_viewer.xml
linden/indra/newview/skins/default/xui/zh/panel_group_general.xml
linden/indra/newview/viewer_manifest.py
linden/indra/newview/viewerversion.cpp
linden/indra/newview/viewerversion.h
linden/install.xml
Also some post merge tweaks.
Diffstat (limited to '')
-rwxr-xr-x | linden/scripts/build_version.py | 62 | ||||
-rwxr-xr-x | linden/scripts/package.py | 334 | ||||
-rwxr-xr-x | linden/scripts/viewer_info.py | 101 |
3 files changed, 435 insertions, 62 deletions
diff --git a/linden/scripts/build_version.py b/linden/scripts/build_version.py deleted file mode 100755 index f6b88a9..0000000 --- a/linden/scripts/build_version.py +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # | ||
3 | # Print the build information embedded in a header file. | ||
4 | # | ||
5 | # Expects to be invoked from the command line with a file name and a | ||
6 | # list of directories to search. The file name will be one of the | ||
7 | # following: | ||
8 | # | ||
9 | # llversionserver.h | ||
10 | # llversionviewer.h | ||
11 | # | ||
12 | # The directory list that follows will include indra/llcommon, where | ||
13 | # these files live. | ||
14 | |||
15 | import errno, os, re | ||
16 | |||
17 | def get_version(filename): | ||
18 | fp = open(filename) | ||
19 | data = fp.read() | ||
20 | fp.close() | ||
21 | |||
22 | vals = {} | ||
23 | m = re.search('<viewer version_major="(\d+)" />', data) | ||
24 | vals['major'] = m.group(1) | ||
25 | m = re.search('<viewer version_minor="(\d+)" />', data) | ||
26 | vals['minor'] = m.group(1) | ||
27 | m = re.search('<viewer version_patch="(\d+)" />', data) | ||
28 | vals['patch'] = m.group(1) | ||
29 | m = re.search('<viewer version_test="(.*)" />', data) | ||
30 | vals['test'] = m.group(1) | ||
31 | |||
32 | version = "%(major)s.%(minor)s.%(patch)s" % vals | ||
33 | |||
34 | if len(vals['test']) > 0: | ||
35 | # Replace some puncuation and spaces with '-' in the test version | ||
36 | vals['test'] = re.sub('[ \t:;,+/\\"\'`]+', '-', vals['test']) | ||
37 | version += "-%(test)s" % vals | ||
38 | |||
39 | return version | ||
40 | |||
41 | |||
42 | if __name__ == '__main__': | ||
43 | import sys | ||
44 | |||
45 | try: | ||
46 | for path in sys.argv[2:]: | ||
47 | name = os.path.join(path, sys.argv[1]) | ||
48 | try: | ||
49 | print get_version(name) | ||
50 | break | ||
51 | except OSError, err: | ||
52 | if err.errno != errno.ENOENT: | ||
53 | raise | ||
54 | else: | ||
55 | print >> sys.stderr, 'File not found:', sys.argv[1] | ||
56 | sys.exit(1) | ||
57 | except AttributeError: | ||
58 | print >> sys.stderr, 'Error: malformatted file: ', name | ||
59 | sys.exit(1) | ||
60 | except IndexError: | ||
61 | print >> sys.stderr, ('Usage: %s llversion[...].h [directories]' % | ||
62 | sys.argv[0]) | ||
diff --git a/linden/scripts/package.py b/linden/scripts/package.py new file mode 100755 index 0000000..e02a9cc --- /dev/null +++ b/linden/scripts/package.py | |||
@@ -0,0 +1,334 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # | ||
3 | # @file package.py | ||
4 | # @author Jacek Antonelli | ||
5 | # @brief Script for generating viewer installer packages. | ||
6 | # | ||
7 | # Usage: package.py --build-dir=PATH [options] | ||
8 | # | ||
9 | # Copyright (c) 2007-2009, Linden Research, Inc. | ||
10 | # Copyright (c) 2010-2011, Jacek Antonelli | ||
11 | # | ||
12 | # Permission is hereby granted, free of charge, to any person | ||
13 | # obtaining a copy of this software and associated documentation files | ||
14 | # (the "Software"), to deal in the Software without restriction, | ||
15 | # including without limitation the rights to use, copy, modify, merge, | ||
16 | # publish, distribute, sublicense, and/or sell copies of the Software, | ||
17 | # and to permit persons to whom the Software is furnished to do so, | ||
18 | # subject to the following conditions: | ||
19 | # | ||
20 | # The above copyright notice and this permission notice shall be | ||
21 | # included in all copies or substantial portions of the Software. | ||
22 | # | ||
23 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
26 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
27 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
28 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
29 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
30 | # SOFTWARE. | ||
31 | # | ||
32 | |||
33 | import os, sys | ||
34 | from viewer_info import ViewerInfo | ||
35 | |||
36 | |||
37 | SCRIPTS_DIR = sys.path[0] # directory containing this script | ||
38 | TOP_DIR = os.path.abspath(os.path.join(SCRIPTS_DIR,'..')) | ||
39 | SOURCE_DIR = os.path.abspath(os.path.join(TOP_DIR,'indra')) | ||
40 | BUILD_TYPE = "RelWithDebInfo" | ||
41 | |||
42 | |||
43 | class PackagerError(Exception): pass | ||
44 | |||
45 | class BadDir(PackagerError): pass | ||
46 | |||
47 | class WeirdPlatform(PackagerError): pass | ||
48 | |||
49 | class CmdFailed(PackagerError): pass | ||
50 | |||
51 | |||
52 | def indent(text, amount=4): | ||
53 | import string | ||
54 | lines = [(' '*amount + line) for line in string.split(text, '\n')] | ||
55 | return string.join(lines, '\n') | ||
56 | |||
57 | def message(*args): | ||
58 | """Prints an informational message with a leading '#'.""" | ||
59 | print '# ' + ' '.join([str(arg) for arg in args]) | ||
60 | |||
61 | def error(*args): | ||
62 | """Prints an error message to stderr.""" | ||
63 | print >> sys.stderr, 'Error: ' + ' '.join([str(arg) for arg in args]) | ||
64 | |||
65 | |||
66 | class Packager: | ||
67 | |||
68 | def __init__(self, build_dir, opts={}): | ||
69 | options = {'source_dir': SOURCE_DIR, | ||
70 | 'build_type': BUILD_TYPE, | ||
71 | 'verbose': False, | ||
72 | } | ||
73 | options.update(opts) | ||
74 | |||
75 | self.build_dir = os.path.abspath(build_dir) | ||
76 | self.__check_build_dir() | ||
77 | |||
78 | # Package results go in the top build directory. | ||
79 | self.dest_dir = build_dir | ||
80 | |||
81 | self.source_dir = os.path.abspath(options['source_dir']) | ||
82 | self.__check_source_dir() | ||
83 | |||
84 | self.build_type = options['build_type'] | ||
85 | self.platform = self.__get_platform() | ||
86 | self.verbose = options['verbose'] | ||
87 | self.viewer_info = ViewerInfo() | ||
88 | |||
89 | |||
90 | def make(self): | ||
91 | plat = self.platform | ||
92 | if plat == 'linux': self.make_linux() | ||
93 | elif plat == 'mac': self.make_mac() | ||
94 | elif plat == 'windows': self.make_windows() | ||
95 | |||
96 | |||
97 | ######### | ||
98 | # LINUX # | ||
99 | ######### | ||
100 | |||
101 | def make_linux(self): | ||
102 | import shutil | ||
103 | |||
104 | packaged_dir = os.path.join(self.build_dir, 'newview', 'packaged') | ||
105 | |||
106 | if not os.path.exists(packaged_dir): | ||
107 | raise BadDir("invalid build dir, has no 'newview/packaged/' " | ||
108 | 'subdirectory: %(d)r'%{'d': self.build_dir}) | ||
109 | |||
110 | self.__run_command( 'Checking/fixing file permissions...', | ||
111 | """find %(d)r -type d | xargs --no-run-if-empty chmod 755; | ||
112 | find %(d)r -type f -perm 0700 | xargs --no-run-if-empty chmod 0755; | ||
113 | find %(d)r -type f -perm 0500 | xargs --no-run-if-empty chmod 0555; | ||
114 | find %(d)r -type f -perm 0600 | xargs --no-run-if-empty chmod 0644; | ||
115 | find %(d)r -type f -perm 0400 | xargs --no-run-if-empty chmod 0444; | ||
116 | true""" % {'d': packaged_dir}) | ||
117 | |||
118 | plat = 'Linux' | ||
119 | from platform import architecture | ||
120 | if architecture()[0] == '64bit': | ||
121 | plat += '-x86_64' | ||
122 | elif architecture()[0] == '32bit': | ||
123 | plat += '-x86' | ||
124 | |||
125 | inst_name = self.viewer_info.combined + '-' + plat | ||
126 | dest_file = os.path.join(self.dest_dir, inst_name + '.tar.bz2') | ||
127 | |||
128 | if (os.path.exists(dest_file)): | ||
129 | bkp = dest_file + ".bkp" | ||
130 | message("Renaming existing package to %r..." % bkp) | ||
131 | shutil.move(dest_file, bkp) | ||
132 | |||
133 | self.__run_command( | ||
134 | 'Creating package %r (this takes a while)...'%dest_file, | ||
135 | 'tar -C %(dir)s --numeric-owner ' | ||
136 | '--transform "s,^./,%(inst_name)s/," ' | ||
137 | #'--verbose --show-transformed-names ' | ||
138 | '-cjf %(dest_file)s .' % { 'dir': packaged_dir, | ||
139 | 'inst_name': inst_name, | ||
140 | 'dest_file': dest_file}) | ||
141 | |||
142 | message('Package complete: %r' % dest_file) | ||
143 | |||
144 | |||
145 | ####### | ||
146 | # MAC # | ||
147 | ####### | ||
148 | |||
149 | def make_mac(self): | ||
150 | import shutil | ||
151 | |||
152 | volname = self.viewer_info.name + " Installer" | ||
153 | |||
154 | # Where the DMG files (background image, etc.) come from. | ||
155 | dmg_src = os.path.join(self.source_dir, 'newview', 'packaging', 'mac') | ||
156 | |||
157 | # Everything that will be in the package is copied to here. | ||
158 | dmg_dst = os.path.join('/Volumes', volname) | ||
159 | |||
160 | if (os.path.exists(dmg_dst)): | ||
161 | error('%r is currently attached. Eject it and try again.' % dmg_dst) | ||
162 | sys.exit(1) | ||
163 | |||
164 | app_name = self.viewer_info.name + ".app" | ||
165 | app_orig = os.path.join(self.build_dir, 'newview', self.build_type, app_name) | ||
166 | app_dst = os.path.join(dmg_dst, app_name) | ||
167 | |||
168 | if (not os.path.exists(app_orig)): | ||
169 | error("App does not exist: %r" % app_orig) | ||
170 | sys.exit(1) | ||
171 | |||
172 | dmg_name = "%s-Mac"%(self.viewer_info.combined) | ||
173 | temp_dmg = os.path.join(self.build_dir, dmg_name+".sparseimage") | ||
174 | final_dmg = os.path.join(self.dest_dir, dmg_name+".dmg") | ||
175 | |||
176 | if (os.path.exists(temp_dmg)): | ||
177 | message("Removing stale temp disk image...") | ||
178 | os.remove(temp_dmg) | ||
179 | |||
180 | self.__run_command( | ||
181 | 'Creating temp disk image...', | ||
182 | 'hdiutil create %(temp)r -volname %(volname)r -fs HFS+ ' | ||
183 | '-layout SPUD -type SPARSE' % | ||
184 | {'temp': temp_dmg, 'volname': volname, 'src': dmg_dst}) | ||
185 | |||
186 | self.__run_command( | ||
187 | 'Mounting temp disk image...', | ||
188 | 'hdiutil attach %r -readwrite -noautoopen' % temp_dmg) | ||
189 | |||
190 | # Move the .app to the staging area (temporarily). | ||
191 | message("Copying %r (this takes a while)..."%(app_name)) | ||
192 | shutil.copytree(app_orig, app_dst, symlinks=True) | ||
193 | |||
194 | message("Copying background.png...") | ||
195 | shutil.copy2( os.path.join(dmg_src, 'background.png'), | ||
196 | os.path.join(dmg_dst, 'background.png')) | ||
197 | |||
198 | config_script = os.path.join(self.source_dir, 'newview', | ||
199 | 'packaging', 'mac', 'ConfigureDMG.scpt') | ||
200 | |||
201 | self.__run_command( | ||
202 | "Configuring temp disk image's view options...", | ||
203 | 'osascript %(script)r %(volname)r %(app_name)r' % | ||
204 | {'script': config_script, 'volname': volname, 'app_name': app_name}) | ||
205 | |||
206 | self.__run_command( | ||
207 | 'Unmounting temp disk image...', | ||
208 | 'hdiutil detach %r' % dmg_dst) | ||
209 | |||
210 | if (os.path.exists(final_dmg)): | ||
211 | bkp = final_dmg + ".bkp" | ||
212 | message("Renaming existing final disk image to %r..." % bkp) | ||
213 | shutil.move(final_dmg, bkp) | ||
214 | |||
215 | self.__run_command( | ||
216 | 'Creating compressed final disk image (this takes a while)...', | ||
217 | 'hdiutil convert %(temp)r -format UDBZ -o %(final)r' % | ||
218 | {'temp':temp_dmg, 'final':final_dmg}) | ||
219 | |||
220 | message("Removing temp disk image...") | ||
221 | os.remove(temp_dmg) | ||
222 | |||
223 | message('Package complete: %r'%final_dmg) | ||
224 | |||
225 | |||
226 | ########### | ||
227 | # WINDOWS # | ||
228 | ########### | ||
229 | |||
230 | def make_windows(self): | ||
231 | print "Packaging for Windows is not supported yet." | ||
232 | |||
233 | |||
234 | ################### | ||
235 | # PRIVATE METHODS # | ||
236 | ################### | ||
237 | |||
238 | def __check_build_dir(self): | ||
239 | if not os.path.exists(self.build_dir): | ||
240 | raise BadDir('build dir %(dir)r does not exist.' % | ||
241 | {'dir': self.build_dir}) | ||
242 | if not os.path.isdir(self.build_dir): | ||
243 | raise BadDir('build dir %(dir)r is not a directory.' % | ||
244 | {'dir': self.build_dir}) | ||
245 | |||
246 | def __check_source_dir(self): | ||
247 | if not os.path.exists(self.source_dir): | ||
248 | raise BadDir('source dir %(dir)r does not exist.' % | ||
249 | {'dir': self.source_dir}) | ||
250 | if not os.path.isdir(self.source_dir): | ||
251 | raise BadDir('source dir %(dir)r is not a directory.' % | ||
252 | {'dir': self.source_dir}) | ||
253 | |||
254 | def __get_platform(self): | ||
255 | platform = sys.platform | ||
256 | try: | ||
257 | return {'linux2':'linux', | ||
258 | 'linux1':'linux', | ||
259 | 'cygwin':'windows', | ||
260 | 'win32' :'windows', | ||
261 | 'darwin':'mac', | ||
262 | }[platform] | ||
263 | except KeyError: | ||
264 | raise WeirdPlatform( | ||
265 | "Unrecognized platform/operating system: %r" % platform) | ||
266 | |||
267 | def __run_command(self, summary=None, command=None): | ||
268 | if summary: message(summary) | ||
269 | |||
270 | if not command: return | ||
271 | |||
272 | import subprocess | ||
273 | |||
274 | out = subprocess.PIPE # = intercept command's output | ||
275 | if self.verbose: | ||
276 | print indent(command) | ||
277 | out = None # = don't intercept | ||
278 | |||
279 | child = subprocess.Popen(command, shell=True, stdout=out, stderr=None) | ||
280 | status = child.wait() | ||
281 | |||
282 | if status: | ||
283 | raise CmdFailed('A command returned non-zero status (%s):\n%s'% | ||
284 | (status, indent(command))) | ||
285 | |||
286 | |||
287 | |||
288 | def main(args=sys.argv[1:]): | ||
289 | from optparse import OptionParser | ||
290 | |||
291 | op = OptionParser(usage='%prog --build-dir=PATH [options]') | ||
292 | |||
293 | op.add_option('--build-dir', dest='build_dir', nargs=1, metavar='PATH', | ||
294 | help='path to the \'build\' directory, which contains ' | ||
295 | 'CMakeCache.txt and the compile result subdirectories') | ||
296 | |||
297 | op.add_option('--source-dir', dest='source_dir', nargs=1, metavar='PATH', | ||
298 | default=SOURCE_DIR, | ||
299 | help='optional path to an alternate source directory, ' | ||
300 | 'i.e. \'indra\'. Default: %(SOURCE_DIR)r' | ||
301 | %{ 'SOURCE_DIR': SOURCE_DIR } ) | ||
302 | |||
303 | op.add_option('--build-type', dest='build_type', nargs=1, metavar='TYPE', | ||
304 | default=BUILD_TYPE, | ||
305 | help='\'Debug\', \'RelWithDebInfo\', or \'Release\'. ' | ||
306 | 'Default: %(BUILD_TYPE)r' | ||
307 | %{ 'BUILD_TYPE': BUILD_TYPE } ) | ||
308 | |||
309 | op.add_option('-v', '--verbose', action='store_true', default=False, | ||
310 | help='print all shell commands as they are run') | ||
311 | |||
312 | if not args: | ||
313 | op.print_help() | ||
314 | return | ||
315 | |||
316 | options = op.parse_args(args)[0] | ||
317 | |||
318 | if not options.build_dir: | ||
319 | error('--build-dir=PATH is required.') | ||
320 | sys.exit(1) | ||
321 | |||
322 | opts_dict = {'source_dir': options.source_dir, | ||
323 | 'build_type': options.build_type, | ||
324 | 'verbose': options.verbose} | ||
325 | |||
326 | try: | ||
327 | Packager(options.build_dir, opts_dict).make() | ||
328 | except PackagerError, err: | ||
329 | error(err.args[0]) | ||
330 | sys.exit(1) | ||
331 | |||
332 | |||
333 | if __name__ == '__main__': | ||
334 | main() | ||
diff --git a/linden/scripts/viewer_info.py b/linden/scripts/viewer_info.py new file mode 100755 index 0000000..53ea432 --- /dev/null +++ b/linden/scripts/viewer_info.py | |||
@@ -0,0 +1,101 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # | ||
3 | # @file viewer_info.py | ||
4 | # @author Jacek Antonelli | ||
5 | # @brief Scans and prints the viewer name and/or version. | ||
6 | # | ||
7 | # Copyright (c) 2010, Jacek Antonelli | ||
8 | # | ||
9 | # Permission is hereby granted, free of charge, to any person | ||
10 | # obtaining a copy of this software and associated documentation files | ||
11 | # (the "Software"), to deal in the Software without restriction, | ||
12 | # including without limitation the rights to use, copy, modify, merge, | ||
13 | # publish, distribute, sublicense, and/or sell copies of the Software, | ||
14 | # and to permit persons to whom the Software is furnished to do so, | ||
15 | # subject to the following conditions: | ||
16 | # | ||
17 | # The above copyright notice and this permission notice shall be | ||
18 | # included in all copies or substantial portions of the Software. | ||
19 | # | ||
20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
21 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
22 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
23 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
24 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
25 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
26 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
27 | # SOFTWARE. | ||
28 | # | ||
29 | # | ||
30 | # Usage: | ||
31 | # | ||
32 | # viewer_info.py --name # viewer name (e.g. "Kokua") | ||
33 | # viewer_info.py --version # viewer version (e.g. "1.0.0-RC1" | ||
34 | # viewer_info.py --combined # name + version (e.g. "Kokua-1.0.0-RC1") | ||
35 | # | ||
36 | # You can pass multiple flags to print each thing on a separate line. | ||
37 | # E.g. `viewer_info.py --name --version' will print 2 lines, e.g.: | ||
38 | # | ||
39 | # Kokua | ||
40 | # 1.0.0-RC1 | ||
41 | # | ||
42 | |||
43 | import errno, os, re, string, sys | ||
44 | |||
45 | |||
46 | class ViewerInfo: | ||
47 | |||
48 | def __init__(self, filepath=None): | ||
49 | f = open(filepath or self.default_file()) | ||
50 | data = f.read() | ||
51 | f.close() | ||
52 | |||
53 | self.name = re.search('NAME\s*=\s*"([^"]*)"', data).group(1) | ||
54 | self.major = re.search('MAJOR\s*=\s*(\d+)', data).group(1) | ||
55 | self.minor = re.search('MINOR\s*=\s*(\d+)', data).group(1) | ||
56 | self.patch = re.search('PATCH\s*=\s*(\d+)', data).group(1) | ||
57 | self.extra = re.search('EXTRA\s*=\s*"([^"]*)"', data).group(1) | ||
58 | self.bundle_id = re.search('BUNDLE_ID\s*=\s*"([^"]*)"', data).group(1) | ||
59 | |||
60 | self.version = "%s.%s.%s"%(self.major, self.minor, self.patch) | ||
61 | if len(self.extra) > 0: | ||
62 | # Replace spaces and some puncuation with '-' in extra | ||
63 | extra = re.sub('[- \t:;,!+/\\"\'`]+', '-', self.extra) | ||
64 | # Strip any leading or trailing "-"s | ||
65 | extra = string.strip(extra, '-') | ||
66 | self.version += "-" + extra | ||
67 | |||
68 | self.combined = self.name + "-" + self.version | ||
69 | |||
70 | @classmethod | ||
71 | def default_file(klass): | ||
72 | scripts_dir = sys.path[0] # directory containing this script | ||
73 | viewerinfo = os.path.join('indra', 'newview', 'viewerinfo.cpp') | ||
74 | filepath = os.path.join(scripts_dir, '..', viewerinfo) | ||
75 | return os.path.abspath(filepath) | ||
76 | |||
77 | |||
78 | if __name__ == '__main__': | ||
79 | |||
80 | try: | ||
81 | info = ViewerInfo() | ||
82 | except IOError, err: | ||
83 | if err.errno == errno.ENOENT: | ||
84 | print >> sys.stderr, 'File not found:', ViewerInfo.default_file() | ||
85 | sys.exit(1) | ||
86 | else: | ||
87 | raise | ||
88 | |||
89 | args = sys.argv[1:] | ||
90 | |||
91 | if not args: | ||
92 | print "Usage: %s [--name] [--version] [--combined]"%(sys.argv[0]) | ||
93 | for arg in args: | ||
94 | if '--name' == arg: | ||
95 | print info.name | ||
96 | elif '--version' == arg: | ||
97 | print info.version | ||
98 | elif '--combined' == arg: | ||
99 | print info.combined | ||
100 | elif '--bundle-id' == arg: | ||
101 | print info.bundle_id | ||