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

Unified Diff: sync/PRESUBMIT.py

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sync/OWNERS ('k') | sync/PRESUBMIT_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sync/PRESUBMIT.py
diff --git a/sync/PRESUBMIT.py b/sync/PRESUBMIT.py
deleted file mode 100644
index 9173777c327cf11b6369c8e18d23a434c7bdfc19..0000000000000000000000000000000000000000
--- a/sync/PRESUBMIT.py
+++ /dev/null
@@ -1,359 +0,0 @@
-# Copyright (c) 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for sync
-This checks that ModelTypeInfo entries in model_type.cc follow conventions.
-See CheckModelTypeInfoMap or model_type.cc for more detail on the rules.
-"""
-
-import os
-
-# Some definitions don't follow all the conventions we want to enforce.
-# It's either difficult or impossible to fix this, so we ignore the problem(s).
-GRANDFATHERED_MODEL_TYPES = [
- 'UNSPECIFIED', # Doesn't have a root tag or notification type.
- 'TOP_LEVEL_FOLDER', # Doesn't have a root tag or notification type.
- 'AUTOFILL_WALLET_DATA', # Root tag and model type string lack DATA suffix.
- 'APP_SETTINGS', # Model type string has inconsistent capitalization.
- 'EXTENSION_SETTINGS', # Model type string has inconsistent capitalization.
- 'SUPERVISED_USER_SETTINGS', # Root tag and model type string replace
- # 'Supervised' with 'Managed'
- 'SUPERVISED_USERS', # See previous.
- 'SUPERVISED_USER_WHITELISTS', # See previous.
- 'SUPERVISED_USER_SHARED_SETTINGS', # See previous.
- 'PROXY_TABS', # Doesn't have a root tag or notification type.
- 'NIGORI'] # Model type string is 'encryption keys'.
-
-# Number of distinct fields in a map entry; used to create
-# sets that check for uniqueness.
-MAP_ENTRY_FIELD_COUNT = 6
-
-# String that precedes the ModelType when referencing the
-# proto field number enum e.g.
-# sync_pb::EntitySpecifics::kManagedUserFieldNumber.
-# Used to map from enum references to the ModelType.
-FIELD_NUMBER_PREFIX = 'sync_pb::EntitySpecifics::k'
-
-# Start and end regexes for finding the EntitySpecifics definition in
-# sync.proto.
-PROTO_DEFINITION_START_PATTERN = '^message EntitySpecifics'
-PROTO_DEFINITION_END_PATTERN = '^\}'
-
-# Start and end regexes for finding the ModelTypeInfoMap definition
-# in model_type.cc.
-MODEL_TYPE_START_PATTERN = '^const ModelTypeInfo kModelTypeInfoMap'
-MODEL_TYPE_END_PATTERN = '^\};'
-
-# Strings relating to files we'll need to read.
-# model_type.cc is where the ModelTypeInfoMap is
-# sync.proto is where the proto definitions for ModelTypes are.
-PROTO_FILE_PATH = './protocol/sync.proto'
-MODEL_TYPE_FILE_NAME = 'model_type.cc'
-
-
-def CheckChangeOnUpload(input_api, output_api):
- """Preupload check function required by presubmit convention.
- See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
- """
- for f in input_api.AffectedFiles():
- if(f.LocalPath().endswith(MODEL_TYPE_FILE_NAME)):
- return CheckModelTypeInfoMap(input_api, output_api, f)
- return []
-
-
-def CheckChangeOnCommit(input_api, output_api):
- """Precommit check function required by presubmit convention.
- See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
- """
- for f in input_api.AffectedFiles():
- if f.LocalPath().endswith(MODEL_TYPE_FILE_NAME):
- return CheckModelTypeInfoMap(input_api, output_api, f)
- return []
-
-
-def CheckModelTypeInfoMap(input_api, output_api, model_type_file):
- """Checks the kModelTypeInfoMap in model_type.cc follows conventions.
- Checks that the kModelTypeInfoMap follows the below rules:
- 1) The model type string should match the model type name, but with
- only the first letter capitalized and spaces instead of underscores.
- 2) The root tag should be the same as the model type but all lowercase.
- 3) The notification type should match the proto message name.
- 4) No duplicate data across model types.
- Args:
- input_api: presubmit_support InputApi instance
- output_api: presubmit_support OutputApi instance
- model_type_file: AffectedFile object where the ModelTypeInfoMap is
- Returns:
- A (potentially empty) list PresubmitError objects corresponding to
- violations of the above rules.
- """
- accumulated_problems = []
- map_entries = ParseModelTypeEntries(
- input_api, model_type_file.AbsoluteLocalPath())
- # If any line of the map changed, we check the whole thing since
- # definitions span multiple lines and there are rules that apply across
- # all definitions e.g. no duplicated field values.
- check_map = False
- for line_num, _ in model_type_file.ChangedContents():
- for map_entry in map_entries:
- if line_num in map_entry.affected_lines:
- check_map = True
- break
-
- if not check_map:
- return []
- proto_field_definitions = ParseSyncProtoFieldIdentifiers(
- input_api, os.path.abspath(PROTO_FILE_PATH))
- accumulated_problems.extend(
- CheckNoDuplicatedFieldValues(output_api, map_entries))
-
- for map_entry in map_entries:
- entry_problems = []
- entry_problems.extend(
- CheckNotificationTypeMatchesProtoMessageName(
- output_api, map_entry, proto_field_definitions))
-
- if map_entry.model_type not in GRANDFATHERED_MODEL_TYPES:
- entry_problems.extend(
- CheckModelTypeStringMatchesModelType(output_api, map_entry))
- entry_problems.extend(
- CheckRootTagMatchesModelType(output_api, map_entry))
-
- if len(entry_problems) > 0:
- accumulated_problems.extend(entry_problems)
-
- return accumulated_problems
-
-
-class ModelTypeEnumEntry(object):
- """Class that encapsulates a ModelTypeInfo definition in model_type.cc.
- Allows access to each of the named fields in the definition and also
- which lines the definition spans.
- Attributes:
- model_type: entry's ModelType enum value
- notification_type: model type's notification string
- root_tag: model type's root tag
- model_type_string: string corresponding to the ModelType
- field_number: proto field number
- histogram_val: value identifying ModelType in histogram
- affected_lines: lines in model_type.cc that the definition spans
- """
- def __init__(self, entry_strings, affected_lines):
- (model_type, notification_type, root_tag, model_type_string,
- field_number, histogram_val) = entry_strings
- self.model_type = model_type
- self.notification_type = notification_type
- self.root_tag = root_tag
- self.model_type_string = model_type_string
- self.field_number = field_number
- self.histogram_val = histogram_val
- self.affected_lines = affected_lines
-
-
-def ParseModelTypeEntries(input_api, model_type_cc_path):
- """Parses model_type_cc_path for ModelTypeEnumEntries
- Args:
- input_api: presubmit_support InputAPI instance
- model_type_cc_path: path to file containing the ModelTypeInfo entries
- Returns:
- A list of ModelTypeEnumEntry objects read from model_type.cc.
- e.g. ('AUTOFILL_WALLET_METADATA', 'WALLET_METADATA',
- 'autofill_wallet_metadata', 'Autofill Wallet Metadata',
- 'sync_pb::EntitySpecifics::kWalletMetadataFieldNumber', '35',
- [63, 64, 65])
- """
- file_contents = input_api.ReadFile(model_type_cc_path)
- start_pattern = input_api.re.compile(MODEL_TYPE_START_PATTERN)
- end_pattern = input_api.re.compile(MODEL_TYPE_END_PATTERN)
- results, definition_strings, definition_lines = [], [], []
- inside_enum = False
- current_line_number = 1
- for line in file_contents.splitlines():
- if start_pattern.match(line):
- inside_enum = True
- continue
- if inside_enum:
- if end_pattern.match(line):
- break
- line_entries = line.strip().strip('{},').split(',')
- definition_strings.extend([entry.strip('" ') for entry in line_entries])
- definition_lines.append(current_line_number)
- if line.endswith('},'):
- results.append(ModelTypeEnumEntry(definition_strings, definition_lines))
- definition_strings = []
- definition_lines = []
- current_line_number += 1
- return results
-
-
-def ParseSyncProtoFieldIdentifiers(input_api, sync_proto_path):
- """Parses proto field identifiers from the EntitySpecifics definition.
- Args:
- input_api: presubmit_support InputAPI instance
- proto_path: path to the file containing the proto field definitions
- Returns:
- A dictionary of the format {'SyncDataType': 'field_identifier'}
- e.g. {'AutofillSpecifics': 'autofill'}
- """
- proto_field_definitions = {}
- proto_file_contents = input_api.ReadFile(sync_proto_path).splitlines()
- start_pattern = input_api.re.compile(PROTO_DEFINITION_START_PATTERN)
- end_pattern = input_api.re.compile(PROTO_DEFINITION_END_PATTERN)
- in_proto_def = False
- for line in proto_file_contents:
- if start_pattern.match(line):
- in_proto_def = True
- continue
- if in_proto_def:
- if end_pattern.match(line):
- break
- line = line.strip()
- split_proto_line = line.split(' ')
- # ignore comments and lines that don't contain definitions.
- if '//' in line or len(split_proto_line) < 3:
- continue
-
- field_typename = split_proto_line[1]
- field_identifier = split_proto_line[2]
- proto_field_definitions[field_typename] = field_identifier
- return proto_field_definitions
-
-
-def StripTrailingS(string):
- return string.rstrip('sS')
-
-
-def IsTitleCased(string):
- return reduce(lambda bool1, bool2: bool1 and bool2,
- [s[0].isupper() for s in string.split(' ')])
-
-
-def FormatPresubmitError(output_api, message, affected_lines):
- """ Outputs a formatted error message with filename and line number(s).
- """
- if len(affected_lines) > 1:
- message_including_lines = 'Error at lines %d-%d in model_type.cc: %s' %(
- affected_lines[0], affected_lines[-1], message)
- else:
- message_including_lines = 'Error at line %d in model_type.cc: %s' %(
- affected_lines[0], message)
- return output_api.PresubmitError(message_including_lines)
-
-
-def CheckNotificationTypeMatchesProtoMessageName(
- output_api, map_entry, proto_field_definitions):
- """Check that map_entry's notification type matches sync.proto.
- Verifies that the notification_type matches the name of the field defined
- in the sync.proto by looking it up in the proto_field_definitions map.
- Args:
- output_api: presubmit_support OutputApi instance
- map_entry: ModelTypeEnumEntry instance
- proto_field_definitions: dict of proto field types and field names
- Returns:
- A potentially empty list of PresubmitError objects corresponding to
- violations of the above rule
- """
- if map_entry.field_number == '-1':
- return []
- proto_message_name = proto_field_definitions[
- FieldNumberToPrototypeString(map_entry.field_number)]
- if map_entry.notification_type.lower() != proto_message_name:
- return [
- FormatPresubmitError(
- output_api,'notification type "%s" does not match proto message'
- ' name defined in sync.proto: ' '"%s"' %
- (map_entry.notification_type, proto_message_name),
- map_entry.affected_lines)]
- return []
-
-
-def CheckNoDuplicatedFieldValues(output_api, map_entries):
- """Check that map_entries has no duplicated field values.
- Verifies that every map_entry in map_entries doesn't have a field value
- used elsewhere in map_entries, ignoring special values ("" and -1).
- Args:
- output_api: presubmit_support OutputApi instance
- map_entries: list of ModelTypeEnumEntry objects to check
- Returns:
- A list PresubmitError objects for each duplicated field value
- """
- problem_list = []
- field_value_sets = [set() for i in range(MAP_ENTRY_FIELD_COUNT)]
- for map_entry in map_entries:
- field_values = [
- map_entry.model_type, map_entry.notification_type,
- map_entry.root_tag, map_entry.model_type_string,
- map_entry.field_number, map_entry.histogram_val]
- for i in range(MAP_ENTRY_FIELD_COUNT):
- field_value = field_values[i]
- field_value_set = field_value_sets[i]
- if field_value in field_value_set:
- problem_list.append(
- FormatPresubmitError(
- output_api, 'Duplicated field value "%s"' % field_value,
- map_entry.affected_lines))
- elif len(field_value) > 0 and field_value != '-1':
- field_value_set.add(field_value)
- return problem_list
-
-
-def CheckModelTypeStringMatchesModelType(output_api, map_entry):
- """Check that map_entry's model_type_string matches ModelType.
- Args:
- output_api: presubmit_support OutputApi instance
- map_entry: ModelTypeEnumEntry object to check
- Returns:
- A list of PresubmitError objects for each violation
- """
- problem_list = []
- expected_model_type_string = map_entry.model_type.lower().replace('_', ' ')
- if (StripTrailingS(expected_model_type_string) !=
- StripTrailingS(map_entry.model_type_string.lower())):
- problem_list.append(
- FormatPresubmitError(
- output_api,'model type string "%s" does not match model type.'
- ' It should be "%s"' % (
- map_entry.model_type_string, expected_model_type_string.title()),
- map_entry.affected_lines))
- if not IsTitleCased(map_entry.model_type_string):
- problem_list.append(
- FormatPresubmitError(
- output_api,'model type string "%s" should be title cased' %
- (map_entry.model_type_string), map_entry.affected_lines))
- return problem_list
-
-
-def CheckRootTagMatchesModelType(output_api, map_entry):
- """Check that map_entry's root tag matches ModelType.
- Args:
- output_api: presubmit_support OutputAPI instance
- map_entry: ModelTypeEnumEntry object to check
- Returns:
- A list of PresubmitError objects for each violation
- """
- expected_root_tag = map_entry.model_type.lower()
- if (StripTrailingS(expected_root_tag) !=
- StripTrailingS(map_entry.root_tag)):
- return [
- FormatPresubmitError(
- output_api,'root tag "%s" does not match model type. It should'
- 'be "%s"' % (map_entry.root_tag, expected_root_tag),
- map_entry.affected_lines)]
- return []
-
-
-def FieldNumberToPrototypeString(field_number):
- """Converts a field number enum reference to an EntitySpecifics string.
- Converts a reference to the field number enum to the corresponding
- proto data type string.
- Args:
- field_number: string representation of a field number enum reference
- Returns:
- A string that is the corresponding proto field data type. e.g.
- FieldNumberToPrototypeString('EntitySpecifics::kAppFieldNumber')
- => 'AppSpecifics'
- """
- return field_number.replace(FIELD_NUMBER_PREFIX, '').replace(
- 'FieldNumber', 'Specifics').replace(
- 'AppNotificationSpecifics', 'AppNotification')
« no previous file with comments | « sync/OWNERS ('k') | sync/PRESUBMIT_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698