| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 | package herculesimport (	"bufio"	"os"	"strings"	"gopkg.in/src-d/go-git.v4"	"gopkg.in/src-d/go-git.v4/plumbing/object")type IdentityDetector struct {	// Maps email || name  -> developer id.	PeopleDict map[string]int	// Maps developer id -> description	ReversePeopleDict []string}const MISSING_AUTHOR = (1 << 18) - 1const SELF_AUTHOR = (1 << 18) - 2func (id *IdentityDetector) Name() string {	return "IdentityDetector"}func (id *IdentityDetector) Provides() []string {	arr := [...]string{"author"}	return arr[:]}func (id *IdentityDetector) Requires() []string {	return []string{}}func (id *IdentityDetector) Initialize(repository *git.Repository) {}func (self *IdentityDetector) Consume(deps map[string]interface{}) (map[string]interface{}, error) {	commit := deps["commit"].(*object.Commit)	signature := commit.Author	id, exists := self.PeopleDict[strings.ToLower(signature.Email)]	if !exists {		id, exists = self.PeopleDict[strings.ToLower(signature.Name)]		if !exists {			id = MISSING_AUTHOR		}	}	return map[string]interface{}{"author": id}, nil}func (id *IdentityDetector) Finalize() interface{} {	return nil}func (id *IdentityDetector) LoadPeopleDict(path string) error {	file, err := os.Open(path)	if err != nil {		return err	}	defer file.Close()	scanner := bufio.NewScanner(file)	dict := make(map[string]int)	reverse_dict := []string{}	size := 0	for scanner.Scan() {		ids := strings.Split(strings.ToLower(scanner.Text()), "|")		for _, id := range ids {			dict[id] = size		}		reverse_dict = append(reverse_dict, ids[0])		size += 1	}	reverse_dict = append(reverse_dict, "<unmatched>")	id.PeopleDict = dict	id.ReversePeopleDict = reverse_dict	return nil}func (id *IdentityDetector) GeneratePeopleDict(commits []*object.Commit) {	dict := make(map[string]int)	emails := make(map[int][]string)	names := make(map[int][]string)	size := 0	for _, commit := range commits {		email := strings.ToLower(commit.Author.Email)		name := strings.ToLower(commit.Author.Name)		id, exists := dict[email]		if exists {			_, exists := dict[name]			if !exists {				dict[name] = id				names[id] = append(names[id], name)			}			continue		}		id, exists = dict[name]		if exists {			dict[email] = id			emails[id] = append(emails[id], email)			continue		}		dict[email] = size		dict[name] = size		emails[size] = append(emails[size], email)		names[size] = append(names[size], name)		size += 1	}	reverse_dict := make([]string, size)	for _, val := range dict {		reverse_dict[val] = strings.Join(names[val], "|") + "|" + strings.Join(emails[val], "|")	}	id.PeopleDict = dict	id.ReversePeopleDict = reverse_dict}
 |