1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Helper script to repack paks for a list of locales.
7
8Gyp doesn't have any built-in looping capability, so this just provides a way to
9loop over a list of locales when repacking pak files, thus avoiding a
10proliferation of mostly duplicate, cut-n-paste gyp actions.
11"""
12
13import optparse
14import os
15import sys
16
17sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..',
18                             'tools', 'grit'))
19from grit.format import data_pack
20
21# The gyp "branding" variable.
22BRANDING = None
23
24# Some build paths defined by gyp.
25GRIT_DIR = None
26SHARE_INT_DIR = None
27INT_DIR = None
28
29# The target platform. If it is not defined, sys.platform will be used.
30OS = None
31
32# Extra input files.
33EXTRA_INPUT_FILES = []
34
35class Usage(Exception):
36  def __init__(self, msg):
37    self.msg = msg
38
39
40def calc_output(locale):
41  """Determine the file that will be generated for the given locale."""
42  #e.g. '<(INTERMEDIATE_DIR)/repack/da.pak',
43  # For Fake Bidi, generate it at a fixed path so that tests can safely
44  # reference it.
45  if locale == 'fake-bidi':
46    return '%s/%s.pak' % (INT_DIR, locale)
47  if OS == 'mac' or OS == 'ios':
48    # For Cocoa to find the locale at runtime, it needs to use '_' instead
49    # of '-' (http://crbug.com/20441).  Also, 'en-US' should be represented
50    # simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
51    if locale == 'en-US':
52      locale = 'en'
53    return '%s/repack/%s.lproj/locale.pak' % (INT_DIR, locale.replace('-', '_'))
54  else:
55    return os.path.join(INT_DIR, 'repack', locale + '.pak')
56
57
58def calc_inputs(locale):
59  """Determine the files that need processing for the given locale."""
60  inputs = []
61
62  #e.g. '<(grit_out_dir)/generated_resources_da.pak'
63  inputs.append(os.path.join(GRIT_DIR, 'generated_resources_%s.pak' % locale))
64
65  #e.g. '<(grit_out_dir)/locale_settings_da.pak'
66  inputs.append(os.path.join(GRIT_DIR, 'locale_settings_%s.pak' % locale))
67
68  #e.g. '<(grit_out_dir)/platform_locale_settings_da.pak'
69  inputs.append(os.path.join(GRIT_DIR,
70                'platform_locale_settings_%s.pak' % locale))
71
72  #e.g. '<(SHARED_INTERMEDIATE_DIR)/components/strings/
73  # component_strings_da.pak',
74  inputs.append(os.path.join(SHARE_INT_DIR, 'components', 'strings',
75                'component_strings_%s.pak' % locale))
76
77  if OS != 'ios':
78    #e.g. '<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_strings_da.pak'
79    inputs.append(os.path.join(SHARE_INT_DIR, 'webkit',
80                  'webkit_strings_%s.pak' % locale))
81
82    #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/ui_strings_da.pak',
83    inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'ui_strings',
84                  'ui_strings_%s.pak' % locale))
85
86    #e.g. '<(SHARED_INTERMEDIATE_DIR)/ash_strings/ash_strings_da.pak',
87    inputs.append(os.path.join(SHARE_INT_DIR, 'ash_strings',
88                  'ash_strings_%s.pak' % locale))
89
90    #e.g. '<(SHARED_INTERMEDIATE_DIR)/device/bluetooth/strings/
91    # device_bluetooth_strings_da.pak',
92    inputs.append(os.path.join(SHARE_INT_DIR, 'device', 'bluetooth', 'strings',
93                  'device_bluetooth_strings_%s.pak' % locale))
94
95    #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/app_locale_settings_da.pak',
96    inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'app_locale_settings',
97                  'app_locale_settings_%s.pak' % locale))
98
99  #e.g. '<(grit_out_dir)/google_chrome_strings_da.pak'
100  #     or
101  #     '<(grit_out_dir)/chromium_strings_da.pak'
102  inputs.append(os.path.join(
103      GRIT_DIR, '%s_strings_%s.pak' % (BRANDING, locale)))
104
105  # Add any extra input files.
106  for extra_file in EXTRA_INPUT_FILES:
107    inputs.append('%s_%s.pak' % (extra_file, locale))
108
109  return inputs
110
111
112def list_outputs(locales):
113  """Returns the names of files that will be generated for the given locales.
114
115  This is to provide gyp the list of output files, so build targets can
116  properly track what needs to be built.
117  """
118  outputs = []
119  for locale in locales:
120    outputs.append(calc_output(locale))
121  # Quote each element so filename spaces don't mess up gyp's attempt to parse
122  # it into a list.
123  return " ".join(['"%s"' % x for x in outputs])
124
125
126def list_inputs(locales):
127  """Returns the names of files that will be processed for the given locales.
128
129  This is to provide gyp the list of input files, so build targets can properly
130  track their prerequisites.
131  """
132  inputs = []
133  for locale in locales:
134    inputs += calc_inputs(locale)
135  # Quote each element so filename spaces don't mess up gyp's attempt to parse
136  # it into a list.
137  return " ".join(['"%s"' % x for x in inputs])
138
139
140def repack_locales(locales):
141  """ Loop over and repack the given locales."""
142  for locale in locales:
143    inputs = []
144    inputs += calc_inputs(locale)
145    output = calc_output(locale)
146    data_pack.DataPack.RePack(output, inputs)
147
148
149def DoMain(argv):
150  global BRANDING
151  global GRIT_DIR
152  global SHARE_INT_DIR
153  global INT_DIR
154  global OS
155  global EXTRA_INPUT_FILES
156
157  parser = optparse.OptionParser("usage: %prog [options] locales")
158  parser.add_option("-i", action="store_true", dest="inputs", default=False,
159                    help="Print the expected input file list, then exit.")
160  parser.add_option("-o", action="store_true", dest="outputs", default=False,
161                    help="Print the expected output file list, then exit.")
162  parser.add_option("-g", action="store", dest="grit_dir",
163                    help="GRIT build files output directory.")
164  parser.add_option("-x", action="store", dest="int_dir",
165                    help="Intermediate build files output directory.")
166  parser.add_option("-s", action="store", dest="share_int_dir",
167                    help="Shared intermediate build files output directory.")
168  parser.add_option("-b", action="store", dest="branding",
169                    help="Branding type of this build.")
170  parser.add_option("-e", action="append", dest="extra_input", default=[],
171                    help="Full path to an extra input pak file without the\
172                         locale suffix and \".pak\" extension.")
173  parser.add_option("-p", action="store", dest="os",
174                    help="The target OS. (e.g. mac, linux, win, etc.)")
175  options, locales = parser.parse_args(argv)
176
177  if not locales:
178    parser.error('Please specificy at least one locale to process.\n')
179
180  print_inputs = options.inputs
181  print_outputs = options.outputs
182  GRIT_DIR = options.grit_dir
183  INT_DIR = options.int_dir
184  SHARE_INT_DIR = options.share_int_dir
185  BRANDING = options.branding
186  EXTRA_INPUT_FILES = options.extra_input
187  OS = options.os
188
189  if not OS:
190    if sys.platform == 'darwin':
191      OS = 'mac'
192    elif sys.platform.startswith('linux'):
193      OS = 'linux'
194    elif sys.platform in ('cygwin', 'win32'):
195      OS = 'win'
196    else:
197      OS = sys.platform
198
199  if not (GRIT_DIR and INT_DIR and SHARE_INT_DIR):
200    parser.error('Please specify all of "-g" and "-x" and "-s".\n')
201  if print_inputs and print_outputs:
202    parser.error('Please specify only one of "-i" or "-o".\n')
203  # Need to know the branding, unless we're just listing the outputs.
204  if not print_outputs and not BRANDING:
205    parser.error('Please specify "-b" to determine the input files.\n')
206
207  if print_inputs:
208    return list_inputs(locales)
209
210  if print_outputs:
211    return list_outputs(locales)
212
213  return repack_locales(locales)
214
215if __name__ == '__main__':
216  results = DoMain(sys.argv[1:])
217  if results:
218    print results
219