Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2025-05-20 15:28:32 +02:00
parent 7f74f5d28f
commit 5a9483411a
14 changed files with 845 additions and 216 deletions
+60 -39
View File
@@ -6,66 +6,87 @@ import (
"github.com/google/go-github/v72/github"
)
func (r Recon) Commits(username string) {
PrintTitle("🐙 Commits")
type CommitsResult struct {
Name string
Email string
Occurences int
FirstFoundIn string
}
seenNames := make(map[string]struct{})
seenEmails := make(map[string]struct{})
var names, emails []string
func (r Recon) Commits(username string) (response []CommitsResult) {
r.PrintTitle("🐙 Commits")
collect := func(order string) error {
opts := &github.SearchOptions{
Sort: "author-date",
Order: order,
ListOptions: github.ListOptions{PerPage: 100},
}
results := make(map[string]CommitsResult)
collect := func(date string) error {
for page := 1; page <= 10; page++ {
opts.ListOptions.Page = page
result, resp, err := r.client.Search.Commits(
r.ctx,
fmt.Sprintf("author:%s", username),
opts,
fmt.Sprintf("author:%s author-date:%s", username, date),
&github.SearchOptions{
Sort: "author-date",
Order: "desc",
ListOptions: github.ListOptions{PerPage: 100, Page: page},
},
)
if err != nil {
return fmt.Errorf("fetch page %d (%s): %w", page, order, err)
return fmt.Errorf("fetch page %d (%s): %w", page, date, err)
}
WaitForRateLimit(resp)
if len(result.Commits) == 0 {
break
}
for _, item := range result.Commits {
a := item.Commit.GetAuthor()
name := a.GetName()
email := a.GetEmail()
if _, seen := seenNames[name]; !seen {
seenNames[name] = struct{}{}
names = append(names, name)
PrintInfo(
"Name "+fmt.Sprint(len(names)),
name,
"from "+item.GetRepository().Owner.GetLogin()+"/"+item.GetRepository().
GetName(),
)
name := item.Commit.GetAuthor().GetName()
email := item.Commit.GetAuthor().GetEmail()
if SkipResult(name, email) {
// continue
}
if _, seen := seenEmails[email]; !seen {
seenEmails[email] = struct{}{}
emails = append(emails, email)
PrintInfo(
"Email "+fmt.Sprint(len(emails)),
email,
"from "+item.GetRepository().Owner.GetLogin()+"/"+item.GetRepository().
if _, seen := results[name+" - "+email]; !seen {
author := CommitsResult{
Name: name,
Email: email,
Occurences: 1,
FirstFoundIn: item.GetRepository().Owner.GetLogin() + "/" + item.GetRepository().
GetName(),
)
}
results[name+" - "+email] = author
} else {
result := results[name+" - "+email]
result.Occurences++
results[name+" - "+email] = result
}
}
}
return nil
}
if err := collect("desc"); err != nil {
r.logger.Error("Failed to fetch commits", "err", err, "order", "desc")
// Range of dates to bypass the limit of 1000 results
for _, date := range []string{
"<2023-01-01", "2023-01-01..2023-12-31",
"2024-01-01..2024-05-31",
"2024-06-01..2024-12-31",
"2025-01-01..2025-05-31",
"2025-06-01..2025-12-31",
">2026-01-01",
} {
if err := collect(date); err != nil {
r.logger.Error("Failed to fetch commits", "err", err, "date", date)
}
}
if err := collect("asc"); err != nil {
r.logger.Error("Failed to fetch commits", "err", err, "order", "asc")
for _, result := range results {
r.PrintInfo(
"Author",
result.Name+" - "+result.Email,
"first from "+result.FirstFoundIn+" (x"+fmt.Sprint(result.Occurences)+")",
)
response = append(response, result)
}
if len(results) == 0 {
r.PrintInfo("INFO", "No commits found")
}
r.PrintNewline()
return
}