diff options
author | Jacek Antonelli | 2008-08-15 23:45:02 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:02 -0500 |
commit | d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd (patch) | |
tree | 7ed0c2c27d717801238a2e6b5749cd5bf88c3059 /linden/scripts/template_verifier.py | |
parent | Second Life viewer sources 1.17.3.0 (diff) | |
download | meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.zip meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.gz meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.bz2 meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.xz |
Second Life viewer sources 1.18.0.6
Diffstat (limited to 'linden/scripts/template_verifier.py')
-rwxr-xr-x | linden/scripts/template_verifier.py | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/linden/scripts/template_verifier.py b/linden/scripts/template_verifier.py new file mode 100755 index 0000000..1bc03e7 --- /dev/null +++ b/linden/scripts/template_verifier.py | |||
@@ -0,0 +1,175 @@ | |||
1 | #!/usr/bin/python | ||
2 | # @file template_verifier.py | ||
3 | # @brief Message template compatibility verifier. | ||
4 | # | ||
5 | # Copyright (c) 2007-2007, Linden Research, Inc. | ||
6 | # | ||
7 | # Second Life Viewer Source Code | ||
8 | # The source code in this file ("Source Code") is provided by Linden Lab | ||
9 | # to you under the terms of the GNU General Public License, version 2.0 | ||
10 | # ("GPL"), unless you have obtained a separate licensing agreement | ||
11 | # ("Other License"), formally executed by you and Linden Lab. Terms of | ||
12 | # the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
13 | # online at http://secondlife.com/developers/opensource/gplv2 | ||
14 | # | ||
15 | # There are special exceptions to the terms and conditions of the GPL as | ||
16 | # it is applied to this Source Code. View the full text of the exception | ||
17 | # in the file doc/FLOSS-exception.txt in this software distribution, or | ||
18 | # online at http://secondlife.com/developers/opensource/flossexception | ||
19 | # | ||
20 | # By copying, modifying or distributing this software, you acknowledge | ||
21 | # that you have read and understood your obligations described above, | ||
22 | # and agree to abide by those obligations. | ||
23 | # | ||
24 | # ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
25 | # WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
26 | # COMPLETENESS OR PERFORMANCE. | ||
27 | |||
28 | """template_verifier is a script which will compare the | ||
29 | current repository message template with the "master" message template, accessible | ||
30 | via http://secondlife.com/app/message_template/master_message_template.msg | ||
31 | If [FILE] is specified, it will be checked against the master template. | ||
32 | If [FILE] [FILE] is specified, two local files will be checked against | ||
33 | each other. | ||
34 | """ | ||
35 | |||
36 | from os.path import realpath, dirname, join, exists | ||
37 | setup_path = join(dirname(realpath(__file__)), "setup-path.py") | ||
38 | if exists(setup_path): | ||
39 | execfile(setup_path) | ||
40 | import optparse | ||
41 | import os | ||
42 | import sys | ||
43 | import urllib | ||
44 | |||
45 | from indra import compatibility | ||
46 | from indra import llmessage | ||
47 | |||
48 | def die(msg): | ||
49 | print >>sys.stderr, msg | ||
50 | sys.exit(1) | ||
51 | |||
52 | MESSAGE_TEMPLATE = 'message_template.msg' | ||
53 | |||
54 | PRODUCTION_ACCEPTABLE = (compatibility.Same, compatibility.Newer) | ||
55 | DEVELOPMENT_ACCEPTABLE = ( | ||
56 | compatibility.Same, compatibility.Newer, | ||
57 | compatibility.Older, compatibility.Mixed) | ||
58 | |||
59 | def getstatusall(command): | ||
60 | """ Like commands.getstatusoutput, but returns stdout and | ||
61 | stderr separately(to get around "killed by signal 15" getting | ||
62 | included as part of the file). Also, works on Windows.""" | ||
63 | (input, out, err) = os.popen3(command, 't') | ||
64 | input.close() # send no input to the command | ||
65 | output = out.read() | ||
66 | error = err.read() | ||
67 | out.close() | ||
68 | status = err.close() # the status comes from the *last* pipe you close | ||
69 | return status, output, error | ||
70 | |||
71 | def getstatusoutput(command): | ||
72 | status, output, error = getstatusall(command) | ||
73 | return status, output | ||
74 | |||
75 | def compare(base, current, mode): | ||
76 | """Compare the current template against the base template using the given | ||
77 | 'mode' strictness: | ||
78 | |||
79 | development: Allows Same, Newer, Older, and Mixed | ||
80 | production: Allows only Same or Newer | ||
81 | |||
82 | Print out information about whether the current template is compatible | ||
83 | with the base template. | ||
84 | |||
85 | Returns a tuple of (bool, Compatibility) | ||
86 | Return True if they are compatible in this mode, False if not. | ||
87 | """ | ||
88 | base = llmessage.parseTemplateString(base) | ||
89 | current = llmessage.parseTemplateString(current) | ||
90 | |||
91 | compat = current.compatibleWithBase(base) | ||
92 | if mode == 'production': | ||
93 | acceptable = PRODUCTION_ACCEPTABLE | ||
94 | else: | ||
95 | acceptable = DEVELOPMENT_ACCEPTABLE | ||
96 | |||
97 | if type(compat) in acceptable: | ||
98 | return True, compat | ||
99 | return False, compat | ||
100 | |||
101 | def local_template_filename(): | ||
102 | """Returns the message template's default location relative to template_verifier.py: | ||
103 | ./messages/message_template.msg.""" | ||
104 | d = os.path.dirname(os.path.realpath(__file__)) | ||
105 | return os.path.join(d, 'messages', MESSAGE_TEMPLATE) | ||
106 | |||
107 | def run(sysargs): | ||
108 | parser = optparse.OptionParser( | ||
109 | usage="usage: %prog [FILE] [FILE]", | ||
110 | description=__doc__) | ||
111 | parser.add_option( | ||
112 | '-m', '--mode', type='string', dest='mode', | ||
113 | default='development', | ||
114 | help="""[development|production] The strictness mode to use | ||
115 | while checking the template; see the wiki page for details about | ||
116 | what is allowed and disallowed by each mode: | ||
117 | http://wiki.secondlife.com/wiki/Template_verifier.py | ||
118 | """) | ||
119 | parser.add_option( | ||
120 | '-u', '--master_url', type='string', dest='master_url', | ||
121 | default='http://secondlife.com/app/message_template/master_message_template.msg', | ||
122 | help="""The url of the master message template.""") | ||
123 | |||
124 | options, args = parser.parse_args(sysargs) | ||
125 | |||
126 | # both current and master supplied in positional params | ||
127 | if len(args) == 2: | ||
128 | master_filename, current_filename = args | ||
129 | print "base:", master_filename | ||
130 | print "current:", current_filename | ||
131 | master = file(master_filename).read() | ||
132 | current = file(current_filename).read() | ||
133 | # only current supplied in positional param | ||
134 | elif len(args) == 1: | ||
135 | master = None | ||
136 | current_filename = args[0] | ||
137 | print "base: <master template from repository>" | ||
138 | print "current:", current_filename | ||
139 | current = file(current_filename).read() | ||
140 | # nothing specified, use defaults for everything | ||
141 | elif len(args) == 0: | ||
142 | master = None | ||
143 | current = None | ||
144 | else: | ||
145 | die("Too many arguments") | ||
146 | |||
147 | # fetch the master from the url (default or supplied) | ||
148 | if master is None: | ||
149 | master = urllib.urlopen(options.master_url).read() | ||
150 | |||
151 | # fetch the template for this build | ||
152 | if current is None: | ||
153 | current_filename = local_template_filename() | ||
154 | print "base: <master template from repository>" | ||
155 | print "current:", current_filename | ||
156 | current = file(current_filename).read() | ||
157 | |||
158 | acceptable, compat = compare( | ||
159 | master, current, options.mode) | ||
160 | |||
161 | def explain(header, compat): | ||
162 | print header | ||
163 | # indent compatibility explanation | ||
164 | print '\n\t'.join(compat.explain().split('\n')) | ||
165 | |||
166 | if acceptable: | ||
167 | explain("--- PASS ---", compat) | ||
168 | else: | ||
169 | explain("*** FAIL ***", compat) | ||
170 | return 1 | ||
171 | |||
172 | if __name__ == '__main__': | ||
173 | sys.exit(run(sys.argv[1:])) | ||
174 | |||
175 | |||