Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Show run durations and lazy step logs

c765ae2e18691b3f98d93b00b4eb418ce781e3f1 · Keenan Nemetz · 13d ago · parent bdf6a0de

internal/format/format.go +36−1

@@ -4,7 +4,10 @@
4 4 // web UI and hook messages, not part of the API a developer embeds.
5 5 package format
6 6
7 import "fmt"
7 import (
8 "fmt"
9 "time"
10 )
8 11
9 12 // Bytes renders a byte count in binary units ("1.4 MiB").
10 13 func Bytes(n int64) string {
@@ -43,3 +46,35 @@ func ID(s string) string {
43 46 }
44 47 return s
45 48 }
49
50 // Duration renders a non-negative duration in the compact form the web UI uses:
51 // seconds for short work, minutes and hours once it matters. Sub-second work is
52 // milliseconds, because a step that finished instantly should not read as "0s".
53 func Duration(d time.Duration) string {
54 if d <= 0 {
55 return "0s"
56 }
57 if d < time.Second {
58 return fmt.Sprintf("%dms", d.Milliseconds())
59 }
60 d = d.Round(time.Second)
61 h := d / time.Hour
62 d -= h * time.Hour
63 m := d / time.Minute
64 d -= m * time.Minute
65 s := d / time.Second
66 switch {
67 case h > 0 && m == 0 && s == 0:
68 return fmt.Sprintf("%dh", h)
69 case h > 0 && s == 0:
70 return fmt.Sprintf("%dh %dm", h, m)
71 case h > 0:
72 return fmt.Sprintf("%dh %dm %ds", h, m, s)
73 case m > 0 && s == 0:
74 return fmt.Sprintf("%dm", m)
75 case m > 0:
76 return fmt.Sprintf("%dm %ds", m, s)
77 default:
78 return fmt.Sprintf("%ds", s)
79 }
80 }