Files
cdesouza-chromium 1796f9c9a0 [brockit] Tooling path further restructure for relative paths (#36322)
This change does further restruturing to `tools/cr`, as now we are fully
reliant on paths being completely relative, and derived primarily from
`Repository.brave.root` as an anchor for all other relative paths.

With relative paths already landed, we can now further break down
`alias`, and make tests more reliable, by using `FakeChromiumSrc`
sandboxing for all tests. In particular, `tools/cr/commit.py` has also
been introduced, and now the hook destination path is fully relative to
`brave-core` root. This potentially fixes a recurring issue that in some
cases running tests for `install-hook` was uninstalling hooks in the
current `brave-core` checkout.

As an additional, `git cr` calls were not propagating the `cwd`
correctly, and this can now be corrected too.

This change also adds a README.md, to provide some overview of this
path, and some instructions that may be useful to be picked by AI agents
when writing tests.

For better guarantees, `vpython3_utils.py` now handles the file path
resolution to the vpython3 runtime across all applications in this path.

Finally, logging policy is now established with a default logger for
anything using `terminal.py`. This logger can be replaced by individual
applications, but it is of great benefit to be able to call anything
using `terminal.py` with `--verbose` at any moment.
2026-05-11 17:27:13 +01:00

159 lines
5.5 KiB
Python
Executable File

#!/usr/bin/env vpython3
# Copyright (c) 2026 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.
"""git_cr — brave-core git helper.
Subcommands:
- commit Commit with brave-core hook flags.
- follow-renames Repair brave-core artefacts after upstream Chromium
renames.
- mv Move a file/directory in brave-core and repair every
downstream artefact.
- install-hook Install the commit-msg hook from
tools/cr/alias/commit-msg.py.
- setup-alias Register the `git cr` alias in the local .git/config.
Installing the alias
--------------------
From inside the brave-core repository, run once:
vpython3 tools/cr/alias/cmd.py setup-alias
This writes a 'cr' entry to .git/config so that 'git cr' works immediately
in the current repository without modifying any shell config files.
Installing the hook
-------------------
From inside the brave-core repository, run once:
git cr install-hook
This creates a symlink so that future updates to commit-msg.py are
reflected automatically without re-running this command.
"""
from __future__ import annotations
import platform
import stat
import subprocess
import sys
from pathlib import Path
import _boot # noqa: F401
import repository
from alias.base import (HOOK_DEST, HOOK_SOURCE, WINDOWS_SHIM,
UserValidationError, check_hooks_path)
from alias.commit import cmd_commit
from vpython_utils import VPYTHON3_PATH
def _to_alias_path(p: Path) -> str:
"""Returns `p` in a form suitable for embedding in a git !alias.
Absolute paths are POSIX-normalised, with Windows drive-letter
translation (C:/… → /c/…) for git's bundled bash. Relative paths — used
for bare command names like `vpython3` — are passed through verbatim so
bash resolves them via $PATH at alias-invocation time.
"""
if not p.is_absolute():
return p.as_posix()
posix = p.as_posix()
if platform.system() == 'Windows':
posix = '/' + posix[0].lower() + posix[2:]
return posix
# This script's path, in POSIX form for embedding in a git alias.
_SCRIPT_PATH: str = _to_alias_path(Path(__file__).resolve())
# `vpython3` invocation for the alias body. `VPYTHON3_PATH` is either a bare
# `Path('vpython3')` (when depot_tools is on PATH) or an absolute path to
# Chromium's bundled `third_party/depot_tools/vpython3` (when it isn't).
_VPYTHON3_PATH: str = _to_alias_path(VPYTHON3_PATH)
def cmd_install_hook() -> int:
"""Install the commit-msg hook from the source tree.
On POSIX a symlink is created so that edits to commit-msg.py take effect
immediately without re-running this command. On Windows, where symlinks
require elevated privileges, a small #!/bin/sh shim is written instead;
Git for Windows uses its bundled bash to run hooks regardless of the host
OS, so a shebang script works correctly.
"""
check_hooks_path()
HOOK_DEST.parent.mkdir(parents=True, exist_ok=True)
if HOOK_DEST.exists() or HOOK_DEST.is_symlink():
HOOK_DEST.unlink()
if platform.system() == 'Windows':
HOOK_DEST.write_bytes(WINDOWS_SHIM)
HOOK_DEST.chmod(HOOK_DEST.stat().st_mode | stat.S_IXUSR
| stat.S_IXGRP
| stat.S_IXOTH)
else:
HOOK_DEST.symlink_to(HOOK_SOURCE)
HOOK_SOURCE.chmod(HOOK_SOURCE.stat().st_mode | stat.S_IXUSR
| stat.S_IXGRP | stat.S_IXOTH)
print(f'Installed: {HOOK_DEST}{HOOK_SOURCE}')
return 0
def cmd_setup_alias() -> int:
"""Register 'git cr' as a local git alias pointing to this script.
Writes to .git/config so no shell config files are touched. The alias
works on Linux, macOS, and Windows (Git for Windows) without any extra
setup steps.
"""
# `!`-prefixed aliases run from the work-tree top by default, masking the
# user's actual cwd. Restore it via $GIT_PREFIX (git's path-from-top hint)
# so relative paths and `git rev-parse --show-cdup` behave as expected.
alias_value = (f'!cd "${{GIT_PREFIX:-.}}" && '
f'"{_VPYTHON3_PATH}" "{_SCRIPT_PATH}"')
try:
repository.brave.run_git('config', '--local', 'alias.cr', alias_value)
except subprocess.CalledProcessError as e:
raise UserValidationError(f'git_cr: {e.stderr.strip()}') from e
print('Installed: git alias.cr')
print('Run "git cr" for usage.')
return 0
def main() -> int:
"""Dispatch to the requested subcommand."""
args = sys.argv[1:]
if not args:
print(__doc__)
return 0
try:
subcmd, rest = args[0], args[1:]
if subcmd == 'commit':
return cmd_commit(rest)
if subcmd == 'install-hook':
return cmd_install_hook()
if subcmd == 'setup-alias':
return cmd_setup_alias()
if subcmd == 'mv':
import alias.mv
return alias.mv.cmd_mv(rest)
if subcmd == 'follow-renames':
import alias.follow_renames
return alias.follow_renames.cmd_follow_renames(rest)
except UserValidationError as e:
print(e, file=sys.stderr)
return 1
print(f"git_cr: unknown subcommand '{subcmd}'", file=sys.stderr)
print(__doc__, file=sys.stderr)
return 1
if __name__ == '__main__':
try:
sys.exit(main())
except KeyboardInterrupt:
sys.exit(130)