From 6da484b892b56675ee6e2a0410b0e3ebe277ec21 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sat, 28 Jan 2023 01:54:07 -0800 Subject: [PATCH] refactor from mgfetch into commits --- cmd/mgfetch/mgfetch.go | 133 +--------------------------------- cmd/server/svg-server.go | 7 +- commits/commits.go | 151 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 133 deletions(-) create mode 100644 commits/commits.go diff --git a/cmd/mgfetch/mgfetch.go b/cmd/mgfetch/mgfetch.go index f378ba6..37db193 100644 --- a/cmd/mgfetch/mgfetch.go +++ b/cmd/mgfetch/mgfetch.go @@ -1,149 +1,22 @@ package main import ( - "errors" "fmt" - "os" - "regexp" "time" git "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/taigrr/gico/types" - "github.com/taigrr/mg/parse" + "github.com/taigrr/gico/commits" ) type Repo git.Repository func main() { year := time.Now().Year() - 1 - yearLength := 365 - if year%4 == 0 { - yearLength++ - } - gfreq := make(types.YearFreq, yearLength) - mrconf, err := parse.LoadMRConfig() + authors := []string{"Groot"} + gfreq, err := commits.GlobalFrequency(year, authors) if err != nil { panic(err) } - paths := mrconf.GetRepoPaths() - for _, p := range paths { - repo, err := OpenRepo(p) - if err != nil { - panic(err) - } - commits, err := repo.GetCommitSetForYear(year) - if err != nil { - panic(err) - } - commits, err = commits.FilterByAuthorRegex([]string{"Groot"}) - if err != nil { - panic(err) - } - freq := commits.ToYearFreq() - gfreq = gfreq.Merge(freq) - } fmt.Print(gfreq.String()) } - -func OpenRepo(directory string) (Repo, error) { - if s, err := os.Stat(directory); err != nil { - return Repo{}, err - } else { - if !s.IsDir() { - return Repo{}, errors.New("received path to non-directory for git repo") - } - } - r, err := git.PlainOpenWithOptions(directory, &(git.PlainOpenOptions{DetectDotGit: true})) - return Repo(*r), err -} - -type CommitSet struct { - Commits []types.Commit - Year int -} - -func (cs CommitSet) ToYearFreq() types.YearFreq { - year := cs.Year - yearLength := 365 - if year%4 == 0 { - yearLength++ - } - freq := make([]int, yearLength) - data := types.NewDataSet() - for _, commit := range cs.Commits { - ts := commit.TimeStamp - roundedTS := ts.Round(time.Hour * 24) - wd, ok := data[roundedTS] - if !ok { - wd = types.WorkDay{} - wd.Commits = []types.Commit{} - } - wd.Commits = append(wd.Commits, commit) - wd.Count++ - wd.Day = roundedTS - data[roundedTS] = wd - } - for k, v := range data { - if k.Year() != year { - continue - } - // this is equivalent to adding len(commits) to the freq total, but - // it's a stub for later when we do more here - for range v.Commits { - freq[k.YearDay()-1]++ - } - } - return freq -} - -func (cs CommitSet) FilterByAuthorRegex(authors []string) (CommitSet, error) { - regSet := [](*regexp.Regexp){} - for _, a := range authors { - r, err := regexp.Compile(a) - if err != nil { - return CommitSet{}, err - } - regSet = append(regSet, r) - } - newCS := CommitSet{Year: cs.Year} - for _, commit := range cs.Commits { - for _, r := range regSet { - if r.MatchString(commit.Author) { - newCS.Commits = append(newCS.Commits, commit) - break - } - } - } - return newCS, nil -} - -func (repo Repo) GetCommitSetForYear(year int) (CommitSet, error) { - yearLength := 365 - if year%4 == 0 { - yearLength++ - } - cs := CommitSet{} - commits := []types.Commit{} - r := git.Repository(repo) - ref, err := r.Head() - if err != nil { - return cs, err - } - cIter, err := r.Log(&git.LogOptions{From: ref.Hash()}) - if err != nil { - return cs, err - } - err = cIter.ForEach(func(c *object.Commit) error { - ts := c.Author.When - commit := types.Commit{Author: c.Author.Name, Message: c.Message, TimeStamp: ts} - if commit.TimeStamp.Year() == year { - commits = append(commits, commit) - } - return nil - }) - cs.Commits = commits - cs.Year = year - return cs, nil -} diff --git a/cmd/server/svg-server.go b/cmd/server/svg-server.go index 3d54ab7..0b085c6 100644 --- a/cmd/server/svg-server.go +++ b/cmd/server/svg-server.go @@ -7,6 +7,7 @@ import ( "github.com/gorilla/mux" + "github.com/taigrr/gico/commits" "github.com/taigrr/gico/gitgraph/svg" ) @@ -28,9 +29,9 @@ func main() { svg.WriteTo(w) }) r.HandleFunc("/yearly.svg", func(w http.ResponseWriter, r *http.Request) { - freq := []int{} - for i := 0; i < 365; i++ { - freq = append(freq, rand.Int()) + freq, err := commits.GlobalFrequency(2022, []string{"Groot"}) + if err != nil { + panic(err) } svg := svg.GetYearSVG(freq) w.Header().Add("Content-Type", "text/html") diff --git a/commits/commits.go b/commits/commits.go new file mode 100644 index 0000000..8738012 --- /dev/null +++ b/commits/commits.go @@ -0,0 +1,151 @@ +package commits + +import ( + "errors" + "os" + "regexp" + "time" + + git "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + + "github.com/taigrr/gico/types" + "github.com/taigrr/mg/parse" +) + +type Repo git.Repository + +func GlobalFrequency(year int, authors []string) (types.YearFreq, error) { + yearLength := 365 + if year%4 == 0 { + yearLength++ + } + gfreq := make(types.YearFreq, yearLength) + mrconf, err := parse.LoadMRConfig() + if err != nil { + return types.YearFreq{}, err + } + paths := mrconf.GetRepoPaths() + for _, p := range paths { + repo, err := OpenRepo(p) + if err != nil { + return types.YearFreq{}, err + } + commits, err := repo.GetCommitSet() + if err != nil { + return types.YearFreq{}, err + } + commits = commits.FilterByYear(year) + commits, err = commits.FilterByAuthorRegex(authors) + if err != nil { + return types.YearFreq{}, err + } + freq := commits.ToYearFreq() + gfreq = gfreq.Merge(freq) + } + return gfreq, nil +} + +func OpenRepo(directory string) (Repo, error) { + if s, err := os.Stat(directory); err != nil { + return Repo{}, err + } else { + if !s.IsDir() { + return Repo{}, errors.New("received path to non-directory for git repo") + } + } + r, err := git.PlainOpenWithOptions(directory, &(git.PlainOpenOptions{DetectDotGit: true})) + return Repo(*r), err +} + +type CommitSet struct { + Commits []types.Commit + Year int +} + +func (cs CommitSet) ToYearFreq() types.YearFreq { + year := cs.Year + yearLength := 365 + if year%4 == 0 { + yearLength++ + } + freq := make([]int, yearLength) + data := types.NewDataSet() + for _, commit := range cs.Commits { + ts := commit.TimeStamp + roundedTS := ts.Round(time.Hour * 24) + wd, ok := data[roundedTS] + if !ok { + wd = types.WorkDay{} + wd.Commits = []types.Commit{} + } + wd.Commits = append(wd.Commits, commit) + wd.Count++ + wd.Day = roundedTS + data[roundedTS] = wd + } + for k, v := range data { + if k.Year() != year { + continue + } + // this is equivalent to adding len(commits) to the freq total, but + // it's a stub for later when we do more here + for range v.Commits { + freq[k.YearDay()-1]++ + } + } + return freq +} + +func (cs CommitSet) FilterByAuthorRegex(authors []string) (CommitSet, error) { + regSet := [](*regexp.Regexp){} + for _, a := range authors { + r, err := regexp.Compile(a) + if err != nil { + return CommitSet{}, err + } + regSet = append(regSet, r) + } + newCS := CommitSet{Year: cs.Year} + for _, commit := range cs.Commits { + for _, r := range regSet { + if r.MatchString(commit.Author) { + newCS.Commits = append(newCS.Commits, commit) + break + } + } + } + return newCS, nil +} + +func (cs CommitSet) FilterByYear(year int) CommitSet { + newCS := CommitSet{Year: year} + for _, commit := range cs.Commits { + if commit.TimeStamp.Year() == year { + newCS.Commits = append(newCS.Commits, commit) + } + } + return newCS +} + +func (repo Repo) GetCommitSet() (CommitSet, error) { + cs := CommitSet{} + commits := []types.Commit{} + r := git.Repository(repo) + ref, err := r.Head() + if err != nil { + return cs, err + } + cIter, err := r.Log(&git.LogOptions{From: ref.Hash()}) + if err != nil { + return cs, err + } + cIter.ForEach(func(c *object.Commit) error { + ts := c.Author.When + commit := types.Commit{Author: c.Author.Name, Message: c.Message, TimeStamp: ts} + commits = append(commits, commit) + return nil + }) + cs.Commits = commits + return cs, nil +}