mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 20:19:07 +00:00
health-check: Add copyright header check
New files will require a copyright header, which is checked by CI and locally. BUG=b:242605601 TEST=touch foo.rs && ./tools/health-check; ./tools/health-check --fix Change-Id: I31bf299bd636a5da4f806c32ca8bdf9cfd4c01f3 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3832787 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: Dennis Kempin <denniskempin@google.com> Commit-Queue: Dennis Kempin <denniskempin@google.com>
This commit is contained in:
parent
7b5f6b198f
commit
34a4ee662f
2 changed files with 76 additions and 9 deletions
|
@ -3,11 +3,22 @@
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
# Use of this source code is governed by a BSD-style license that can be
|
||||||
# found in the LICENSE file.
|
# found in the LICENSE file.
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
import sys
|
|
||||||
from impl.common import CROSVM_ROOT, parallel, run_main, cmd, chdir, argh, cwd_context
|
|
||||||
from impl.check_code_hygiene import has_crlf_line_endings
|
from impl.check_code_hygiene import has_crlf_line_endings
|
||||||
|
from impl.common import (
|
||||||
|
CROSVM_ROOT,
|
||||||
|
argh,
|
||||||
|
chdir,
|
||||||
|
cmd,
|
||||||
|
cwd_context,
|
||||||
|
parallel,
|
||||||
|
run_main,
|
||||||
|
)
|
||||||
from impl.health_check import Check, CheckContext, run_checks
|
from impl.health_check import Check, CheckContext, run_checks
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,8 +85,55 @@ def check_rust_lockfiles(_: CheckContext):
|
||||||
raise Exception("Cargo.lock out of date")
|
raise Exception("Cargo.lock out of date")
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE_HEADER_RE = (
|
||||||
|
# Line 1 - copyright.
|
||||||
|
r".*Copyright(?P<copyright> \(c\))? (?P<year>20[0-9]{2})(?:-20[0-9]{2})? "
|
||||||
|
r"The Chromium(?P<chromium_space_os> )?OS Authors\."
|
||||||
|
r"(?P<rights_reserved> All rights reserved\.)?\n"
|
||||||
|
# Line 2 - License.
|
||||||
|
r".*Use of this source code is governed by a BSD-style license that can "
|
||||||
|
r"be\n"
|
||||||
|
# Line 3 - License continuation.
|
||||||
|
r".*found in the LICENSE file\.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
NEW_LICENSE_HEADER = [
|
||||||
|
f"Copyright {datetime.now().year} The ChromiumOS Authors.",
|
||||||
|
"Use of this source code is governed by a BSD-style license that can be",
|
||||||
|
"found in the LICENSE file.",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def new_licence_header(file_suffix: str):
|
||||||
|
if file_suffix == ".py" or file_suffix == "":
|
||||||
|
prefix = "#"
|
||||||
|
else:
|
||||||
|
prefix = "//"
|
||||||
|
return "\n".join(f"{prefix} {line}" for line in NEW_LICENSE_HEADER) + "\n\n"
|
||||||
|
|
||||||
|
|
||||||
|
def check_copyright_header(context: CheckContext):
|
||||||
|
"Checks copyright header on new files only. Can 'fix' them if needed."
|
||||||
|
license_re = re.compile(LICENSE_HEADER_RE, re.MULTILINE)
|
||||||
|
for file in context.new_files:
|
||||||
|
header = file.open("r").read(256)
|
||||||
|
license_match = license_re.search(header)
|
||||||
|
if license_match:
|
||||||
|
continue
|
||||||
|
if context.fix:
|
||||||
|
contents = file.read_text()
|
||||||
|
file.write_text(new_licence_header(file.suffix) + contents)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Bad copyright header: {file}")
|
||||||
|
|
||||||
|
|
||||||
# List of all checks and on which files they should run.
|
# List of all checks and on which files they should run.
|
||||||
CHECKS: List[Check] = [
|
CHECKS: List[Check] = [
|
||||||
|
Check(
|
||||||
|
check_copyright_header,
|
||||||
|
files=["**.rs", "**.py"],
|
||||||
|
python_tools=True,
|
||||||
|
),
|
||||||
Check(
|
Check(
|
||||||
check_rust_format,
|
check_rust_format,
|
||||||
files=["**.rs"],
|
files=["**.rs"],
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
# Use of this source code is governed by a BSD-style license that can be
|
||||||
# found in the LICENSE file.
|
# found in the LICENSE file.
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
|
from pathlib import Path
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Callable, List, NamedTuple
|
from typing import Callable, List, NamedTuple
|
||||||
from pathlib import Path
|
|
||||||
from impl.common import all_tracked_files, cmd, verbose
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from impl.common import all_tracked_files, cmd, verbose
|
||||||
|
|
||||||
git = cmd("git")
|
git = cmd("git")
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ class CheckContext(object):
|
||||||
# Those files of all_files that were modified locally.
|
# Those files of all_files that were modified locally.
|
||||||
modified_files: List[Path]
|
modified_files: List[Path]
|
||||||
|
|
||||||
|
# Files that do not exist upstream and have been added locally.
|
||||||
|
new_files: List[Path]
|
||||||
|
|
||||||
|
|
||||||
class Check(NamedTuple):
|
class Check(NamedTuple):
|
||||||
"Metadata for each check, definining on which files it should run."
|
"Metadata for each check, definining on which files it should run."
|
||||||
|
@ -53,7 +56,7 @@ class Check(NamedTuple):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
def list_modified_files():
|
def list_file_diff():
|
||||||
"""
|
"""
|
||||||
Lists files there were modified compared to the upstream branch.
|
Lists files there were modified compared to the upstream branch.
|
||||||
|
|
||||||
|
@ -61,10 +64,13 @@ def list_modified_files():
|
||||||
"""
|
"""
|
||||||
upstream = git("rev-parse @{u}").stdout(check=False)
|
upstream = git("rev-parse @{u}").stdout(check=False)
|
||||||
if upstream:
|
if upstream:
|
||||||
return (Path(f) for f in git("diff --name-only", upstream).lines())
|
for line in git("diff --name-status", upstream).lines():
|
||||||
|
parts = line.split("\t", 1)
|
||||||
|
yield (parts[0].strip(), Path(parts[1].strip()))
|
||||||
else:
|
else:
|
||||||
print("WARNING: Not tracking a branch. Checking all files.")
|
print("WARNING: Not tracking a branch. Checking all files.")
|
||||||
return all_tracked_files()
|
for file in all_tracked_files():
|
||||||
|
yield ("M", file)
|
||||||
|
|
||||||
|
|
||||||
def should_run_check_on_file(check: Check, file: Path):
|
def should_run_check_on_file(check: Check, file: Path):
|
||||||
|
@ -129,10 +135,12 @@ def run_checks(
|
||||||
nightly: Use nightly version of rust tooling.
|
nightly: Use nightly version of rust tooling.
|
||||||
"""
|
"""
|
||||||
all_files = [*all_tracked_files()]
|
all_files = [*all_tracked_files()]
|
||||||
|
file_diff = [*list_file_diff()]
|
||||||
|
new_files = [f for (s, f) in file_diff if s == "A"]
|
||||||
if run_on_all_files:
|
if run_on_all_files:
|
||||||
modified_files = all_files
|
modified_files = all_files
|
||||||
else:
|
else:
|
||||||
modified_files = [*list_modified_files()]
|
modified_files = [f for (s, f) in file_diff if s in ("M", "A")]
|
||||||
|
|
||||||
success = True
|
success = True
|
||||||
for check in checks_list:
|
for check in checks_list:
|
||||||
|
@ -141,6 +149,7 @@ def run_checks(
|
||||||
nightly=nightly,
|
nightly=nightly,
|
||||||
all_files=[f for f in all_files if should_run_check_on_file(check, f)],
|
all_files=[f for f in all_files if should_run_check_on_file(check, f)],
|
||||||
modified_files=[f for f in modified_files if should_run_check_on_file(check, f)],
|
modified_files=[f for f in modified_files if should_run_check_on_file(check, f)],
|
||||||
|
new_files=[f for f in new_files if should_run_check_on_file(check, f)],
|
||||||
)
|
)
|
||||||
if context.modified_files:
|
if context.modified_files:
|
||||||
if not run_check(check, context):
|
if not run_check(check, context):
|
||||||
|
|
Loading…
Reference in a new issue