summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-04-13 17:51:38 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-04-13 17:51:38 -0600
commit95ebab0baff6fc94ed6214b9603df9c552228b31 (patch)
tree8a14dfa1a7c5ebc83e5ca90c91668035f7b61e79 /cmd
parent816ace2436b57a709a569bfb03a17236db28f1bf (diff)
wip
Diffstat (limited to 'cmd')
-rw-r--r--cmd/generate/httpcache.go34
-rw-r--r--cmd/generate/imworkingon.html.tmpl46
-rw-r--r--cmd/generate/main.go4
-rw-r--r--cmd/generate/src_contribs.go97
-rw-r--r--cmd/generate/src_tags.go5
-rw-r--r--cmd/generate/src_upstreams.go7
6 files changed, 147 insertions, 46 deletions
diff --git a/cmd/generate/httpcache.go b/cmd/generate/httpcache.go
new file mode 100644
index 0000000..7debd0a
--- /dev/null
+++ b/cmd/generate/httpcache.go
@@ -0,0 +1,34 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+)
+
+var httpCache = map[string]string{}
+
+func httpGet(u string) (string, error) {
+ resp, err := http.Get(u)
+ if err != nil {
+ return "", err
+ }
+ if resp.StatusCode != http.StatusOK {
+ return "", fmt.Errorf("unexpected HTTP status: %v", resp.Status)
+ }
+ bs, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+ httpCache[u] = string(bs)
+ return httpCache[u], nil
+}
+
+func httpGetJSON(u string, out any) error {
+ str, err := httpGet(u)
+ if err != nil {
+ return err
+ }
+ return json.Unmarshal([]byte(str), out)
+}
diff --git a/cmd/generate/imworkingon.html.tmpl b/cmd/generate/imworkingon.html.tmpl
index 54d9431..e0ee5a5 100644
--- a/cmd/generate/imworkingon.html.tmpl
+++ b/cmd/generate/imworkingon.html.tmpl
@@ -47,6 +47,7 @@
}
/* tags */
+
article.tag {
padding: 0.5em 2em;
}
@@ -55,9 +56,15 @@
}
/* contribs */
+
article.contrib {
display: grid;
- grid-template-columns: 25% 75%;
+ grid-template-columns: 25% 25% 25% 25%;
+ grid-template-areas:
+ "uname url url url"
+ "uname tag tag tag"
+ "uname submitted status ."
+ "udesc desc desc desc";
padding: 0;
overflow: hidden;
}
@@ -65,34 +72,44 @@
padding: 0.5em;
}
article.contrib div.contrib-upstream-name {
- grid-row: 1 / 3;
- grid-column: 1;
- text-align: center;
+ grid-area: uname;
+
background-color: #DDDDFF;
border-right: solid 1px #8D8DA6;
+
+ text-align: center;
font-weight: bold;
padding-top: 1em;
}
article.contrib div.contrib-upstream-desc {
- grid-row: 3;
- grid-column: 1;
+ grid-area: udesc;
+
background-color: #DDDDFF;
border-top: solid 1px #8D8DA6;
border-right: solid 1px #8D8DA6;
}
article.contrib div.contrib-urls {
- grid-row: 1;
- grid-column: 2;
+ grid-area: url;
padding-bottom: 0;
}
article.contrib div.contrib-tags {
- grid-row: 2;
- grid-column: 2;
+ grid-area: tag;
padding-top: 0;
}
+ article.contrib div.contrib-submitted {
+ grid-area: submitted;
+ background-color: #DDDDFF;
+ border-top: solid 1px #8D8DA6;
+ border-right: solid 1px #8D8DA6;
+ }
+ article.contrib div.contrib-status {
+ grid-area: status;
+ background-color: #DDDDFF;
+ border-top: solid 1px #8D8DA6;
+ border-right: solid 1px #8D8DA6;
+ }
article.contrib div.contrib-desc {
- grid-row: 3;
- grid-column: 2;
+ grid-area: desc;
border-top: solid 1px #8D8DA6;
}
</style>
@@ -110,7 +127,7 @@
</section>
<section id="contribs">
<h1>... by contributing...</h1>
- {{- range $contrib := .Contributions }}
+ {{- range $contrib := .Contribs }}
{{ $upstream := $contrib | getUpstream }}
<article class="contrib">
<div class="contrib-upstream-name"><a href="{{ index $upstream.URLs 0 }}">{{ $upstream.Name }}</a></div>
@@ -125,7 +142,8 @@
<a href="#tag-{{ $tag }}">#{{ $tag }}</a> {{/* */}}
{{- end }}
</div>
- <div class="contrib-submitted-at">{{ $contrib.SubmittedAt }}</div>
+ <div class="contrib-submitted">Submitted: {{ $contrib.SubmittedAt.Format "2006-01-02" }}</div>
+ <div class="contrib-status">Status: {{ $contrib.Status }}</div>
<div class="contrib-desc">{{ $contrib.Desc | md2html }}</div>
</article>
{{- end }}
diff --git a/cmd/generate/main.go b/cmd/generate/main.go
index ce5ce0d..cee0f2e 100644
--- a/cmd/generate/main.go
+++ b/cmd/generate/main.go
@@ -39,7 +39,7 @@ func mainWithError() error {
if err != nil {
return err
}
- tags, err := ReadUpstreams("tags.yml")
+ tags, err := ReadTags("tags.yml")
if err != nil {
return err
}
@@ -77,7 +77,7 @@ func mainWithError() error {
}); err != nil {
return err
}
- if err := os.WriteFile("plan.html", out.Bytes(), 0666); err != nil {
+ if err := os.WriteFile("imworkingon.html", out.Bytes(), 0666); err != nil {
return err
}
return nil
diff --git a/cmd/generate/src_contribs.go b/cmd/generate/src_contribs.go
index eaff24b..b08e18d 100644
--- a/cmd/generate/src_contribs.go
+++ b/cmd/generate/src_contribs.go
@@ -1,10 +1,8 @@
package main
import (
- "encoding/json"
"fmt"
- "io"
- "net/http"
+ "net/url"
"os"
"regexp"
"strings"
@@ -20,21 +18,22 @@ type Contribution struct {
Desc string `json:"desc"`
SubmittedAt time.Time `json:"submitted-at"`
+ Status string `json:"status"`
}
func ReadContribs(filename string) ([]Contribution, error) {
bs, err := os.ReadFile(filename)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("contribs: %q: %w", filename, err)
}
var ret []Contribution
if err := yaml.UnmarshalStrict(bs, &ret); err != nil {
- return nil, err
+ return nil, fmt.Errorf("contribs: %q: %w", filename, err)
}
for i := range ret {
contrib := ret[i]
if err := contrib.Fill(); err != nil {
- return nil, err
+ return nil, fmt.Errorf("contribs: %q: %w", filename, err)
}
ret[i] = contrib
}
@@ -44,7 +43,13 @@ func ReadContribs(filename string) ([]Contribution, error) {
func (c *Contribution) Fill() error {
var err error
if c.SubmittedAt.IsZero() {
- c.SubmittedAt, err = c.getSubmittedAt()
+ c.SubmittedAt, err = c.fetchSubmittedAt()
+ if err != nil {
+ return err
+ }
+ }
+ if c.Status == "" {
+ c.Status, err = c.fetchStatus()
if err != nil {
return err
}
@@ -54,46 +59,88 @@ func (c *Contribution) Fill() error {
var (
reGitHubPR = regexp.MustCompile(`^https://github.com/([^/?#]+)/([^/?#]+)/pull/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`)
+ reGitLabMR = regexp.MustCompile(`^https://([^/]+)/([^?#]+)/-/merge_requests/([0-9]+)(?:\?[^#]*)?(?:#.*)?$`)
rePiperMailDate = regexp.MustCompile(`^\s*<I>([^<]+)</I>\s*$`)
)
-func (c Contribution) getSubmittedAt() (time.Time, error) {
+func (c Contribution) fetchStatus() (string, error) {
if m := reGitHubPR.FindStringSubmatch(c.URLs[0]); m != nil {
user := m[1]
repo := m[2]
prnum := m[3]
- resp, err := http.Get("https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum)
- if err != nil {
- return time.Time{}, err
+
+ urlStr := "https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum
+
+ var obj struct {
+ State string `json:"state"`
}
- if resp.StatusCode != http.StatusOK {
- return time.Time{}, fmt.Errorf("unexpected HTTP status: %v", resp.Status)
+ if err := httpGetJSON(urlStr, &obj); err != nil {
+ return "", err
}
- jsonBytes, err := io.ReadAll(resp.Body)
- if err != nil {
- return time.Time{}, err
+ return obj.State, nil
+ }
+ if m := reGitLabMR.FindStringSubmatch(c.URLs[0]); m != nil {
+ authority := m[1]
+ projectID := m[2]
+ mrnum := m[3]
+
+ urlStr := "https://" + authority + "/api/v4/projects/" + url.QueryEscape(projectID) + "/merge_requests/" + mrnum
+
+ var obj struct {
+ State string `json:"state"`
}
+ if err := httpGetJSON(urlStr, &obj); err != nil {
+ return "", err
+ }
+ return obj.State, nil
+ }
+ if len(c.URLs) > 1 {
+ for _, u := range c.URLs[1:] {
+ if strings.Contains(u, "/commit/") {
+ return "merged", nil
+ }
+ }
+ }
+ return "", fmt.Errorf("idk how to get status for %q", c.URLs[0])
+}
+
+func (c Contribution) fetchSubmittedAt() (time.Time, error) {
+ if m := reGitHubPR.FindStringSubmatch(c.URLs[0]); m != nil {
+ user := m[1]
+ repo := m[2]
+ prnum := m[3]
+
+ urlStr := "https://api.github.com/repos/" + user + "/" + repo + "/pulls/" + prnum
+
var obj struct {
CreatedAt time.Time `json:"created_at"`
}
- if err := json.Unmarshal(jsonBytes, &obj); err != nil {
+ if err := httpGetJSON(urlStr, &obj); err != nil {
return time.Time{}, err
}
return obj.CreatedAt, nil
}
- if strings.Contains(c.URLs[0], "/pipermail/") {
- resp, err := http.Get(c.URLs[0])
- if err != nil {
- return time.Time{}, err
+ if m := reGitLabMR.FindStringSubmatch(c.URLs[0]); m != nil {
+ authority := m[1]
+ projectID := m[2]
+ mrnum := m[3]
+
+ urlStr := "https://" + authority + "/api/v4/projects/" + url.QueryEscape(projectID) + "/merge_requests/" + mrnum
+
+ var obj struct {
+ CreatedAt time.Time `json:"created_at"`
}
- if resp.StatusCode != http.StatusOK {
- return time.Time{}, fmt.Errorf("unexpected HTTP status: %v", resp.Status)
+ if err := httpGetJSON(urlStr, &obj); err != nil {
+ return time.Time{}, err
}
- htmlBytes, err := io.ReadAll(resp.Body)
+ return obj.CreatedAt, nil
+ }
+ if strings.Contains(c.URLs[0], "/pipermail/") {
+ htmlStr, err := httpGet(c.URLs[0])
if err != nil {
return time.Time{}, err
}
- for _, line := range strings.Split(string(htmlBytes), "\n") {
+ for _, line := range strings.Split(htmlStr, "\n") {
if m := rePiperMailDate.FindStringSubmatch(line); m != nil {
return time.Parse(time.UnixDate, m[1])
}
diff --git a/cmd/generate/src_tags.go b/cmd/generate/src_tags.go
index 497f37e..8dcf554 100644
--- a/cmd/generate/src_tags.go
+++ b/cmd/generate/src_tags.go
@@ -1,6 +1,7 @@
package main
import (
+ "fmt"
"os"
"sigs.k8s.io/yaml"
@@ -14,11 +15,11 @@ type TagInfo struct {
func ReadTags(filename string) (map[string]TagInfo, error) {
bs, err := os.ReadFile(filename)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("tags: %q: %w", filename, err)
}
var ret map[string]TagInfo
if err := yaml.UnmarshalStrict(bs, &ret); err != nil {
- return nil, err
+ return nil, fmt.Errorf("tags: %q: %w", filename, err)
}
return ret, nil
}
diff --git a/cmd/generate/src_upstreams.go b/cmd/generate/src_upstreams.go
index 1ea7750..791df1b 100644
--- a/cmd/generate/src_upstreams.go
+++ b/cmd/generate/src_upstreams.go
@@ -2,6 +2,7 @@ package main
import (
_ "embed"
+ "fmt"
"net/url"
"os"
"path"
@@ -18,16 +19,16 @@ type Upstream struct {
func ReadUpstreams(filename string) ([]Upstream, error) {
bs, err := os.ReadFile(filename)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("upstreams: %q: %w", filename, err)
}
var ret []Upstream
if err := yaml.UnmarshalStrict(bs, &ret); err != nil {
- return []Upstream{}, err
+ return nil, fmt.Errorf("upstreams: %q: %w", filename, err)
}
for i := range ret {
upstream := ret[i]
if err := upstream.Fill(); err != nil {
- return nil, err
+ return nil, fmt.Errorf("upstreams: %q: %w", filename, err)
}
ret[i] = upstream
}