aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/scripts
diff options
context:
space:
mode:
authorDavid Seikel2011-06-04 00:17:28 +1000
committerDavid Seikel2011-06-04 00:17:28 +1000
commit492eaaf4eec82327116f2605e3d8becf94bec1b3 (patch)
treedcddd674cb4861445c3ec5aaa59325b99a437614 /linden/scripts
parentSet the real bare minimum prim size to 0.00001, as 0 sized objects cause bugs. (diff)
parentFixing the menu to actually use its color options reveals how broken the whol... (diff)
downloadmeta-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-xlinden/scripts/build_version.py62
-rwxr-xr-xlinden/scripts/package.py334
-rwxr-xr-xlinden/scripts/viewer_info.py101
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
15import errno, os, re
16
17def 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
42if __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
33import os, sys
34from viewer_info import ViewerInfo
35
36
37SCRIPTS_DIR = sys.path[0] # directory containing this script
38TOP_DIR = os.path.abspath(os.path.join(SCRIPTS_DIR,'..'))
39SOURCE_DIR = os.path.abspath(os.path.join(TOP_DIR,'indra'))
40BUILD_TYPE = "RelWithDebInfo"
41
42
43class PackagerError(Exception): pass
44
45class BadDir(PackagerError): pass
46
47class WeirdPlatform(PackagerError): pass
48
49class CmdFailed(PackagerError): pass
50
51
52def 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
57def message(*args):
58 """Prints an informational message with a leading '#'."""
59 print '# ' + ' '.join([str(arg) for arg in args])
60
61def error(*args):
62 """Prints an error message to stderr."""
63 print >> sys.stderr, 'Error: ' + ' '.join([str(arg) for arg in args])
64
65
66class 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;
112find %(d)r -type f -perm 0700 | xargs --no-run-if-empty chmod 0755;
113find %(d)r -type f -perm 0500 | xargs --no-run-if-empty chmod 0555;
114find %(d)r -type f -perm 0600 | xargs --no-run-if-empty chmod 0644;
115find %(d)r -type f -perm 0400 | xargs --no-run-if-empty chmod 0444;
116true""" % {'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
288def 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
333if __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
43import errno, os, re, string, sys
44
45
46class 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
78if __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