From e476f7d33f38ed8c946a51336e0a0d23f8e5056d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 12 Jul 2017 10:40:56 -0700 Subject: [PATCH] Strawman OWNERS --> CODEOWNERS script --- .github/CODEOWNERS | 22 +++ OWNERS | 6 + bazel/OWNERS | 2 + cmake/OWNERS | 2 + doc/OWNERS | 2 + etc/OWNERS | 2 + include/OWNERS | 4 + src/core/OWNERS | 4 + src/cpp/OWNERS | 4 + src/csharp/OWNERS | 3 + src/node/OWNERS | 2 + src/objective-c/OWNERS | 3 + src/php/OWNERS | 3 + src/python/OWNERS | 3 + src/ruby/OWNERS | 3 + tools/OWNERS | 4 + tools/codegen/core/OWNERS | 5 + tools/dockerfile/OWNERS | 3 + tools/mkowners/mkowners.py | 190 +++++++++++++++++++++++ tools/run_tests/OWNERS | 4 + tools/run_tests/sanity/check_owners.sh | 45 ++++++ tools/run_tests/sanity/sanity_tests.yaml | 1 + 22 files changed, 317 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 OWNERS create mode 100644 bazel/OWNERS create mode 100644 cmake/OWNERS create mode 100644 doc/OWNERS create mode 100644 etc/OWNERS create mode 100644 include/OWNERS create mode 100644 src/core/OWNERS create mode 100644 src/cpp/OWNERS create mode 100644 src/csharp/OWNERS create mode 100644 src/node/OWNERS create mode 100644 src/objective-c/OWNERS create mode 100644 src/php/OWNERS create mode 100644 src/python/OWNERS create mode 100644 src/ruby/OWNERS create mode 100644 tools/OWNERS create mode 100644 tools/codegen/core/OWNERS create mode 100644 tools/dockerfile/OWNERS create mode 100755 tools/mkowners/mkowners.py create mode 100644 tools/run_tests/OWNERS create mode 100755 tools/run_tests/sanity/check_owners.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..f5dab5aa0e2 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,22 @@ +# Auto-generated by the tools/mkowners/mkowners.py tool +# Uses OWNERS files in different modules throughout the +# repository as the source of truth for module ownership. +* @a11r @nicolasnoble @ctiller +bazel/* @nicolasnoble @a11r @ctiller +cmake/* @jtattermusch @a11r @nicolasnoble @ctiller +doc/PROTOCOL-HTTP2.md @ejona86 @a11r @nicolasnoble @ctiller +doc/interop-test-descriptions.md @ejona86 @a11r @nicolasnoble @ctiller +etc/* @jboeuf @nicolasnoble @a11r @ctiller +include/* @ctiller @markdroth @dgquintas @a11r @nicolasnoble +src/core/* @ctiller @markdroth @dgquintas @a11r @nicolasnoble +src/cpp/* @ctiller @markdroth @dgquintas @a11r @nicolasnoble +src/csharp/* @jtattermusch @apolcyn @a11r @nicolasnoble @ctiller +src/node/* @murgatroid99 @a11r @nicolasnoble @ctiller +src/objective-c/* @muxi @makdharma @a11r @nicolasnoble @ctiller +src/php/* @stanley-cheung @murgatroid99 @a11r @nicolasnoble @ctiller +src/python/* @nathanielmanistaatgoogle @kpayson64 @a11r @nicolasnoble @ctiller +src/ruby/* @apolcyn @murgatroid99 @a11r @nicolasnoble @ctiller +tools/* @matt-kwong @jtattermusch @nicolasnoble @a11r @ctiller +tools/codegen/core/* @ctiller @dgquintas @markdroth +tools/dockerfile/* @matt-kwong @jtattermusch @nicolasnoble @a11r @ctiller +tools/run_tests/* @matt-kwong @jtattermusch @nicolasnoble @a11r @ctiller diff --git a/OWNERS b/OWNERS new file mode 100644 index 00000000000..78fc2513b10 --- /dev/null +++ b/OWNERS @@ -0,0 +1,6 @@ +# Top level ownership + +@a11r +@nicolasnoble +@ctiller + diff --git a/bazel/OWNERS b/bazel/OWNERS new file mode 100644 index 00000000000..40d21e8e0d6 --- /dev/null +++ b/bazel/OWNERS @@ -0,0 +1,2 @@ +@nicolasnoble + diff --git a/cmake/OWNERS b/cmake/OWNERS new file mode 100644 index 00000000000..c0ae0533b35 --- /dev/null +++ b/cmake/OWNERS @@ -0,0 +1,2 @@ +@jtattermusch + diff --git a/doc/OWNERS b/doc/OWNERS new file mode 100644 index 00000000000..f05861799e2 --- /dev/null +++ b/doc/OWNERS @@ -0,0 +1,2 @@ +@ejona86 PROTOCOL-HTTP2.md interop-test-descriptions.md + diff --git a/etc/OWNERS b/etc/OWNERS new file mode 100644 index 00000000000..2dfd7cd61e6 --- /dev/null +++ b/etc/OWNERS @@ -0,0 +1,2 @@ +@jboeuf +@nicolasnoble diff --git a/include/OWNERS b/include/OWNERS new file mode 100644 index 00000000000..8dca75ce916 --- /dev/null +++ b/include/OWNERS @@ -0,0 +1,4 @@ +@ctiller +@markdroth +@dgquintas + diff --git a/src/core/OWNERS b/src/core/OWNERS new file mode 100644 index 00000000000..8dca75ce916 --- /dev/null +++ b/src/core/OWNERS @@ -0,0 +1,4 @@ +@ctiller +@markdroth +@dgquintas + diff --git a/src/cpp/OWNERS b/src/cpp/OWNERS new file mode 100644 index 00000000000..8dca75ce916 --- /dev/null +++ b/src/cpp/OWNERS @@ -0,0 +1,4 @@ +@ctiller +@markdroth +@dgquintas + diff --git a/src/csharp/OWNERS b/src/csharp/OWNERS new file mode 100644 index 00000000000..bde3ed985c8 --- /dev/null +++ b/src/csharp/OWNERS @@ -0,0 +1,3 @@ +@jtattermusch +@apolcyn + diff --git a/src/node/OWNERS b/src/node/OWNERS new file mode 100644 index 00000000000..3a49353d845 --- /dev/null +++ b/src/node/OWNERS @@ -0,0 +1,2 @@ +@murgatroid99 + diff --git a/src/objective-c/OWNERS b/src/objective-c/OWNERS new file mode 100644 index 00000000000..2bc91186e75 --- /dev/null +++ b/src/objective-c/OWNERS @@ -0,0 +1,3 @@ +@muxi +@makdharma + diff --git a/src/php/OWNERS b/src/php/OWNERS new file mode 100644 index 00000000000..7065b41132b --- /dev/null +++ b/src/php/OWNERS @@ -0,0 +1,3 @@ +@stanley-cheung +@murgatroid99 + diff --git a/src/python/OWNERS b/src/python/OWNERS new file mode 100644 index 00000000000..73a707c67d3 --- /dev/null +++ b/src/python/OWNERS @@ -0,0 +1,3 @@ +@nathanielmanistaatgoogle +@kpayson64 + diff --git a/src/ruby/OWNERS b/src/ruby/OWNERS new file mode 100644 index 00000000000..b01fd8061e9 --- /dev/null +++ b/src/ruby/OWNERS @@ -0,0 +1,3 @@ +@apolcyn +@murgatroid99 + diff --git a/tools/OWNERS b/tools/OWNERS new file mode 100644 index 00000000000..8f6de536742 --- /dev/null +++ b/tools/OWNERS @@ -0,0 +1,4 @@ +@matt-kwong +@jtattermusch +@nicolasnoble + diff --git a/tools/codegen/core/OWNERS b/tools/codegen/core/OWNERS new file mode 100644 index 00000000000..17e66479b6e --- /dev/null +++ b/tools/codegen/core/OWNERS @@ -0,0 +1,5 @@ +set noparent +@ctiller +@dgquintas +@markdroth + diff --git a/tools/dockerfile/OWNERS b/tools/dockerfile/OWNERS new file mode 100644 index 00000000000..20ee8085c21 --- /dev/null +++ b/tools/dockerfile/OWNERS @@ -0,0 +1,3 @@ +@matt-kwong +@jtattermusch + diff --git a/tools/mkowners/mkowners.py b/tools/mkowners/mkowners.py new file mode 100755 index 00000000000..e24b052d671 --- /dev/null +++ b/tools/mkowners/mkowners.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import argparse +import collections +import operator +import os +import re +import subprocess + +# +# Find the root of the git tree +# + +git_root = (subprocess + .check_output(['git', 'rev-parse', '--show-toplevel']) + .decode('utf-8') + .strip()) + +# +# Parse command line arguments +# + +default_out = os.path.join(git_root, '.github', 'CODEOWNERS') + +argp = argparse.ArgumentParser('Generate .github/CODEOWNERS file') +argp.add_argument('--out', '-o', + type=str, + default=default_out, + help='Output file (default %s)' % default_out) +args = argp.parse_args() + +# +# Walk git tree to locate all OWNERS files +# + +owners_files = [os.path.join(root, 'OWNERS') + for root, dirs, files in os.walk(git_root) + if 'OWNERS' in files] + +# +# Parse owners files +# + +Owners = collections.namedtuple('Owners', 'parent directives dir') +Directive = collections.namedtuple('Directive', 'who globs') + +def parse_owners(filename): + with open(filename) as f: + src = f.read().splitlines() + parent = True + directives = [] + for line in src: + line = line.strip() + # line := directive | comment + if not line: continue + if line[0] == '#': continue + # it's a directive + directive = None + if line == 'set noparent': + parent = False + elif line == '*': + directive = Directive(who='*', globs=[]) + elif ' ' in line: + (who, globs) = line.split(' ', 1) + globs_list = [glob + for glob in globs.split(' ') + if glob] + directive = Directive(who=who, globs=globs_list) + else: + directive = Directive(who=line, globs=[]) + if directive: + directives.append(directive) + return Owners(parent=parent, + directives=directives, + dir=os.path.relpath(os.path.dirname(filename), git_root)) + +owners_data = sorted([parse_owners(filename) + for filename in owners_files], + key=operator.attrgetter('dir')) + +# +# Modify owners so that parented OWNERS files point to the actual +# Owners tuple with their parent field +# + +new_owners_data = [] +for owners in owners_data: + if owners.parent == True: + best_parent = None + best_parent_score = None + for possible_parent in owners_data: + if possible_parent is owners: continue + rel = os.path.relpath(owners.dir, possible_parent.dir) + # '..' ==> we had to walk up from possible_parent to get to owners + # ==> not a parent + if '..' in rel: continue + depth = len(rel.split(os.sep)) + if not best_parent or depth < best_parent_score: + best_parent = possible_parent + best_parent_score = depth + if best_parent: + owners = owners._replace(parent = best_parent.dir) + else: + owners = owners._replace(parent = None) + new_owners_data.append(owners) +owners_data = new_owners_data + +# +# In bottom to top order, process owners data structures to build up +# a CODEOWNERS file for GitHub +# + +def glob_intersect(g1, g2): + if not g2: + return all(c == '*' for c in g1) + if not g1: + return all(c == '*' for c in g2) + c1, *t1 = g1 + c2, *t2 = g2 + if c1 == '*': + return glob_intersect(g1, t2) or glob_intersect(t1, g2) + if c2 == '*': + return glob_intersect(t1, g2) or glob_intersect(g1, t2) + return c1 == c2 and glob_intersect(t1, t2) + +def add_parent_to_globs(parent, globs): + if not parent: return + for owners in owners_data: + if owners.dir == parent: + for directive in owners.directives: + for dglob in directive.globs or ['*']: + for gglob, glob in globs.items(): + if glob_intersect(dglob, gglob): + if directive.who not in glob: + glob.append(directive.who) + add_parent_to_globs(owners.parent, globs) + return + assert(False) + +todo = owners_data.copy() +done = set() +with open(args.out, 'w') as out: + out.write('# Auto-generated by the tools/mkowners/mkowners.py tool\n') + out.write('# Uses OWNERS files in different modules throughout the\n') + out.write('# repository as the source of truth for module ownership.\n') + while todo: + head, *todo = todo + if head.parent and not head.parent in done: + todo.append(head) + continue + globs = collections.OrderedDict() + for directive in head.directives: + for glob in directive.globs or ['*']: + if glob not in globs: + globs[glob] = [] + globs[glob].append(directive.who) + add_parent_to_globs(head.parent, globs) + for glob, owners in globs.items(): + out.write('%s %s\n' % ( + os.path.join(head.dir, glob) if head.dir != '.' else glob, + ' '.join(owners))) + done.add(head.dir) diff --git a/tools/run_tests/OWNERS b/tools/run_tests/OWNERS new file mode 100644 index 00000000000..8f6de536742 --- /dev/null +++ b/tools/run_tests/OWNERS @@ -0,0 +1,4 @@ +@matt-kwong +@jtattermusch +@nicolasnoble + diff --git a/tools/run_tests/sanity/check_owners.sh b/tools/run_tests/sanity/check_owners.sh new file mode 100755 index 00000000000..365a278b71b --- /dev/null +++ b/tools/run_tests/sanity/check_owners.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +set -e + +export TEST=true + +cd `dirname $0`/../../.. + +owners=.github/CODEOWNERS +want_owners=`mktemp /tmp/submXXXXXX` + +tools/mkowners/mkowners.py -o $want_owners +diff -u $owners $want_owners + +rm $want_owners diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index 445f53e5558..65cb2fe6a73 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -1,5 +1,6 @@ # a set of tests that are run in parallel for sanity tests - script: tools/run_tests/sanity/check_cache_mk.sh +- script: tools/run_tests/sanity/check_owners.sh - script: tools/run_tests/sanity/check_sources_and_headers.py - script: tools/run_tests/sanity/check_submodules.sh - script: tools/run_tests/sanity/check_test_filtering.py