Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(775)

Side by Side Diff: build/mac/tweak_info_plist.py

Issue 2037043002: [iOS] Add support for iOS to build/mac/tweak_info_plist.py. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 # 7 #
8 # Xcode supports build variable substitutions and CPP; sadly, that doesn't work 8 # Xcode supports build variable substitutions and CPP; sadly, that doesn't work
9 # because: 9 # because:
10 # 10 #
(...skipping 13 matching lines...) Expand all
24 import os 24 import os
25 import plistlib 25 import plistlib
26 import re 26 import re
27 import subprocess 27 import subprocess
28 import sys 28 import sys
29 import tempfile 29 import tempfile
30 30
31 TOP = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) 31 TOP = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
32 32
33 33
34 def _ConvertPlist(source_plist, output_plist, fmt):
35 """Convert |source_plist| to |fmt| and save as |output_plist|."""
36 return subprocess.call(
37 ['plutil', '-convert', fmt, '-o', output_plist, source_plist])
38
39
34 def _GetOutput(args): 40 def _GetOutput(args):
35 """Runs a subprocess and waits for termination. Returns (stdout, returncode) 41 """Runs a subprocess and waits for termination. Returns (stdout, returncode)
36 of the process. stderr is attached to the parent.""" 42 of the process. stderr is attached to the parent."""
37 proc = subprocess.Popen(args, stdout=subprocess.PIPE) 43 proc = subprocess.Popen(args, stdout=subprocess.PIPE)
38 (stdout, stderr) = proc.communicate() 44 (stdout, stderr) = proc.communicate()
39 return (stdout, proc.returncode) 45 return (stdout, proc.returncode)
40 46
41 47
42 def _GetOutputNoError(args): 48 def _GetOutputNoError(args):
43 """Similar to _GetOutput() but ignores stderr. If there's an error launching 49 """Similar to _GetOutput() but ignores stderr. If there's an error launching
(...skipping 10 matching lines...) Expand all
54 60
55 def _RemoveKeys(plist, *keys): 61 def _RemoveKeys(plist, *keys):
56 """Removes a varargs of keys from the plist.""" 62 """Removes a varargs of keys from the plist."""
57 for key in keys: 63 for key in keys:
58 try: 64 try:
59 del plist[key] 65 del plist[key]
60 except KeyError: 66 except KeyError:
61 pass 67 pass
62 68
63 69
64 def _AddVersionKeys(plist, version=None): 70 def _ApplyVersionOverrides(version, keys, overrides, separator='.'):
71 """Applies version overrides.
72
73 Given a |version| string as "a.b.c.d" (assuming a default separator) with
74 version components named by |keys| then overrides any value that is present
75 in |overrides|.
76
77 >>> _ApplyVersionOverrides('a.b', ['major', 'minor'], {'minor': 'd'})
78 'a.d'
79 """
80 if not overrides:
81 return version
82 version_values = version.split(separator)
83 for i, (key, value) in enumerate(zip(keys, version_values)):
84 if key in overrides:
85 version_values[i] = overrides[key]
86 return separator.join(version_values)
87
88
89 def _AddVersionKeys(plist, version=None, overrides=None):
65 """Adds the product version number into the plist. Returns True on success and 90 """Adds the product version number into the plist. Returns True on success and
66 False on error. The error will be printed to stderr.""" 91 False on error. The error will be printed to stderr."""
67 if version: 92 if version:
68 match = re.match('\d+\.\d+\.(\d+\.\d+)$', version) 93 match = re.match('\d+\.\d+\.(\d+\.\d+)$', version)
69 if not match: 94 if not match:
70 print >>sys.stderr, 'Invalid version string specified: "%s"' % version 95 print >>sys.stderr, 'Invalid version string specified: "%s"' % version
71 return False 96 return False
72 97
73 full_version = match.group(0) 98 full_version = match.group(0)
74 bundle_version = match.group(1) 99 bundle_version = match.group(1)
75 100
76 else: 101 else:
77 # Pull in the Chrome version number. 102 # Pull in the Chrome version number.
78 VERSION_TOOL = os.path.join(TOP, 'build/util/version.py') 103 VERSION_TOOL = os.path.join(TOP, 'build/util/version.py')
79 VERSION_FILE = os.path.join(TOP, 'chrome/VERSION') 104 VERSION_FILE = os.path.join(TOP, 'chrome/VERSION')
80 105
81 (stdout, retval1) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t', 106 (stdout, retval1) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
82 '@MAJOR@.@MINOR@.@BUILD@.@PATCH@']) 107 '@MAJOR@.@MINOR@.@BUILD@.@PATCH@'])
83 full_version = stdout.rstrip() 108 full_version = _ApplyVersionOverrides(
109 stdout.rstrip(), ('MAJOR', 'MINOR', 'BUILD', 'PATCH'), overrides)
84 110
85 (stdout, retval2) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t', 111 (stdout, retval2) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
86 '@BUILD@.@PATCH@']) 112 '@BUILD@.@PATCH@'])
87 bundle_version = stdout.rstrip() 113 bundle_version = _ApplyVersionOverrides(
114 stdout.rstrip(), ('BUILD', 'PATCH'), overrides)
88 115
89 # If either of the two version commands finished with non-zero returncode, 116 # If either of the two version commands finished with non-zero returncode,
90 # report the error up. 117 # report the error up.
91 if retval1 or retval2: 118 if retval1 or retval2:
92 return False 119 return False
93 120
94 # Add public version info so "Get Info" works. 121 # Add public version info so "Get Info" works.
95 plist['CFBundleShortVersionString'] = full_version 122 plist['CFBundleShortVersionString'] = full_version
96 123
97 # Honor the 429496.72.95 limit. The maximum comes from splitting 2^32 - 1 124 # Honor the 429496.72.95 limit. The maximum comes from splitting 2^32 - 1
(...skipping 26 matching lines...) Expand all
124 # See if the operation failed. 151 # See if the operation failed.
125 _RemoveKeys(plist, 'SCMRevision') 152 _RemoveKeys(plist, 'SCMRevision')
126 if scm_revision != None: 153 if scm_revision != None:
127 plist['SCMRevision'] = scm_revision 154 plist['SCMRevision'] = scm_revision
128 elif add_keys: 155 elif add_keys:
129 print >>sys.stderr, 'Could not determine SCM revision. This may be OK.' 156 print >>sys.stderr, 'Could not determine SCM revision. This may be OK.'
130 157
131 return True 158 return True
132 159
133 160
134 def _AddBreakpadKeys(plist, branding): 161 def _AddBreakpadKeys(plist, branding, platform):
135 """Adds the Breakpad keys. This must be called AFTER _AddVersionKeys() and 162 """Adds the Breakpad keys. This must be called AFTER _AddVersionKeys() and
136 also requires the |branding| argument.""" 163 also requires the |branding| argument."""
137 plist['BreakpadReportInterval'] = '3600' # Deliberately a string. 164 plist['BreakpadReportInterval'] = '3600' # Deliberately a string.
138 plist['BreakpadProduct'] = '%s_Mac' % branding 165 plist['BreakpadProduct'] = '%s_%s' % (
166 branding, {'mac': 'Mac', 'ios': 'iOS'}[platform])
139 plist['BreakpadProductDisplay'] = branding 167 plist['BreakpadProductDisplay'] = branding
140 plist['BreakpadVersion'] = plist['CFBundleShortVersionString'] 168 plist['BreakpadVersion'] = plist['CFBundleShortVersionString']
141 # These are both deliberately strings and not boolean. 169 # These are both deliberately strings and not boolean.
142 plist['BreakpadSendAndExit'] = 'YES' 170 plist['BreakpadSendAndExit'] = 'YES'
143 plist['BreakpadSkipConfirm'] = 'YES' 171 plist['BreakpadSkipConfirm'] = 'YES'
144 172
145 173
146 def _RemoveBreakpadKeys(plist): 174 def _RemoveBreakpadKeys(plist):
147 """Removes any set Breakpad keys.""" 175 """Removes any set Breakpad keys."""
148 _RemoveKeys(plist, 176 _RemoveKeys(plist,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 help='Enable Breakpad\'s uploading of crash dumps [1 or 0]') 241 help='Enable Breakpad\'s uploading of crash dumps [1 or 0]')
214 parser.add_option('--keystone', dest='use_keystone', action='store', 242 parser.add_option('--keystone', dest='use_keystone', action='store',
215 type='int', default=False, help='Enable Keystone [1 or 0]') 243 type='int', default=False, help='Enable Keystone [1 or 0]')
216 parser.add_option('--scm', dest='add_scm_info', action='store', type='int', 244 parser.add_option('--scm', dest='add_scm_info', action='store', type='int',
217 default=True, help='Add SCM metadata [1 or 0]') 245 default=True, help='Add SCM metadata [1 or 0]')
218 parser.add_option('--branding', dest='branding', action='store', 246 parser.add_option('--branding', dest='branding', action='store',
219 type='string', default=None, help='The branding of the binary') 247 type='string', default=None, help='The branding of the binary')
220 parser.add_option('--bundle_id', dest='bundle_identifier', 248 parser.add_option('--bundle_id', dest='bundle_identifier',
221 action='store', type='string', default=None, 249 action='store', type='string', default=None,
222 help='The bundle id of the binary') 250 help='The bundle id of the binary')
251 parser.add_option('--platform', choices=('ios', 'mac'), default='mac',
TVL 2016/06/03 15:49:11 Why not "iOS" and "Mac" so you don't have to do a
sdefresne 2016/06/03 16:11:45 This value will be passed from BUILD.gn or *.gyp f
TVL 2016/06/03 16:24:27 That's fair, minor nit then: you might want to do
sdefresne 2016/06/03 16:29:04 Done.
252 help='The target platform of the bundle')
253 parser.add_option('--version-overrides', action='append',
254 help='Key-value pair to override specific component of version')
TVL 2016/06/03 15:49:11 Like --version does, you probably want to give an
sdefresne 2016/06/03 16:11:45 Done.
255 parser.add_option('--format', choices=('binary1', 'xml1', 'json'),
256 default='xml1', help='Format to use when writing property list')
223 parser.add_option('--version', dest='version', action='store', type='string', 257 parser.add_option('--version', dest='version', action='store', type='string',
224 default=None, help='The version string [major.minor.build.patch]') 258 default=None, help='The version string [major.minor.build.patch]')
225 (options, args) = parser.parse_args(argv) 259 (options, args) = parser.parse_args(argv)
226 260
227 if len(args) > 0: 261 if len(args) > 0:
228 print >>sys.stderr, parser.get_usage() 262 print >>sys.stderr, parser.get_usage()
229 return 1 263 return 1
230 264
231 if not options.plist_path: 265 if not options.plist_path:
232 print >>sys.stderr, 'No --plist specified.' 266 print >>sys.stderr, 'No --plist specified.'
233 return 1 267 return 1
234 268
235 # Read the plist into its parsed format. 269 # Read the plist into its parsed format. Convert the file to 'xml1' as
236 plist = plistlib.readPlist(options.plist_path) 270 # plistlib only supports that format in Python 2.7.
271 with tempfile.NamedTemporaryFile() as temp_info_plist:
272 retcode = _ConvertPlist(options.plist_path, temp_info_plist.name, 'xml1')
273 if retcode != 0:
274 return retcode
275 plist = plistlib.readPlist(temp_info_plist.name)
276
277 # Convert overrides.
278 overrides = {}
279 if options.version_overrides:
280 for pair in options.version_overrides:
281 if not '=' in pair:
282 print >>sys.stderr, 'Invalid value for --version-overrides:', pair
283 return 1
284 key, value = pair.split('=', 1)
285 overrides[key] = value
TVL 2016/06/03 15:49:11 Do you want to validate the key to ensure it is on
sdefresne 2016/06/03 16:11:45 Done.
237 286
238 # Insert the product version. 287 # Insert the product version.
239 if not _AddVersionKeys(plist, version=options.version): 288 if not _AddVersionKeys(plist, version=options.version, overrides=overrides):
240 return 2 289 return 2
241 290
242 # Add Breakpad if configured to do so. 291 # Add Breakpad if configured to do so.
243 if options.use_breakpad: 292 if options.use_breakpad:
244 if options.branding is None: 293 if options.branding is None:
245 print >>sys.stderr, 'Use of Breakpad requires branding.' 294 print >>sys.stderr, 'Use of Breakpad requires branding.'
246 return 1 295 return 1
247 _AddBreakpadKeys(plist, options.branding) 296 _AddBreakpadKeys(plist, options.branding, options.platform)
248 if options.breakpad_uploads: 297 if options.breakpad_uploads:
249 plist['BreakpadURL'] = 'https://clients2.google.com/cr/report' 298 plist['BreakpadURL'] = 'https://clients2.google.com/cr/report'
250 else: 299 else:
251 # This allows crash dumping to a file without uploading the 300 # This allows crash dumping to a file without uploading the
252 # dump, for testing purposes. Breakpad does not recognise 301 # dump, for testing purposes. Breakpad does not recognise
253 # "none" as a special value, but this does stop crash dump 302 # "none" as a special value, but this does stop crash dump
254 # uploading from happening. We need to specify something 303 # uploading from happening. We need to specify something
255 # because if "BreakpadURL" is not present, Breakpad will not 304 # because if "BreakpadURL" is not present, Breakpad will not
256 # register its crash handler and no crash dumping will occur. 305 # register its crash handler and no crash dumping will occur.
257 plist['BreakpadURL'] = 'none' 306 plist['BreakpadURL'] = 'none'
258 else: 307 else:
259 _RemoveBreakpadKeys(plist) 308 _RemoveBreakpadKeys(plist)
260 309
261 # Add Keystone if configured to do so. 310 # Add Keystone if configured to do so.
262 if options.use_keystone: 311 if options.use_keystone:
263 if options.bundle_identifier is None: 312 if options.bundle_identifier is None:
264 print >>sys.stderr, 'Use of Keystone requires the bundle id.' 313 print >>sys.stderr, 'Use of Keystone requires the bundle id.'
265 return 1 314 return 1
266 _AddKeystoneKeys(plist, options.bundle_identifier) 315 _AddKeystoneKeys(plist, options.bundle_identifier)
267 else: 316 else:
268 _RemoveKeystoneKeys(plist) 317 _RemoveKeystoneKeys(plist)
269 318
270 # Adds or removes any SCM keys. 319 # Adds or removes any SCM keys.
271 if not _DoSCMKeys(plist, options.add_scm_info): 320 if not _DoSCMKeys(plist, options.add_scm_info):
272 return 3 321 return 3
273 322
274 # Now that all keys have been mutated, rewrite the file.
275 temp_info_plist = tempfile.NamedTemporaryFile()
276 plistlib.writePlist(plist, temp_info_plist.name)
277
278 # Info.plist will work perfectly well in any plist format, but traditionally
279 # applications use xml1 for this, so convert it to ensure that it's valid.
280 output_path = options.plist_path 323 output_path = options.plist_path
281 if options.plist_output is not None: 324 if options.plist_output is not None:
282 output_path = options.plist_output 325 output_path = options.plist_output
283 proc = subprocess.Popen(['plutil', '-convert', 'xml1', 326
284 '-o', output_path, 327 # Now that all keys have been mutated, rewrite the file.
285 temp_info_plist.name]) 328 with tempfile.NamedTemporaryFile() as temp_info_plist:
286 proc.wait() 329 plistlib.writePlist(plist, temp_info_plist.name)
287 return proc.returncode 330
331 # Info.plist will work perfectly well in any plist format, but traditionally
332 # applications use xml1 for this, so convert it to ensure that it's valid.
TVL 2016/06/03 15:49:11 Comment isn't completely right, you are honoring t
sdefresne 2016/06/03 16:11:45 Done.
333 return _ConvertPlist(temp_info_plist.name, output_path, options.format)
288 334
289 335
290 if __name__ == '__main__': 336 if __name__ == '__main__':
291 sys.exit(Main(sys.argv[1:])) 337 sys.exit(Main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698