File: generate_grd.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (186 lines) | stat: -rw-r--r-- 7,849 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Generates a grit grd file from a list of input manifest files. This is useful
# for preventing the need to list JS files in multiple locations, as files can
# be listed just once in the BUILD.gn file as inputs for a build rule that knows
# how to output such a manifest (e.g. preprocess_if_expr).
#
# Variables:
#   manifest-files:
#      List of paths to manifest files. Each must contain a JSON object with
#      2 fields:
#      - base_dir, the base directory where the files are located
#      - files, a list of file paths from the base directory
#
#   out_grd:
#     Path where the generated grd file should be written.
#
#   grd_prefix:
#     Used to generate both grit IDs for included files and names for the
#     header/pak/resource map files specified in the <outputs> section of the
#     grd file. For example, prefix "foo" will result in a grd file that has
#     as output "foo_resources.pak", "grit/foo_resources.h", etc, and has grit
#     IDs prefixed by IDS_FOO.
#
#   root_gen_dir:
#     Path to the root generated directory. Used to compute the relative path
#     from the root generated directory for setting file paths, as grd files
#     with generated file paths must specify these paths as
#     "${root_gen_dir}/<path_to_file>"
#
#   input_files:
#     List of file paths (from |input_files_base_dir|) that are not included in
#     any manifest files, but should be added to the grd.
#
#   input_files_base_dir:
#     The base directory for the paths in |input_files|. |input_files| and
#     |input_files_base_dir| must either both be provided or both be omitted.

import argparse
import json
import os
import sys

_CWD = os.getcwd()

GRD_BEGIN_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>\n'\
                     '<grit latest_public_release="0" current_release="1">\n'\
                     '  <outputs>\n'\
                     '    <output filename="{out_dir}/{prefix}_resources.h" '\
                     'type="rc_header">\n'\
                     '      <emit emit_type=\'prepend\'></emit>\n'\
                     '    </output>\n'\
                     '    <output filename="{out_dir}/{prefix}_resources_map.cc"\n'\
                     '            type="resource_file_map_source" />\n'\
                     '    <output filename="{out_dir}/{prefix}_resources_map.h"\n'\
                     '            type="resource_map_header" />\n'\
                     '    <output filename="{prefix}_resources.pak" '\
                     'type="data_package" />\n'\
                     '  </outputs>\n'\
                     '  <release seq="1">\n'\
                     '    <includes>\n'

GRD_INCLUDE_TEMPLATE = '      <include name="{name}" ' \
                       'file="{file}" resource_path="{path}" ' \
                       'use_base_dir="false" type="{type}" />\n'

GRD_END_TEMPLATE = '    </includes>\n'\
                   '  </release>\n'\
                   '</grit>\n'

GRDP_BEGIN_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>\n'\
                     '<grit-part>\n'
GRDP_END_TEMPLATE = '</grit-part>\n'

# Generates an <include .... /> row for the given file.
def _generate_include_row(grd_prefix, filename, pathname, \
                          resource_path_rewrites, resource_path_prefix):
  assert '\\' not in filename
  assert '\\' not in pathname
  name_suffix = filename.upper().replace('/', '_').replace('.', '_'). \
          replace('-', '_').replace('@', '_AT_')
  name = 'IDR_%s_%s' % (grd_prefix.upper(), name_suffix)
  extension = os.path.splitext(filename)[1]
  type = 'chrome_html' if extension == '.html' or extension == '.js' \
          else 'BINDATA'

  resource_path = resource_path_rewrites[filename] \
      if filename in resource_path_rewrites else filename

  if resource_path_prefix != None:
    resource_path = resource_path_prefix + '/' + resource_path
  assert '\\' not in resource_path

  return GRD_INCLUDE_TEMPLATE.format(
      file=pathname,
      path=resource_path,
      name=name,
      type=type)


def _generate_part_row(filename):
  return '      <part file="%s" />\n' % filename


def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument('--manifest-files', nargs="*")
  parser.add_argument('--out-grd', required=True)
  parser.add_argument('--grd-prefix', required=True)
  parser.add_argument('--root-gen-dir', required=True)
  parser.add_argument('--input-files', nargs="*")
  parser.add_argument('--input-files-base-dir')
  parser.add_argument('--output-files-base-dir', default='grit')
  parser.add_argument('--grdp-files', nargs="*")
  parser.add_argument('--resource-path-rewrites', nargs="*")
  parser.add_argument('--resource-path-prefix')
  args = parser.parse_args(argv)

  grd_path = os.path.normpath(os.path.join(_CWD, args.out_grd))
  with open(grd_path, 'w', newline='', encoding='utf-8') as grd_file:
    begin_template = GRDP_BEGIN_TEMPLATE if args.out_grd.endswith('.grdp') \
        else GRD_BEGIN_TEMPLATE
    grd_file.write(begin_template.format(prefix=args.grd_prefix,
        out_dir=args.output_files_base_dir))

    if args.grdp_files != None:
      out_grd_dir = os.path.dirname(args.out_grd)
      for grdp_file in args.grdp_files:
        grdp_path = os.path.relpath(grdp_file, out_grd_dir).replace('\\', '/')
        grd_file.write(_generate_part_row(grdp_path))

    resource_path_rewrites = {}
    if args.resource_path_rewrites != None:
      for r in args.resource_path_rewrites:
        [original, rewrite] = r.split("|")
        resource_path_rewrites[original] = rewrite

    if args.input_files != None:
      assert(args.input_files_base_dir)
      args.input_files_base_dir = args.input_files_base_dir.replace('\\', '/')
      args.root_gen_dir = args.root_gen_dir.replace('\\', '/')

      # Detect whether the input files reside under $root_src_dir or
      # $root_gen_dir.
      base_dir = os.path.join('${root_src_dir}', args.input_files_base_dir)
      if args.input_files_base_dir.startswith(args.root_gen_dir + '/'):
        base_dir = args.input_files_base_dir.replace(
            args.root_gen_dir + '/', '${root_gen_dir}/')

      for filename in args.input_files:
        norm_base = os.path.normpath(args.input_files_base_dir)
        norm_path = os.path.normpath(os.path.join(args.input_files_base_dir,
                                                  filename))
        assert os.path.commonprefix([norm_base, norm_path]) == norm_base, \
            f'Error: input_file {filename} found outside of ' + \
            'input_files_base_dir'

        filepath = os.path.join(base_dir, filename).replace('\\', '/')
        grd_file.write(_generate_include_row(
            args.grd_prefix, filename, filepath,
            resource_path_rewrites, args.resource_path_prefix))

    if args.manifest_files != None:
      for manifest_file in args.manifest_files:
        manifest_path = os.path.normpath(os.path.join(_CWD, manifest_file))
        with open(manifest_path, 'r', encoding='utf-8') as f:
          data = json.load(f)
          base_dir= os.path.normpath(os.path.join(_CWD, data['base_dir']))
          for filename in data['files']:
            filepath = os.path.join(base_dir, filename)
            rebased_path = os.path.relpath(filepath, args.root_gen_dir)
            rebased_path = rebased_path.replace('\\', '/')
            grd_file.write(_generate_include_row(
                args.grd_prefix, filename, '${root_gen_dir}/' + rebased_path,
                resource_path_rewrites, args.resource_path_prefix))

    end_template = GRDP_END_TEMPLATE if args.out_grd.endswith('.grdp') else \
        GRD_END_TEMPLATE
    grd_file.write(end_template)
    return


if __name__ == '__main__':
  main(sys.argv[1:])