update-go-mod/internal/cli/action_overlook.go

143 lines
2.9 KiB
Go
Raw Normal View History

2023-08-15 10:59:16 +00:00
package cli
import (
2023-08-15 12:18:48 +00:00
"context"
2023-08-15 10:59:16 +00:00
"fmt"
2023-08-15 11:26:34 +00:00
"os"
2023-08-15 10:59:16 +00:00
"regexp"
2023-08-15 11:26:34 +00:00
"sort"
2023-08-15 12:18:48 +00:00
"sync"
2023-08-15 11:26:34 +00:00
"text/tabwriter"
"time"
2023-08-15 10:59:16 +00:00
2024-03-01 07:18:54 +00:00
"github.com/google/go-github/v60/github"
2023-08-15 12:18:48 +00:00
"github.com/sourcegraph/conc/pool"
2023-08-15 17:54:05 +00:00
"github.com/spf13/cast"
2023-08-15 10:59:16 +00:00
"github.com/urfave/cli/v2"
)
2023-08-15 12:18:48 +00:00
const maxPoolGoroutine = 8
2023-08-15 10:59:16 +00:00
var reGitHub = regexp.MustCompile(`github\.com/([^/]*)/([^/]*)`)
2023-08-15 11:26:34 +00:00
type GitHubRepoData struct {
LastCommitAt time.Time
Name string
StarCount int
2023-08-15 11:26:34 +00:00
}
2023-08-15 10:59:16 +00:00
func (a *action) Overlook(c *cli.Context) error {
2023-08-15 12:00:22 +00:00
// Optional
if a.ghClient == nil {
return nil
}
2023-08-15 10:59:16 +00:00
a.getFlags(c)
mapImportedModules, err := a.runGetImportedModules(c)
if err != nil {
return err
}
2023-08-15 11:26:34 +00:00
if len(mapImportedModules) == 0 {
return nil
}
listGHRepoData := make([]GitHubRepoData, 0, len(mapImportedModules))
// To avoid duplicate
mGHRepoData := make(map[string]struct{})
2023-08-15 12:18:48 +00:00
p := pool.New().WithMaxGoroutines(maxPoolGoroutine)
var mMutex sync.Mutex
2023-08-15 12:18:48 +00:00
var listMutex sync.Mutex
2023-08-15 10:59:16 +00:00
for module := range mapImportedModules {
2023-08-15 12:18:48 +00:00
module := module
p.Go(func() {
ctx := context.Background()
2023-08-15 12:18:48 +00:00
if !reGitHub.MatchString(module) {
return
}
parts := reGitHub.FindStringSubmatch(module)
if len(parts) != 3 {
return
}
name := parts[0]
mMutex.Lock()
if _, ok := mGHRepoData[name]; ok {
mMutex.Unlock()
2023-08-15 12:18:48 +00:00
return
}
mGHRepoData[name] = struct{}{}
2023-08-15 12:18:48 +00:00
mMutex.Unlock()
owner := parts[1]
repo := parts[2]
ghRepo, _, err := a.ghClient.Repositories.Get(ctx, owner, repo)
2023-08-15 12:18:48 +00:00
if err != nil {
a.log("GitHub failed to get repo %s/%s: %s\n", owner, repo, err)
2023-08-15 12:18:48 +00:00
}
var starCount int
2023-08-15 12:18:48 +00:00
if ghRepo.StargazersCount != nil {
starCount = *ghRepo.StargazersCount
}
ghCommits, _, err := a.ghClient.Repositories.ListCommits(ctx, owner, repo, &github.CommitsListOptions{
ListOptions: github.ListOptions{
Page: 1,
PerPage: 1,
},
})
if err != nil {
a.log("GitHub failed to get commits %s/%s: %s\n", owner, repo, err)
2023-08-15 12:18:48 +00:00
}
var lastCommitAt time.Time
if len(ghCommits) != 0 {
if ghCommits[0].Commit != nil &&
ghCommits[0].Commit.Author != nil &&
ghCommits[0].Commit.Author.Date != nil {
lastCommitAt = ghCommits[0].Commit.Author.Date.Time
}
2023-08-15 12:18:48 +00:00
}
listMutex.Lock()
listGHRepoData = append(listGHRepoData, GitHubRepoData{
LastCommitAt: lastCommitAt,
Name: name,
StarCount: starCount,
2023-08-15 12:18:48 +00:00
})
listMutex.Unlock()
2023-08-15 11:26:34 +00:00
})
}
2023-08-15 12:18:48 +00:00
p.Wait()
2023-08-15 11:26:34 +00:00
// Sort for consistency
sort.Slice(listGHRepoData, func(i, j int) bool {
return listGHRepoData[i].Name < listGHRepoData[j].Name
})
// Print
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
for _, r := range listGHRepoData {
2023-08-15 17:54:05 +00:00
fmt.Fprintf(w, "Module %s\t%s\t⭐\tLast commit %s\n", r.Name, roundK(r.StarCount), r.LastCommitAt.Format(time.DateOnly))
2023-08-15 10:59:16 +00:00
}
2023-08-15 11:26:34 +00:00
w.Flush()
2023-08-15 10:59:16 +00:00
return nil
}
2023-08-15 17:54:05 +00:00
// Nearest thounsand
// 1234 -> 1K
func roundK(v int) string {
if v < 1000 {
return cast.ToString(v)
}
return fmt.Sprintf("%dK", v/1000)
}