mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'feature/codeowners' into 'master'
add initial CODEOWNERS file Closes IDF-308 See merge request espressif/esp-idf!9928
This commit is contained in:
commit
390a90ff7f
107
.gitlab/CODEOWNERS
Normal file
107
.gitlab/CODEOWNERS
Normal file
@ -0,0 +1,107 @@
|
||||
* @esp-idf-codeowners/other
|
||||
|
||||
components/app_trace @esp-idf-codeowners/tools
|
||||
components/app_update @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
components/asio @esp-idf-codeowners/network
|
||||
components/bootloader*/** @esp-idf-codeowners/system @esp-idf-codeowners/security
|
||||
components/bt @esp-idf-codeowners/bluetooth
|
||||
components/cbor @esp-idf-codeowners/app-utilities
|
||||
components/coap @esp-idf-codeowners/app-utilities
|
||||
components/console @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
components/cxx @esp-idf-codeowners/system
|
||||
components/driver @esp-idf-codeowners/peripherals
|
||||
components/efuse @esp-idf-codeowners/system
|
||||
components/esp32* @esp-idf-codeowners/system
|
||||
components/esp_adc_cal @esp-idf-codeowners/peripherals
|
||||
components/esp_common @esp-idf-codeowners/system
|
||||
components/esp_eth @esp-idf-codeowners/network
|
||||
components/esp_event @esp-idf-codeowners/system
|
||||
components/esp_gdbstub @esp-idf-codeowners/tools
|
||||
components/esp_hid @esp-idf-codeowners/bluetooth
|
||||
components/esp_http_client @esp-idf-codeowners/app-utilities
|
||||
components/esp_http_server @esp-idf-codeowners/app-utilities
|
||||
components/esp_https_ota @esp-idf-codeowners/app-utilities
|
||||
components/esp_https_server @esp-idf-codeowners/app-utilities
|
||||
components/esp_ipc @esp-idf-codeowners/system
|
||||
components/esp_local_ctrl @esp-idf-codeowners/app-utilities
|
||||
components/esp_netif @esp-idf-codeowners/network
|
||||
components/esp_ringbuf @esp-idf-codeowners/system
|
||||
components/esp_rom @esp-idf-codeowners/system
|
||||
components/esp_serial_slave_link @esp-idf-codeowners/peripherals
|
||||
components/esp_system @esp-idf-codeowners/system
|
||||
components/esp_timer @esp-idf-codeowners/system
|
||||
components/esp-tls @esp-idf-codeowners/app-utilities
|
||||
components/esp_websocket_client @esp-idf-codeowners/network
|
||||
components/esp_wifi @esp-idf-codeowners/wifi
|
||||
components/espcoredump @esp-idf-codeowners/tools
|
||||
components/esptool_py @esp-idf-codeowners/tools
|
||||
components/expat @esp-idf-codeowners/app-utilities
|
||||
components/fatfs @esp-idf-codeowners/storage
|
||||
components/freemodbus @esp-idf-codeowners/peripherals
|
||||
components/freertos @esp-idf-codeowners/system
|
||||
components/heap @esp-idf-codeowners/system
|
||||
components/idf_test @esp-idf-codeowners/ci
|
||||
components/jsmn @esp-idf-codeowners/app-utilities
|
||||
components/json @esp-idf-codeowners/app-utilities
|
||||
components/libsodium @esp-idf-codeowners/security
|
||||
components/log @esp-idf-codeowners/system
|
||||
components/lwip @esp-idf-codeowners/lwip
|
||||
components/mbedtls @esp-idf-codeowners/app-utilities @esp-idf-codeowners/security
|
||||
components/mdns @esp-idf-codeowners/network
|
||||
components/mqtt @esp-idf-codeowners/network
|
||||
components/newlib @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||
components/nghttp @esp-idf-codeowners/app-utilities
|
||||
components/nvs_flash @esp-idf-codeowners/storage
|
||||
components/openssl @esp-idf-codeowners/network
|
||||
components/partition_table @esp-idf-codeowners/system
|
||||
components/perfmon @esp-idf-codeowners/tools
|
||||
components/protobuf-c @esp-idf-codeowners/app-utilities
|
||||
components/protocomm @esp-idf-codeowners/app-utilities
|
||||
components/pthread @esp-idf-codeowners/system
|
||||
components/sdmmc @esp-idf-codeowners/storage
|
||||
components/soc @esp-idf-codeowners/peripherals
|
||||
components/spi_flash @esp-idf-codeowners/peripherals
|
||||
components/spiffs @esp-idf-codeowners/storage
|
||||
components/tcp_transport @esp-idf-codeowners/network
|
||||
components/tcpip_adapter @esp-idf-codeowners/network
|
||||
components/tinyusb @esp-idf-codeowners/peripherals
|
||||
components/ulp @esp-idf-codeowners/system
|
||||
components/unity @esp-idf-codeowners/ci
|
||||
components/vfs @esp-idf-codeowners/storage
|
||||
components/wear_levelling @esp-idf-codeowners/storage
|
||||
components/wifi_provisioning @esp-idf-codeowners/app-utilities
|
||||
components/wpa_supplicant @esp-idf-codeowners/wifi
|
||||
components/xtensa @esp-idf-codeowners/system
|
||||
|
||||
docs @esp-idf-codeowners/docs
|
||||
|
||||
examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
|
||||
examples/bluetooth @esp-idf-codeowners/bluetooth
|
||||
examples/build_system @esp-idf-codeowners/build-config
|
||||
examples/common_components @esp-idf-codeowners/system
|
||||
examples/cxx @esp-idf-codeowners/system
|
||||
examples/ethernet @esp-idf-codeowners/network
|
||||
examples/get-started @esp-idf-codeowners/system
|
||||
examples/mesh @esp-idf-codeowners/wifi
|
||||
examples/peripherals @esp-idf-codeowners/peripherals
|
||||
examples/protocols @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
examples/provisioning @esp-idf-codeowners/app-utilities
|
||||
examples/security @esp-idf-codeowners/security
|
||||
examples/storage @esp-idf-codeowners/storage
|
||||
examples/system @esp-idf-codeowners/system
|
||||
examples/wifi @esp-idf-codeowners/wifi
|
||||
|
||||
make @esp-idf-codeowners/build-config
|
||||
|
||||
tools @esp-idf-codeowners/tools
|
||||
tools/*_apps.py @esp-idf-codeowners/ci
|
||||
tools/ble @esp-idf-codeowners/app-utilities
|
||||
tools/catch @esp-idf-codeowners/ci
|
||||
tools/ci @esp-idf-codeowners/ci
|
||||
tools/cmake @esp-idf-codeowners/build-config
|
||||
tools/esp_prov @esp-idf-codeowners/app-utilities
|
||||
tools/find_build_apps @esp-idf-codeowners/ci
|
||||
tools/kconfig* @esp-idf-codeowners/build-config
|
||||
tools/ldgen @esp-idf-codeowners/build-config
|
||||
tools/mass_mfg @esp-idf-codeowners/app-utilities
|
@ -202,3 +202,8 @@ clang_tidy_check_all:
|
||||
variables:
|
||||
BOT_NEEDS_TRIGGER_BY_NAME: 1
|
||||
BOT_LABEL_STATIC_ANALYSIS_ALL: 1
|
||||
|
||||
check_codeowners:
|
||||
extends: .check_job_template
|
||||
script:
|
||||
- tools/codeowners.py ci-check
|
||||
|
@ -63,6 +63,7 @@ tools/ci/test_build_system_cmake.sh
|
||||
tools/ci/test_configure_ci_environment.sh
|
||||
tools/cmake/convert_to_cmake.py
|
||||
tools/cmake/run_cmake_lint.sh
|
||||
tools/codeowners.py
|
||||
tools/docker/entrypoint.sh
|
||||
tools/docker/hooks/build
|
||||
tools/esp_app_trace/logtrace_proc.py
|
||||
|
136
tools/codeowners.py
Executable file
136
tools/codeowners.py
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Utility script for ESP-IDF developers to work with the CODEOWNERS file.
|
||||
#
|
||||
# Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
CODEOWNERS_PATH = os.path.join(os.path.dirname(__file__), "..", ".gitlab", "CODEOWNERS")
|
||||
CODEOWNER_GROUP_PREFIX = "@esp-idf-codeowners/"
|
||||
|
||||
|
||||
def action_identify(args):
|
||||
best_match = []
|
||||
with open(CODEOWNERS_PATH) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
tokens = line.split()
|
||||
path_pattern = tokens[0]
|
||||
owners = tokens[1:]
|
||||
files = files_by_pattern(path_pattern)
|
||||
if args.path in files:
|
||||
best_match = owners
|
||||
for owner in best_match:
|
||||
print(owner)
|
||||
|
||||
|
||||
def files_by_pattern(pattern=None):
|
||||
args = ["git", "ls-files"]
|
||||
if pattern:
|
||||
args.append(pattern)
|
||||
idf_root = os.path.join(os.path.dirname(__file__), "..")
|
||||
return subprocess.check_output(args, cwd=idf_root).decode("utf-8").split()
|
||||
|
||||
|
||||
def action_ci_check(args):
|
||||
errors = []
|
||||
|
||||
def add_error(msg):
|
||||
errors.append("Error at CODEOWNERS:{}: {}".format(line_no, msg))
|
||||
|
||||
files_by_owner = defaultdict(int)
|
||||
prev_path_pattern = ""
|
||||
with open(CODEOWNERS_PATH) as f:
|
||||
for line_no, line in enumerate(f, start=1):
|
||||
# Skip empty lines and comments
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
|
||||
# Each line has a form of "<path> <owners>+"
|
||||
tokens = line.split()
|
||||
path_pattern = tokens[0]
|
||||
owners = tokens[1:]
|
||||
if not owners:
|
||||
add_error("no owners specified for {}".format(path_pattern))
|
||||
|
||||
# Check that the file is sorted by path patterns
|
||||
path_pattern_for_cmp = path_pattern.replace("-", "_") # ignore difference between _ and - for ordering
|
||||
if path_pattern_for_cmp < prev_path_pattern:
|
||||
add_error("file is not sorted: {} < {}".format(path_pattern_for_cmp, prev_path_pattern))
|
||||
prev_path_pattern = path_pattern_for_cmp
|
||||
|
||||
# Check that the pattern matches at least one file
|
||||
files = files_by_pattern(path_pattern)
|
||||
if not files:
|
||||
add_error("no files matched by pattern {}".format(path_pattern))
|
||||
|
||||
# Count the number of files per owner
|
||||
for o in owners:
|
||||
# Sanity-check the owner group name
|
||||
if not o.startswith(CODEOWNER_GROUP_PREFIX):
|
||||
add_error("owner {} doesn't start with {}".format(o, CODEOWNER_GROUP_PREFIX))
|
||||
files_by_owner[o] += len(files)
|
||||
|
||||
owners_sorted = sorted([(owner, cnt) for owner, cnt in files_by_owner.items()], key=lambda p: p[0])
|
||||
print("File count per owner (not including submodules):")
|
||||
for owner, cnt in owners_sorted:
|
||||
print("{}: {} files".format(owner, cnt))
|
||||
|
||||
if not errors:
|
||||
print("No errors found.")
|
||||
else:
|
||||
print("Errors found!")
|
||||
for e in errors:
|
||||
print(e)
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
sys.argv[0], description="Internal helper script for working with the CODEOWNERS file."
|
||||
)
|
||||
subparsers = parser.add_subparsers(dest="action")
|
||||
identify = subparsers.add_parser(
|
||||
"identify",
|
||||
help="Lists the owners of the specified path within IDF."
|
||||
"This command doesn't support files inside submodules, or files not added to git repository.",
|
||||
)
|
||||
identify.add_argument("path", help="Path of the file relative to the root of the repository")
|
||||
subparsers.add_parser(
|
||||
"ci-check",
|
||||
help="Check CODEOWNERS file: every line should match at least one file, sanity-check group names, "
|
||||
"check that the file is sorted by paths",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.action is None:
|
||||
parser.print_help()
|
||||
parser.exit(1)
|
||||
|
||||
action_func_name = "action_" + args.action.replace("-", "_")
|
||||
action_func = globals()[action_func_name]
|
||||
action_func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
x
Reference in New Issue
Block a user