File: PRESUBMIT.py

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; 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,697 bytes parent folder | download | duplicates (4)
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 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Presubmit script for changes affecting deprecations.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""

import difflib
import os
import sys


# Deprecations in this list have no `WebFeature`s to generate code from as they
# are not dispatched within the renderer. If this list starts to grow we should
# add more formal support.
EXEMPTED_FROM_RENDERER_GENERATION = {
    "PrivacySandboxExtensionsAPI": True,
}

# pyright: reportMissingImports=false
def _LoadDeprecation(input_api, filename):
    """Returns the deprecations present in the specified JSON5 file."""

    # We need to wait until we have an input_api object and use this
    # roundabout construct to import json5 because this file is
    # eval-ed and thus doesn't have __file__.
    try:
        json5_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                            '..', '..', '..', '..', '..',
                                            'pyjson5', 'src')
        sys.path.append(json5_path)
        import json5
        return json5.load(open(filename, encoding='utf-8'))['data']
    finally:
        # Restore sys.path to what it was before.
        sys.path.remove(json5_path)


def _CheckDeprecation(input_api, output_api):
    """Check: deprecation.json5 is well formed.
    """
    # Read deprecation.json5 using the JSON5 parser.
    filename = os.path.join(input_api.PresubmitLocalPath(),
                            'deprecation.json5')
    deprecations = _LoadDeprecation(input_api, filename)

    # Parse deprecations for correctness.
    deprecation_names = []
    for deprecation in deprecations:
        if 'name' not in deprecation or not deprecation['name']:
            return [
                output_api.PresubmitError(
                    'deprecation.json5 items must all contain a non-empty "name" value.'
                )
            ]
        deprecation_names.append(deprecation['name'])
        if 'message' not in deprecation or not deprecation['message']:
            return [
                output_api.PresubmitError(
                    'deprecation.json5 items must all contain a non-empty "message" value.'
                )
            ]
        if len(deprecation['message']) != len(deprecation['message'].encode()):
            return [
                output_api.PresubmitError(
                    'deprecation.json5 items must all contain fully ascii "message" values.'
                )
            ]
        if 'translation_note' not in deprecation or not deprecation[
                'translation_note']:
            return [
                output_api.PresubmitError(
                    'deprecation.json5 items must all contain a non-empty '
                    '"translation_note" value.'
                )
            ]
        if len(deprecation['translation_note']) != len(
                deprecation['translation_note'].encode()):
            return [
                output_api.PresubmitError(
                    'deprecation.json5 items must all contain fully ascii '
                    '"translation_note" values.'
                )
            ]
        if 'web_features' in deprecation and deprecation['web_features']:
            sorted_web_features = sorted(deprecation['web_features'],
                                         key=lambda s: s.lower())
            if deprecation['web_features'] != sorted_web_features:
                differ = difflib.Differ()
                diff = differ.compare(deprecation['web_features'],
                                      sorted_web_features)
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items web_features must be sorted alphabetically. '
                        'Diff of web_features data order follows:',
                        long_text='\n'.join(diff))
                ]
        else:
            if deprecation['name'] not in EXEMPTED_FROM_RENDERER_GENERATION:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items must all contain a non-empty '
                        'list of "web_features".'
                    )
                ]
        if 'chrome_status_feature' in deprecation:
            if not deprecation['chrome_status_feature']:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items can omit chrome_status_feature,'
                        'but if included it must have a value.'
                    )
                ]
            if deprecation[
                    'chrome_status_feature'] < 1000000000000000 or deprecation[
                        'chrome_status_feature'] > 9999999999999999:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items with a chrome_status_feature '
                        'must have one in the valid range.'
                    )
                ]
        if 'milestone' in deprecation:
            if not deprecation['milestone']:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items can omit milestone, but if '
                        'included it must have a value.'
                    )
                ]
            if deprecation['milestone'] < 1 or deprecation['milestone'] > 1000:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items with a milestone must have '
                        'one in the valid range.'
                    )
                ]
        if 'obsolete_to_be_removed_after_milestone' in deprecation:
            if not deprecation['obsolete_to_be_removed_after_milestone']:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items can omit milestone, but if '
                        'included it must have a value.'
                    )
                ]
            if deprecation[
                    'obsolete_to_be_removed_after_milestone'] < 1 or deprecation[
                        'obsolete_to_be_removed_after_milestone'] > 1000:
                return [
                    output_api.PresubmitError(
                        'deprecation.json5 items with an '
                        'obsolete_to_be_removed_after_milestone must have a '
                        'milestone in the valid range.'
                    )
                ]

    # Parse deprecations for ordering.
    deprecation_names_sorted = sorted(deprecation_names,
                                      key=lambda s: s.lower())
    if deprecation_names == deprecation_names_sorted:
        return []
    differ = difflib.Differ()
    diff = differ.compare(deprecation_names, deprecation_names_sorted)
    return [
        output_api.PresubmitError(
            'deprecation.json5 items must be sorted alphabetically. '
            'Diff of deprecation data order follows:',
            long_text='\n'.join(diff))
    ]


def _CommonChecks(input_api, output_api):
    """Checks common to both upload and commit."""
    results = []
    results.extend(_CheckDeprecation(input_api, output_api))
    return results


def CheckChangeOnUpload(input_api, output_api):
    return _CommonChecks(input_api, output_api)


def CheckChangeOnCommit(input_api, output_api):
    return _CommonChecks(input_api, output_api)