Files
trufflehog/pkg/log/codeowners.go
Miccah Castorina 31402a3a96 Implement CodeOwnersLeveler
CodeOwnersLeveler is a log leveler that can be dynamically controlled by
the owners found in CODEOWNERS. Levels can be independently set for each
owner, and logs will be checked based on the owner of the function that
emitted them.
2026-02-06 19:07:48 -08:00

82 lines
1.6 KiB
Go

package log
import (
"strings"
"unicode"
"github.com/hmarr/codeowners"
)
type CodeOwners struct {
rules codeowners.Ruleset
}
func ParseCodeOwners(content string) (*CodeOwners, error) {
rules, err := codeowners.ParseFile(strings.NewReader(content))
if err != nil {
return nil, err
}
return &CodeOwners{rules}, nil
}
func (co *CodeOwners) OwnersOf(path string) ([]string, error) {
path = goPathToFilePath(path)
rule, err := co.rules.Match(path)
if err != nil {
return nil, err
}
if rule == nil {
return nil, nil
}
owners := make([]string, len(rule.Owners))
for i, owner := range rule.Owners {
owners[i] = owner.String()
}
return owners, nil
}
func (co *CodeOwners) Owners() []string {
ownerSet := make(map[string]struct{})
for _, rule := range co.rules {
for _, owner := range rule.Owners {
ownerSet[owner.String()] = struct{}{}
}
}
owners := make([]string, 0, len(ownerSet))
for owner := range ownerSet {
owners = append(owners, owner)
}
return owners
}
func goPathToFilePath(path string) string {
// Expected formats:
// - host/repo_owner/repo_name/path/to/package.func
// - host/repo_owner/repo_name/repo_version/path/to/package.func
parts := strings.Split(path, "/")
if len(parts) < 3 {
return path
}
parts = parts[3:]
if len(parts) > 1 && isVersionString(parts[0]) {
parts = parts[1:]
}
return strings.Join(parts, "/")
}
func isVersionString(s string) bool {
if len(s) <= 1 {
return false
}
if s[0] != 'v' {
return false
}
for _, r := range s[1:] {
if !unicode.IsDigit(r) {
return false
}
}
return true
}