From a6898e71abf374d699ebaa121312e89bad8f100a Mon Sep 17 00:00:00 2001 From: Josip Sokcevic Date: Thu, 23 Feb 2023 17:57:25 +0000 Subject: [PATCH] Add presubmit check for git submodule This change allows repos that use depot_tools to have submodules. It relies on a "magic" text `SUBMODULE_MIGRATION` and `use_git_submodules`in DEPS file. SUBMODULE_MIGRATION is placed in DEPS file when git submodules should be accepted but parity with DEPS file is expected. We don't rely on gclient getdep as it's too slow for a presubmit check. Instead, we just naively check presence of git submodule commit hash in the DEPS file. use_git_submodules (to be a proper variable in DEPS file) indicates the project migrated to git submodules and no git dependencies are specified in DEPS file. R=aravindvasudev@google.com, jojwang@google.com Bug: 1417051 Change-Id: I03fcd98a001ee8513740108e58bc1dfe3c9a460e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4262472 Reviewed-by: Aravind Vasudevan Commit-Queue: Josip Sokcevic --- presubmit_canned_checks.py | 65 ++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py index 8b9246edf..dc90c7e48 100644 --- a/presubmit_canned_checks.py +++ b/presubmit_canned_checks.py @@ -1737,19 +1737,58 @@ def CheckForCommitObjects(input_api, output_api): ['git', 'ls-tree', '-r', '--full-tree', 'HEAD'], cwd=input_api.PresubmitLocalPath() ).decode('utf8') - tree_entries = full_tree.split('\n') - tree_entries = [x for x in tree_entries if len(x) > 0] - tree_entries = map(parse_tree_entry, tree_entries) - bad_tree_entries = [x for x in tree_entries if x[1] == 'commit'] - bad_tree_entries = [x[3] for x in bad_tree_entries] - if len(bad_tree_entries) > 0: - return [output_api.PresubmitError( - 'Commit objects present within tree.\n' - 'This may be due to submodule-related interactions; the presence of a\n' - 'commit object in the tree may lead to odd situations where files are\n' - 'inconsistently checked-out. Remove these commit entries and validate\n' - 'your changeset again:\n', - bad_tree_entries)] + # deps_entry holds tree entry for the root DEPS file. + deps_entry = None + # commit_tree_entries holds all commit entries (ie gitlink, submodule record). + commit_tree_entries = [] + for entry in full_tree.strip().split('\n'): + tree_entry = parse_tree_entry(entry) + if tree_entry[1] == 'commit': + commit_tree_entries.append(tree_entry) + if tree_entry[3] == 'DEPS': + deps_entry = tree_entry + + if len(commit_tree_entries) > 0: + if not deps_entry: + # No DEPS file, carry on! + return [] + + # This gets DEPS file from HEAD (the same as local DEPS file if there's no + # modification). + deps_content = input_api.subprocess.check_output( + ['git', 'cat-file', 'blob', deps_entry[2]], + cwd=input_api.PresubmitLocalPath()).decode('utf8') + + if 'use_git_submodules' in deps_content: + # git submodule is source of truth, so no further action needed. + return [] + + if not 'SUBMODULE_MIGRATION' in deps_content: + commit_tree_entries = [x[3] for x in commit_tree_entries] + return [ + output_api.PresubmitError( + 'Commit objects present within tree.\n' + 'This may be due to submodule-related interactions;\n' + 'the presence of a commit object in the tree may lead to odd\n' + 'situations where files are inconsistently checked-out.\n' + 'Remove these commit entries and validate your changeset ' + 'again:\n', commit_tree_entries) + ] + + mismatch_entries = [] + for commit_tree_entry in commit_tree_entries: + # Search for commit hashes in DEPS file - they must be present + if commit_tree_entry[2] not in deps_content: + mismatch_entries.append(commit_tree_entry[3]) + if mismatch_entries: + return [ + output_api.PresubmitError( + 'DEPS file indicates git submodule migration is in progress,\n' + 'but the commit objects do not match DEPS entries.\n' + 'Update the following commit objects or DEPS entries:\n', + mismatch_entries) + ] + return []