1package main
2
3import (
4	"context"
5	"fmt"
6	"time"
7
8	"github.com/charmbracelet/lipgloss"
9	"github.com/muesli/reflow/truncate"
10	"github.com/shurcooL/githubv4"
11)
12
13var historyQuery struct {
14	Repository struct {
15		Object struct {
16			Commit struct {
17				Oid     githubv4.String
18				History struct {
19					TotalCount githubv4.Int
20					Edges      []struct {
21						Cursor githubv4.String
22						Node   struct {
23							QLCommit
24						}
25					}
26				} `graphql:"history(first: 100, since: $since)"`
27			} `graphql:"... on Commit"`
28		} `graphql:"object(expression: \"HEAD\")"`
29	} `graphql:"repository(owner: $owner, name: $name)"`
30}
31
32type QLCommit struct {
33	OID             githubv4.GitObjectID
34	MessageHeadline githubv4.String
35	CommittedDate   githubv4.GitTimestamp
36	Author          struct {
37		User struct {
38			Login githubv4.String
39		}
40	}
41}
42
43type Commit struct {
44	ID              string
45	MessageHeadline string
46	CommittedAt     time.Time
47	Author          string
48}
49
50func history(owner string, name string, since time.Time) ([]Commit, error) {
51	var commits []Commit
52
53	variables := map[string]interface{}{
54		"owner": githubv4.String(owner),
55		"name":  githubv4.String(name),
56		"since": githubv4.GitTimestamp{Time: since},
57	}
58
59	// if err := client.Query(context.Background(), &historyQuery, variables); err != nil {
60	if err := queryWithRetry(context.Background(), &historyQuery, variables); err != nil {
61		return commits, err
62	}
63
64	for _, v := range historyQuery.Repository.Object.Commit.History.Edges {
65		if v.Node.QLCommit.OID == "" {
66			// fmt.Println("Commit ID broken:", v.Node.QLCommit.OID)
67			continue
68		}
69		commits = append(commits, CommitFromQL(v.Node.QLCommit))
70	}
71
72	return commits, nil
73}
74
75func CommitFromQL(commit QLCommit) Commit {
76	return Commit{
77		ID:              string(commit.OID),
78		MessageHeadline: string(commit.MessageHeadline),
79		CommittedAt:     commit.CommittedDate.Time,
80		Author:          string(commit.Author.User.Login),
81	}
82}
83
84func printCommit(commit Commit) {
85	genericStyle := lipgloss.NewStyle().
86		Foreground(lipgloss.Color(theme.colorGray))
87	numberStyle := lipgloss.NewStyle().
88		Foreground(lipgloss.Color(theme.colorBlue))
89	timeStyle := lipgloss.NewStyle().
90		Foreground(lipgloss.Color(theme.colorGreen)).Width(8).Align(lipgloss.Right)
91	titleStyle := lipgloss.NewStyle().
92		Foreground(lipgloss.Color(theme.colorDarkGray)).Width(80 - 7)
93
94	var s string
95	s += numberStyle.Render(commit.ID[:7])
96	s += genericStyle.Render(" ")
97	s += titleStyle.Render(truncate.StringWithTail(commit.MessageHeadline, 80-7, "…"))
98	s += genericStyle.Render(" ")
99	s += timeStyle.Render(ago(commit.CommittedAt))
100	s += genericStyle.Render(" ")
101	s += numberStyle.Render(commit.Author)
102
103	fmt.Println(s)
104}
105
106func printCommits(repo Repo) {
107	commits := repo.LastRelease.CommitsSince
108
109	headerStyle := lipgloss.NewStyle().
110		PaddingTop(1).
111		Foreground(lipgloss.Color(theme.colorMagenta))
112
113	sinceTag := repo.LastRelease.TagName
114	if sinceTag == "" {
115		sinceTag = "creation"
116	}
117
118	fmt.Println(headerStyle.Render(fmt.Sprintf("%s %s %s", "��", pluralize(len(commits), "commit since", "commits since"), sinceTag)))
119
120	// trimmed := false
121	if *maxCommits > 0 && len(commits) > *maxCommits {
122		commits = commits[:*maxCommits]
123		// trimmed = true
124	}
125
126	for _, v := range commits {
127		printCommit(v)
128	}
129	// if trimmed {
130	// 	fmt.Println("...")
131	// }
132}
133