mirror of
https://github.com/tiennm99/awesome-coding-agents.git
synced 2026-05-27 05:59:47 +00:00
237d7acd6a
Go updater that fetches AI agent coding tool repo stats via GitHub GraphQL (batched, one query), sorts by star count, appends a daily snapshot to data/history.jsonl, and regenerates README.md from templates/readme.tmpl. Daily workflow at .github/workflows/update.yml refreshes rankings and commits changes. Seed list in data/agents.yml covers 19 tracked repos.
106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
type Snapshot struct {
|
|
Date string `json:"date"`
|
|
Stars map[string]int `json:"stars"`
|
|
}
|
|
|
|
func appendHistory(path string, stats []Stat) (map[string]int, error) {
|
|
today := time.Now().UTC().Format("2006-01-02")
|
|
current := Snapshot{Date: today, Stars: map[string]int{}}
|
|
for _, s := range stats {
|
|
current.Stars[s.NameWithOwner] = s.Stars
|
|
}
|
|
|
|
snapshots, err := readSnapshots(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deltas := computeDeltas(snapshots, current)
|
|
|
|
// drop any pre-existing snapshot for today, then append current
|
|
kept := snapshots[:0]
|
|
for _, s := range snapshots {
|
|
if s.Date != today {
|
|
kept = append(kept, s)
|
|
}
|
|
}
|
|
kept = append(kept, current)
|
|
|
|
return deltas, writeSnapshots(path, kept)
|
|
}
|
|
|
|
func readSnapshots(path string) ([]Snapshot, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
var out []Snapshot
|
|
scanner := bufio.NewScanner(f)
|
|
scanner.Buffer(make([]byte, 1024*1024), 16*1024*1024)
|
|
for scanner.Scan() {
|
|
line := scanner.Bytes()
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
var s Snapshot
|
|
if err := json.Unmarshal(line, &s); err != nil {
|
|
// skip malformed lines rather than fail the whole run
|
|
continue
|
|
}
|
|
out = append(out, s)
|
|
}
|
|
return out, scanner.Err()
|
|
}
|
|
|
|
func writeSnapshots(path string, snapshots []Snapshot) error {
|
|
f, err := os.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
enc := json.NewEncoder(f)
|
|
for _, s := range snapshots {
|
|
if err := enc.Encode(s); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// computeDeltas returns stars-now minus stars-at-or-before-cutoff for each repo.
|
|
// Cutoff = 7 days ago UTC. If no snapshot is old enough, delta is omitted.
|
|
func computeDeltas(history []Snapshot, current Snapshot) map[string]int {
|
|
deltas := map[string]int{}
|
|
cutoff := time.Now().UTC().AddDate(0, 0, -7).Format("2006-01-02")
|
|
|
|
var base *Snapshot
|
|
for i := range history {
|
|
if history[i].Date <= cutoff {
|
|
base = &history[i]
|
|
}
|
|
}
|
|
if base == nil {
|
|
return deltas
|
|
}
|
|
for repo, cur := range current.Stars {
|
|
if prev, ok := base.Stars[repo]; ok {
|
|
deltas[repo] = cur - prev
|
|
}
|
|
}
|
|
return deltas
|
|
}
|