util/: Replace GPLv2 boiler plate with SPDX header
Used commands:
perl -i -p0e 's|\/\*[\s*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-only */|' $(cat filelist)
perl -i -p0e 's|This[\s*]*program[\s*]*is[\s*]*free[\s*]*software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*either[\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License,[\s*]*or[\s*]*.at[\s*]*your[\s*]*option.*[\s*]*any[\s*]*later[\s*]*version.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-or-later */|' $(cat filelist)
perl -i -p0e 's|\/\*[\s*]*.*This[\s*#]*program[\s*#]*is[\s*#]*free[\s*#]*software[;:,][\s*#]*you[\s*#]*can[\s*#]*redistribute[\s*#]*it[\s*#]*and/or[\s*#]*modify[\s*#]*it[\s*#]*under[\s*#]*the[\s*#]*terms[\s*#]*of[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*as[\s*#]*published[\s*#]*by[\s*#]*the[\s*#]*Free[\s*#]*Software[\s*#]*Foundation[;:,][\s*#]*either[\s*#]*version[\s*#]*3[\s*#]*of[\s*#]*the[\s*#]*License[;:,][\s*#]*or[\s*#]*.at[\s*#]*your[\s*#]*option.*[\s*#]*any[\s*#]*later[\s*#]*version.[\s*#]*This[\s*#]*program[\s*#]*is[\s*#]*distributed[\s*#]*in[\s*#]*the[\s*#]*hope[\s*#]*that[\s*#]*it[\s*#]*will[\s*#]*be[\s*#]*useful[;:,][\s*#]*but[\s*#]*WITHOUT[\s*#]*ANY[\s*#]*WARRANTY[;:,][\s*#]*without[\s*#]*even[\s*#]*the[\s*#]*implied[\s*#]*warranty[\s*#]*of[\s*#]*MERCHANTABILITY[\s*#]*or[\s*#]*FITNESS[\s*#]*FOR[\s*#]*A[\s*#]*PARTICULAR[\s*#]*PURPOSE.[\s*#]*See[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*for[\s*#]*more[\s*#]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-3.0-or-later */|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w]*.*is free software[:;][\#\s]*you[\#\s]*can[\#\s]*redistribute[\#\s]*it[\#\s]*and\/or[\#\s]*modify[\#\s]*it[\s\#]*under[\s \#]*the[\s\#]*terms[\s\#]*of[\s\#]*the[\s\#]*GNU[\s\#]*General[\s\#]*Public[\s\#]*License[\s\#]*as[\s\#]*published[\s\#]*by[\s\#]*the[\s\#]*Free[\s\#]*Software[\s\#]*Foundation[;,][\s\#]*version[\s\#]*2[\s\#]*of[\s\#]*the[\s\#]*License.*[\s\#]*This[\s\#]*program[\s\#]*is[\s\#]*distributed[\s\#]*in[\s\#]*the[\s\#]*hope[\s\#]*that[\s\#]*it[\s\#]*will[\#\s]*be[\#\s]*useful,[\#\s]*but[\#\s]*WITHOUT[\#\s]*ANY[\#\s]*WARRANTY;[\#\s]*without[\#\s]*even[\#\s]*the[\#\s]*implied[\#\s]*warranty[\#\s]*of[\#\s]*MERCHANTABILITY[\#\s]*or[\#\s]*FITNESS[\#\s]*FOR[\#\s]*A[\#\s]*PARTICULAR[\#\s]*PURPOSE.[\#\s]*See[\#\s]*the[\#\s]*GNU[\#\s]*General[\#\s]*Public[\#\s]*License[\#\s]*for[\#\s]*more[\#\s]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
Change-Id: I1008a63b804f355a916221ac994701d7584f60ff
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Signed-off-by: Elyes HAOUAS <ehaouas@noos.fr>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41177
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-05-08 20:48:04 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2015-10-21 22:12:51 +02:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2018-11-12 18:48:40 +01:00
|
|
|
"flag"
|
2015-10-21 22:12:51 +02:00
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2018-11-12 17:31:48 +01:00
|
|
|
"regexp"
|
2018-11-12 17:52:24 +01:00
|
|
|
"strings"
|
2015-10-21 22:12:51 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type subsystem struct {
|
|
|
|
name string
|
|
|
|
maintainer []string
|
2018-11-12 17:31:48 +01:00
|
|
|
paths []string
|
|
|
|
globs []*regexp.Regexp
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var subsystems []subsystem
|
|
|
|
|
|
|
|
func get_git_files() ([]string, error) {
|
|
|
|
var files []string
|
|
|
|
|
|
|
|
/* Read in list of all files in the git repository */
|
|
|
|
cmd := exec.Command("git", "ls-files")
|
|
|
|
out, err := cmd.StdoutPipe()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("git ls-files failed: %v", err)
|
|
|
|
return files, err
|
|
|
|
}
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
|
|
log.Fatalf("Could not start %v: %v", cmd, err)
|
|
|
|
return files, err
|
|
|
|
}
|
|
|
|
|
|
|
|
r := bufio.NewScanner(out)
|
|
|
|
for r.Scan() {
|
|
|
|
/* Cut out leading tab */
|
|
|
|
files = append(files, r.Text())
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd.Wait()
|
|
|
|
|
|
|
|
return files, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func get_maintainers() ([]string, error) {
|
|
|
|
var maintainers []string
|
|
|
|
|
|
|
|
/* Read in all maintainers */
|
|
|
|
file, err := os.Open("MAINTAINERS")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Can't open MAINTAINERS file: %v", err)
|
|
|
|
log.Fatalf("Are you running from the top-level directory?")
|
|
|
|
return maintainers, err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
keep := false
|
|
|
|
s := bufio.NewScanner(file)
|
|
|
|
for s.Scan() {
|
|
|
|
/* Are we in the "data" section and have a non-empty line? */
|
|
|
|
if keep && s.Text() != "" {
|
|
|
|
maintainers = append(maintainers, s.Text())
|
|
|
|
}
|
|
|
|
/* Skip everything before the delimiter */
|
|
|
|
if s.Text() == "\t\t-----------------------------------" {
|
|
|
|
keep = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return maintainers, nil
|
|
|
|
}
|
|
|
|
|
2018-11-12 17:31:48 +01:00
|
|
|
func path_to_regexstr(path string) string {
|
maintainers.go: Work around common mistake in MAINTAINERS
Gerrit is able to add reviewers based on entries in the `MAINTAINERS`
file. For inclusion and exclusion matches either paths or regular
expressions can be used. The syntax is described in the header of the
file.
When matching a path, there are two sensible possibilities:
- `path/to/file` matches a file.
- `path/to/dir/` matches a folder including its contents recursively.
- `path/to/dir/*` matches all files in that folder, without recursing
into its subfolders.
The trailing slash in the second example is essential. Without it, only
the directory entry itself matches when, for example, the folder gets
deleted, renamed or its permissions get modified. Reviewers in the list
won't get added to changes of any files or directories below that path.
However, from time to time entries get added without this trailing
slash. Thus, implement a workaround in `maintainers.go` to check, if a
path entry is actually a directory. In such case a trailing slash gets
appended, so that the contents will match, too.
Example: `path/to/dir` will become `path/to/dir/`
Tests:
1. output before and after does not differ
2. manual test of resulting regex when running `maintainers.go`
Change-Id: Ic712aacb0c5c50380fa9beeccf5161501f1cd8ea
Signed-off-by: Michael Niewöhner <foss@mniewoehner.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/52276
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2021-04-13 00:44:21 +02:00
|
|
|
/* Add missing trailing slash if path is a directory */
|
|
|
|
if path[len(path)-1] != '/' {
|
|
|
|
fileInfo, err := os.Stat(path)
|
|
|
|
if err == nil && fileInfo.IsDir() {
|
|
|
|
path += "/"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-13 00:17:39 +02:00
|
|
|
regexstr := glob_to_regex(path)
|
|
|
|
|
|
|
|
/* Handle path with trailing '/' as prefix */
|
|
|
|
if regexstr[len(regexstr)-2:] == "/$" {
|
|
|
|
regexstr = regexstr[:len(regexstr)-1] + ".*$"
|
2018-11-12 17:31:48 +01:00
|
|
|
}
|
2021-04-13 00:17:39 +02:00
|
|
|
|
|
|
|
return regexstr;
|
2018-11-12 17:31:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func path_to_regex(path string) *regexp.Regexp {
|
|
|
|
regexstr := path_to_regexstr(path)
|
|
|
|
return regexp.MustCompile(regexstr)
|
|
|
|
}
|
|
|
|
|
2015-10-21 22:12:51 +02:00
|
|
|
func build_maintainers(maintainers []string) {
|
|
|
|
var current *subsystem
|
|
|
|
for _, line := range maintainers {
|
|
|
|
if line[1] != ':' {
|
|
|
|
/* Create new subsystem entry */
|
|
|
|
var tmp subsystem
|
|
|
|
subsystems = append(subsystems, tmp)
|
|
|
|
current = &subsystems[len(subsystems)-1]
|
|
|
|
current.name = line
|
|
|
|
} else {
|
|
|
|
switch line[0] {
|
2018-11-12 17:09:40 +01:00
|
|
|
case 'R', 'M':
|
|
|
|
/* Add subsystem maintainer */
|
|
|
|
current.maintainer = append(current.maintainer, line[3:len(line)])
|
2015-10-21 22:12:51 +02:00
|
|
|
case 'F':
|
2018-11-12 17:09:40 +01:00
|
|
|
// add files
|
2018-11-12 17:31:48 +01:00
|
|
|
current.paths = append(current.paths, line[3:len(line)])
|
|
|
|
current.globs = append(current.globs, path_to_regex(line[3:len(line)]))
|
|
|
|
break
|
2018-11-12 17:09:40 +01:00
|
|
|
case 'L', 'S', 'T', 'W': // ignore
|
2015-10-21 22:12:51 +02:00
|
|
|
default:
|
2018-11-12 17:09:40 +01:00
|
|
|
fmt.Println("No such specifier: ", line)
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func print_maintainers() {
|
|
|
|
for _, subsystem := range subsystems {
|
|
|
|
fmt.Println(subsystem.name)
|
|
|
|
fmt.Println(" ", subsystem.maintainer)
|
2018-11-12 17:31:48 +01:00
|
|
|
fmt.Println(" ", subsystem.paths)
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-12 17:31:48 +01:00
|
|
|
func match_file(fname string, component subsystem) bool {
|
|
|
|
for _, glob := range component.globs {
|
|
|
|
if glob.Match([]byte(fname)) {
|
|
|
|
return true
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-12 17:31:48 +01:00
|
|
|
return false
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func find_maintainer(fname string) {
|
2018-11-12 17:29:49 +01:00
|
|
|
var success bool
|
|
|
|
|
2015-10-21 22:12:51 +02:00
|
|
|
for _, subsystem := range subsystems {
|
2018-11-12 17:31:48 +01:00
|
|
|
matched := match_file(fname, subsystem)
|
2018-11-16 12:41:19 +01:00
|
|
|
if matched {
|
2018-11-12 17:29:49 +01:00
|
|
|
success = true
|
2015-10-21 22:12:51 +02:00
|
|
|
fmt.Println(fname, "is in subsystem",
|
|
|
|
subsystem.name)
|
2018-11-12 17:52:24 +01:00
|
|
|
fmt.Println("Maintainers: ", strings.Join(subsystem.maintainer, ", "))
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-12 17:29:49 +01:00
|
|
|
if !success {
|
|
|
|
fmt.Println(fname, "has no subsystem defined in MAINTAINERS")
|
|
|
|
}
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func find_unmaintained(fname string) {
|
2018-11-12 17:29:49 +01:00
|
|
|
var success bool
|
|
|
|
|
2015-10-21 22:12:51 +02:00
|
|
|
for _, subsystem := range subsystems {
|
2018-11-12 17:31:48 +01:00
|
|
|
matched := match_file(fname, subsystem)
|
2018-11-16 12:41:19 +01:00
|
|
|
if matched {
|
2018-11-12 17:29:49 +01:00
|
|
|
success = true
|
2015-10-21 22:12:51 +02:00
|
|
|
fmt.Println(fname, "is in subsystem",
|
|
|
|
subsystem.name)
|
|
|
|
}
|
|
|
|
}
|
2018-11-12 17:29:49 +01:00
|
|
|
if !success {
|
|
|
|
fmt.Println(fname, "has no subsystem defined in MAINTAINERS")
|
|
|
|
}
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
2018-11-12 17:31:48 +01:00
|
|
|
// taken from https://github.com/zyedidia/glob/blob/master/glob.go which is
|
|
|
|
// Copyright (c) 2016: Zachary Yedidia.
|
|
|
|
// and was published under the MIT "Expat" license.
|
|
|
|
//
|
|
|
|
// only change: return the string, instead of a compiled golang regex
|
|
|
|
func glob_to_regex(glob string) string {
|
|
|
|
regex := ""
|
|
|
|
inGroup := 0
|
|
|
|
inClass := 0
|
|
|
|
firstIndexInClass := -1
|
|
|
|
arr := []byte(glob)
|
|
|
|
|
|
|
|
for i := 0; i < len(arr); i++ {
|
|
|
|
ch := arr[i]
|
|
|
|
|
|
|
|
switch ch {
|
|
|
|
case '\\':
|
|
|
|
i++
|
|
|
|
if i >= len(arr) {
|
|
|
|
regex += "\\"
|
|
|
|
} else {
|
|
|
|
next := arr[i]
|
|
|
|
switch next {
|
|
|
|
case ',':
|
|
|
|
// Nothing
|
|
|
|
case 'Q', 'E':
|
|
|
|
regex += "\\\\"
|
|
|
|
default:
|
|
|
|
regex += "\\"
|
|
|
|
}
|
|
|
|
regex += string(next)
|
|
|
|
}
|
|
|
|
case '*':
|
|
|
|
if inClass == 0 {
|
2021-04-13 00:17:39 +02:00
|
|
|
regex += "[^/]*"
|
2018-11-12 17:31:48 +01:00
|
|
|
} else {
|
|
|
|
regex += "*"
|
|
|
|
}
|
|
|
|
case '?':
|
|
|
|
if inClass == 0 {
|
|
|
|
regex += "."
|
|
|
|
} else {
|
|
|
|
regex += "?"
|
|
|
|
}
|
|
|
|
case '[':
|
|
|
|
inClass++
|
|
|
|
firstIndexInClass = i + 1
|
|
|
|
regex += "["
|
|
|
|
case ']':
|
|
|
|
inClass--
|
|
|
|
regex += "]"
|
|
|
|
case '.', '(', ')', '+', '|', '^', '$', '@', '%':
|
|
|
|
if inClass == 0 || (firstIndexInClass == i && ch == '^') {
|
|
|
|
regex += "\\"
|
|
|
|
}
|
|
|
|
regex += string(ch)
|
|
|
|
case '!':
|
|
|
|
if firstIndexInClass == i {
|
|
|
|
regex += "^"
|
|
|
|
} else {
|
|
|
|
regex += "!"
|
|
|
|
}
|
|
|
|
case '{':
|
|
|
|
inGroup++
|
|
|
|
regex += "("
|
|
|
|
case '}':
|
|
|
|
inGroup--
|
|
|
|
regex += ")"
|
|
|
|
case ',':
|
|
|
|
if inGroup > 0 {
|
|
|
|
regex += "|"
|
|
|
|
} else {
|
|
|
|
regex += ","
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
regex += string(ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "^" + regex + "$"
|
|
|
|
}
|
|
|
|
|
2018-11-12 18:49:09 +01:00
|
|
|
var is_email *regexp.Regexp
|
|
|
|
|
|
|
|
func extract_maintainer(maintainer string) string {
|
|
|
|
if is_email == nil {
|
|
|
|
is_email = regexp.MustCompile("<[^>]*>")
|
|
|
|
}
|
|
|
|
|
|
|
|
if match := is_email.FindStringSubmatch(maintainer); match != nil {
|
|
|
|
return match[0][1 : len(match[0])-1]
|
|
|
|
}
|
|
|
|
return maintainer
|
|
|
|
}
|
|
|
|
|
|
|
|
func do_print_gerrit_rules() {
|
|
|
|
for _, subsystem := range subsystems {
|
|
|
|
if len(subsystem.paths) == 0 || len(subsystem.maintainer) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
fmt.Println("#", subsystem.name)
|
|
|
|
for _, path := range subsystem.paths {
|
2018-11-21 22:07:38 +01:00
|
|
|
fmt.Println("[filter \"file:\\\"" + path_to_regexstr(path) + "\\\"\"]")
|
2018-11-12 18:49:09 +01:00
|
|
|
for _, maint := range subsystem.maintainer {
|
|
|
|
fmt.Println(" reviewer =", extract_maintainer(maint))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-21 22:12:51 +02:00
|
|
|
func main() {
|
2018-11-12 18:48:40 +01:00
|
|
|
var (
|
2018-11-12 18:49:09 +01:00
|
|
|
files []string
|
|
|
|
err error
|
|
|
|
print_gerrit_rules = flag.Bool("print-gerrit-rules", false, "emit the MAINTAINERS rules in a format suitable for Gerrit's reviewers plugin")
|
|
|
|
debug = flag.Bool("debug", false, "emit additional debug output")
|
2018-11-12 18:48:40 +01:00
|
|
|
)
|
|
|
|
flag.Parse()
|
2015-10-21 22:12:51 +02:00
|
|
|
|
2018-11-12 18:48:40 +01:00
|
|
|
/* get and build subsystem database */
|
2015-10-21 22:12:51 +02:00
|
|
|
maintainers, err := get_maintainers()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Oops.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
build_maintainers(maintainers)
|
|
|
|
|
2018-11-12 18:48:40 +01:00
|
|
|
if *debug {
|
2015-10-21 22:12:51 +02:00
|
|
|
print_maintainers()
|
|
|
|
}
|
|
|
|
|
2018-11-12 18:49:09 +01:00
|
|
|
if *print_gerrit_rules {
|
|
|
|
do_print_gerrit_rules()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-12 18:48:40 +01:00
|
|
|
args := flag.Args()
|
|
|
|
if len(args) == 0 {
|
|
|
|
/* get the filenames */
|
|
|
|
files, err = get_git_files()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Oops.")
|
|
|
|
return
|
|
|
|
}
|
2015-10-21 22:12:51 +02:00
|
|
|
for _, file := range files {
|
2018-11-12 18:48:40 +01:00
|
|
|
find_unmaintained(file)
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
} else {
|
2018-11-12 18:48:40 +01:00
|
|
|
files = args
|
|
|
|
|
|
|
|
/* Find maintainers for each file */
|
2015-10-21 22:12:51 +02:00
|
|
|
for _, file := range files {
|
2018-11-12 18:48:40 +01:00
|
|
|
find_maintainer(file)
|
2015-10-21 22:12:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|