14 // Color returns a HTML color code between green and yellow based on the
15 // number of days that passed since ds.
16 func (ds DateString
) Color() string {
17 date
, _
:= time
.Parse("2006-01-02T15:04:05Z", string(ds
))
18 days
:= int(time
.Since(date
).Hours() / 24)
22 return fmt
.Sprintf("#%02xff00", days
)
25 func fetchLogs(dirs
chan<- NamedFS
) {
26 err
:= fs
.WalkDir(bsdirFS
, ".", func(path
string, d fs
.DirEntry
, err error
) error
{
33 if d
.IsDir() && len(strings
.Split(path
, string(filepath
.Separator
))) == 4 {
42 fmt
.Fprintf(os
.Stderr
, "Reading logs failed: %v\n", err
)
47 func collectLogs(dirs
<-chan NamedFS
) {
48 data
.Logs
= make(map[Timeframe
][]Log
)
49 data
.VendorBoardDate
= make(map[string]DateString
)
50 data
.VendorBoardReferenced
= make(map[string]bool)
51 timeframes
:= make(map[Timeframe
]bool)
52 gitcache
:= make(map[string]string)
53 for dir
:= range dirs
{
55 revB
, err
:= fs
.ReadFile(dir
.FS
, filepath
.Join(dir
.Name
, "revision.txt"))
61 for _
, line
:= range strings
.Split(rev
, "\n") {
62 item
:= strings
.SplitN(line
, ":", 2)
64 // This is an error, but let's try to extract
65 // as much value out of revision.txt files as
66 // possible, even if some lines are erroneous.
69 if item
[0] == "Upstream revision" {
70 upstream
= strings
.TrimSpace(item
[1])
71 // tried using go-git, but its resolver
72 // couldn't expand short hashes despite the
73 // docs claiming that it can.
74 if val
, ok
:= gitcache
[upstream
]; ok
{
77 res
, err
:= exec
.Command("/usr/bin/git", "-C", cbdir
, "log", "-n1", "--format=%H", upstream
).Output()
79 fmt
.Fprintf(os
.Stderr
, "revision %s not found \n", upstream
)
83 gitcache
[upstream
] = strings
.TrimSpace(string(res
))
84 upstream
= gitcache
[upstream
]
92 rawFiles
, err
:= fs
.Glob(dir
.FS
, filepath
.Join(dir
.Name
, "*"))
94 fmt
.Fprintf(os
.Stderr
, "Could not fetch log data, skipping: %v\n", err
)
98 pieces
:= strings
.Split(dir
.Name
, string(filepath
.Separator
))
100 fmt
.Fprintf(os
.Stderr
, "log directory %s is malformed, skipping\n", dir
.Name
)
103 vendorBoard
:= strings
.Join(pieces
[:2], "/")
104 // TODO: these need to become "second to last" and "last" item
105 // but only after compatibility to the current system has been ensured.
106 dateTimePath
:= pieces
[3]
107 dateTime
, err
:= time
.Parse(time
.RFC3339
, strings
.ReplaceAll(dateTimePath
, "_", ":"))
109 fmt
.Fprintf(os
.Stderr
, "Could not parse timestamp from %s: %v\n", dir
.Name
, err
)
112 dateTimeNormal
:= dateTime
.UTC().Format("2006-01-02T15:04:05Z")
113 dateTimeHuman
:= dateTime
.UTC().Format(time
.UnixDate
)
114 tfYear
, tfWeek
:= dateTime
.ISOWeek()
115 timeframe
:= Timeframe(fmt
.Sprintf("%dW%02d", tfYear
, tfWeek
))
117 if !timeframes
[timeframe
] {
118 timeframes
[timeframe
] = true
119 data
.Timeframes
= append(data
.Timeframes
, timeframe
)
120 data
.Logs
[timeframe
] = []Log
{}
124 l
:= len(dir
.Name
) + 1
125 for _
, file
:= range rawFiles
{
126 if file
[l
:] == "revision.txt" {
129 files
= append(files
, Path
{
130 Path
: dir
.Name
+ "/",
135 data
.Logs
[timeframe
] = append(data
.Logs
[timeframe
], Log
{
136 VendorBoard
: vendorBoard
,
137 Time
: dateTimeNormal
,
138 TimeReadable
: dateTimeHuman
,
143 sort
.Slice(data
.Timeframes
, func(i
, j
int) bool {
145 return data
.Timeframes
[i
] > data
.Timeframes
[j
]
147 for bi
:= range data
.Logs
{
148 bucket
:= data
.Logs
[bi
]
149 sort
.Slice(data
.Logs
[bi
], func(i
, j
int) bool {
150 if bucket
[i
].Time
== bucket
[j
].Time
{
151 return (bucket
[i
].VendorBoard
> bucket
[j
].VendorBoard
)
153 return (bucket
[i
].Time
> bucket
[j
].Time
)
156 for _
, ts
:= range data
.Timeframes
{
157 for li
, l
:= range data
.Logs
[ts
] {
158 if _
, match
:= data
.VendorBoardDate
[l
.VendorBoard
]; match
{
161 data
.VendorBoardDate
[l
.VendorBoard
] = DateString(l
.Time
)
162 data
.Logs
[ts
][li
].Reference
= true