milestoner 16.2.1 → 17.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -1
  3. data/README.adoc +333 -57
  4. data/lib/milestoner/builders/ascii_doc.rb +32 -0
  5. data/lib/milestoner/builders/container.rb +17 -0
  6. data/lib/milestoner/builders/import.rb +9 -0
  7. data/lib/milestoner/builders/markdown.rb +32 -0
  8. data/lib/milestoner/builders/stream.rb +29 -0
  9. data/lib/milestoner/builders/web.rb +41 -0
  10. data/lib/milestoner/cli/actions/build/format.rb +24 -0
  11. data/lib/milestoner/cli/actions/build/label.rb +26 -0
  12. data/lib/milestoner/cli/actions/build/layout.rb +36 -0
  13. data/lib/milestoner/cli/actions/build/root.rb +25 -0
  14. data/lib/milestoner/cli/actions/build/version.rb +31 -0
  15. data/lib/milestoner/cli/actions/cache/create.rb +35 -0
  16. data/lib/milestoner/cli/actions/cache/delete.rb +31 -0
  17. data/lib/milestoner/cli/actions/cache/find.rb +31 -0
  18. data/lib/milestoner/cli/actions/cache/info.rb +29 -0
  19. data/lib/milestoner/cli/actions/cache/list.rb +33 -0
  20. data/lib/milestoner/cli/actions/publish.rb +9 -5
  21. data/lib/milestoner/cli/commands/build.rb +60 -0
  22. data/lib/milestoner/cli/commands/cache.rb +27 -0
  23. data/lib/milestoner/cli/shell.rb +3 -2
  24. data/lib/milestoner/commits/categorizer.rb +21 -29
  25. data/lib/milestoner/commits/collector.rb +18 -0
  26. data/lib/milestoner/commits/enricher.rb +51 -0
  27. data/lib/milestoner/commits/enrichers/author.rb +26 -0
  28. data/lib/milestoner/commits/enrichers/body.rb +28 -0
  29. data/lib/milestoner/commits/enrichers/colleague.rb +33 -0
  30. data/lib/milestoner/commits/enrichers/container.rb +25 -0
  31. data/lib/milestoner/commits/enrichers/format.rb +23 -0
  32. data/lib/milestoner/commits/enrichers/import.rb +11 -0
  33. data/lib/milestoner/commits/enrichers/issue.rb +28 -0
  34. data/lib/milestoner/commits/enrichers/milestone.rb +24 -0
  35. data/lib/milestoner/commits/enrichers/note.rb +28 -0
  36. data/lib/milestoner/commits/enrichers/review.rb +23 -0
  37. data/lib/milestoner/commits/enrichers/uri.rb +14 -0
  38. data/lib/milestoner/commits/versioner.rb +48 -0
  39. data/lib/milestoner/configuration/contract.rb +30 -3
  40. data/lib/milestoner/configuration/defaults.yml +31 -8
  41. data/lib/milestoner/configuration/model.rb +26 -1
  42. data/lib/milestoner/configuration/transformers/build/root.rb +21 -0
  43. data/lib/milestoner/configuration/transformers/build/template_paths.rb +32 -0
  44. data/lib/milestoner/configuration/transformers/citations/description.rb +39 -0
  45. data/lib/milestoner/configuration/transformers/citations/label.rb +39 -0
  46. data/lib/milestoner/configuration/transformers/gems/description.rb +34 -0
  47. data/lib/milestoner/configuration/transformers/gems/label.rb +35 -0
  48. data/lib/milestoner/configuration/transformers/gems/name.rb +34 -0
  49. data/lib/milestoner/configuration/transformers/gems/uri.rb +35 -0
  50. data/lib/milestoner/configuration/transformers/generator/label.rb +31 -0
  51. data/lib/milestoner/configuration/transformers/generator/uri.rb +31 -0
  52. data/lib/milestoner/configuration/transformers/project/author.rb +34 -0
  53. data/lib/milestoner/configuration/transformers/project/generator.rb +35 -0
  54. data/lib/milestoner/configuration/transformers/project/label.rb +23 -0
  55. data/lib/milestoner/configuration/transformers/project/name.rb +21 -0
  56. data/lib/milestoner/configuration/transformers/project/version.rb +33 -0
  57. data/lib/milestoner/configuration/transformers/uri/avatar.rb +21 -0
  58. data/lib/milestoner/configuration/transformers/uri/commit.rb +24 -0
  59. data/lib/milestoner/configuration/transformers/uri/profile.rb +21 -0
  60. data/lib/milestoner/configuration/transformers/uri/review.rb +24 -0
  61. data/lib/milestoner/configuration/transformers/uri/tracker.rb +24 -0
  62. data/lib/milestoner/container.rb +52 -9
  63. data/lib/milestoner/models/commit.rb +42 -0
  64. data/lib/milestoner/models/link.rb +12 -0
  65. data/lib/milestoner/models/user.rb +12 -0
  66. data/lib/milestoner/renderers/asciidoc.rb +20 -0
  67. data/lib/milestoner/renderers/markdown.rb +20 -0
  68. data/lib/milestoner/renderers/universal.rb +26 -0
  69. data/lib/milestoner/tags/creator.rb +31 -23
  70. data/lib/milestoner/tags/publisher.rb +5 -5
  71. data/lib/milestoner/tags/pusher.rb +9 -3
  72. data/lib/milestoner/templates/layouts/page.adoc.erb +2 -0
  73. data/lib/milestoner/templates/layouts/page.html.erb +37 -0
  74. data/lib/milestoner/templates/layouts/page.md.erb +2 -0
  75. data/lib/milestoner/templates/layouts/page.stream.erb +2 -0
  76. data/lib/milestoner/templates/milestones/_avatar.html.erb +5 -0
  77. data/lib/milestoner/templates/milestones/_commit.adoc.erb +1 -0
  78. data/lib/milestoner/templates/milestones/_commit.html.erb +104 -0
  79. data/lib/milestoner/templates/milestones/_commit.md.erb +1 -0
  80. data/lib/milestoner/templates/milestones/_commit.stream.erb +1 -0
  81. data/lib/milestoner/templates/milestones/_icon.html.erb +6 -0
  82. data/lib/milestoner/templates/milestones/_profile.html.erb +5 -0
  83. data/lib/milestoner/templates/milestones/show.adoc.erb +9 -0
  84. data/lib/milestoner/templates/milestones/show.html.erb +46 -0
  85. data/lib/milestoner/templates/milestones/show.md.erb +9 -0
  86. data/lib/milestoner/templates/milestones/show.stream.erb +9 -0
  87. data/lib/milestoner/templates/public/page.css.erb +373 -0
  88. data/lib/milestoner/views/context.rb +27 -0
  89. data/lib/milestoner/views/milestones/show.rb +47 -0
  90. data/lib/milestoner/views/parts/commit.rb +85 -0
  91. data/lib/milestoner.rb +1 -1
  92. data/milestoner.gemspec +17 -11
  93. data.tar.gz.sig +0 -0
  94. metadata +182 -26
  95. metadata.gz.sig +1 -1
  96. data/lib/milestoner/cli/actions/status.rb +0 -37
  97. data/lib/milestoner/presenters/commit.rb +0 -36
@@ -0,0 +1,2 @@
1
+ <%= yield %>
2
+ *Generated by [<%= generator_label %>](<%= generator_uri %>).*
@@ -0,0 +1,2 @@
1
+ <%= yield %>
2
+ Generated by <%= generator_label %>.
@@ -0,0 +1,5 @@
1
+ <% if name %>
2
+ <img src="<%= url %>" alt="<%= name %>" class="avatar" width="24" height="24" loading="lazy">
3
+ <% else %>
4
+ <%= render :icon, icon: "missing_avatar", kind: "Unknown" %>
5
+ <% end %>
@@ -0,0 +1 @@
1
+ * <%= commit.emoji %> <%= commit.subject %> - _<%= commit.author.name %>_
@@ -0,0 +1,104 @@
1
+ <details id="<%= commit.sha %>" class="row" x-bind:open="open">
2
+ <summary class="summary <%= commit.kind %>">
3
+ <div class="title">
4
+ <%= render :icon, icon: commit.icon, kind: commit.kind %>
5
+ <span class="subject"><%= commit.subject %></span>
6
+ </div>
7
+
8
+ <div class="author">
9
+ <%= render :avatar, name: commit.author.name, url: commit.avatar_url(commit.author) %>
10
+ </div>
11
+
12
+ <a href="<%= commit.uri %>" class="files"><%= commit.files_changed %></a>
13
+
14
+ <span class="lines">
15
+ <span class="deletions"><%= commit.total_deletions %></span>
16
+ <span class="delimiter">/</span>
17
+ <span class="insertions"><%= commit.total_insertions %></span>
18
+ </span>
19
+
20
+ <% if commit.issue.id %>
21
+ <a href="<%= commit.issue.uri %>" class="issue"><%= commit.issue.id %></a>
22
+ <% else %>
23
+ <span class="issue">-</span>
24
+ <% end %>
25
+
26
+ <% if commit.review.id %>
27
+ <a href="<%= commit.review.uri %>" class="review"><%= commit.review.id %></a>
28
+ <% else %>
29
+ <span class="review">-</span>
30
+ <% end %>
31
+ </summary>
32
+
33
+ <div class="details">
34
+ <div class="tag <%= commit.tag %>"><%= commit.tag %></div>
35
+
36
+ <div class="message">
37
+ <h1 class="bar">Message</h1>
38
+
39
+ <div class="content">
40
+ <%= commit.safe_body %>
41
+ </div>
42
+ </div>
43
+
44
+ <% unless commit.notes.empty? %>
45
+ <div class="notes">
46
+ <h2 class="bar">Notes</h2>
47
+
48
+ <div class="content">
49
+ <%= commit.notes.html_safe %>
50
+ </div>
51
+ </div>
52
+ <% end %>
53
+
54
+ <div class="info">
55
+ <h2 class="bar">Info</h2>
56
+
57
+ <div class="panel">
58
+ <h3 class="label">Author</h3>
59
+
60
+ <p class="item">
61
+ <%= render :avatar, name: commit.author.name, url: commit.avatar_url(commit.author) %>
62
+ <%= render :profile, name: commit.author.name, url: commit.profile_url(commit.author) %>
63
+ </p>
64
+
65
+ <% if commit.collaborators.any? %>
66
+ <h3 class="label">Collaborators</h3>
67
+
68
+ <% commit.collaborators.each do |collaborator| %>
69
+ <p class="item">
70
+ <%= render :avatar, name: collaborator.name, url: commit.avatar_url(collaborator) %>
71
+ <%= render :profile, name: collaborator.name, url: commit.profile_url(collaborator) %>
72
+ </p>
73
+ <% end %>
74
+ <% end %>
75
+
76
+ <% if commit.signers.any? %>
77
+ <h3 class="label">Signers</h3>
78
+
79
+ <% commit.signers.each do |signer| %>
80
+ <p class="item">
81
+ <%= render :avatar, name: signer.name, url: commit.avatar_url(signer) %>
82
+ <%= render :profile, name: signer.name, url: commit.profile_url(signer) %>
83
+ </p>
84
+ <% end %>
85
+ <% end %>
86
+
87
+ <h3 class="label">Signature</h3>
88
+
89
+ <p class="item pill <%= commit.security %>">
90
+ <span class="signature"><%= commit.signature %></span>
91
+ </p>
92
+
93
+ <h3 class="label">Created</h3>
94
+
95
+ <p class="item at">
96
+ <time datetime="<%= commit.at %>" class="date"><%= commit.date %></time>
97
+ <time datetime="<%= commit.at %>" class="weekday"><%= commit.weekday %></time>
98
+ <time datetime="<%= commit.at %>" class="time"><%= commit.time %></time>
99
+ <time datetime="<%= commit.at %>" class="zone"><%= commit.zone %></time>
100
+ </p>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </details>
@@ -0,0 +1 @@
1
+ - <%= commit.emoji %> <%= commit.subject %> - *<%= commit.author.name %>*
@@ -0,0 +1 @@
1
+ <%= commit.emoji %> <%= commit.subject %> - <%= commit.author.name %>
@@ -0,0 +1,6 @@
1
+ <img src="https://alchemists.io/images/projects/milestoner/icons/commits/<%= icon %>.png"
2
+ alt="<%= kind %>"
3
+ class="icon"
4
+ width="24"
5
+ height="24"
6
+ loading="lazy">
@@ -0,0 +1,5 @@
1
+ <% if name %>
2
+ <a href="<%= url %>"><%= name %></a>
3
+ <% else %>
4
+ <span>Unknown</span>
5
+ <% end %>
@@ -0,0 +1,9 @@
1
+ = <%= project_label %> <%= project_version %> (<%= date %>)
2
+
3
+ <% if commits.empty? %>
4
+ *<%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.*
5
+ <% else %>
6
+ <% commits.each do |commit| %><%= commit.render :commit %><% end %>
7
+
8
+ *<%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.*
9
+ <% end %>
@@ -0,0 +1,46 @@
1
+ <article class="milestone">
2
+ <header class="header">
3
+ <h1 class="title">
4
+ <a href="<%= uri %>" class="label"><%= project_label %></a>
5
+ <span class="version"><%= project_version %></span>
6
+ </h1>
7
+
8
+ <time datetime="<%= datetime %>" class="date"><%= date %></time>
9
+ </header>
10
+
11
+ <% if commits.empty? %>
12
+ <p class="dormant"></p>
13
+ <% else %>
14
+ <section class="body" x-data="{open: false}">
15
+ <div class="actions">
16
+ <button class="toggle"
17
+ x-on:click="open = !open"
18
+ x-text="open ? 'Collapse' : 'Expand'">
19
+ Expand
20
+ </button>
21
+ </div>
22
+
23
+ <div class="columns">
24
+ <span class="label">Commit</span>
25
+ <span class="label">Author</span>
26
+ <span class="label">Files</span>
27
+ <span class="label">Lines</span>
28
+ <span class="label">Issue</span>
29
+ <span class="label">Review</span>
30
+ </div>
31
+
32
+ <% commits.each do |commit| %>
33
+ <%= commit.render :commit %>
34
+ <% end %>
35
+ </section>
36
+ <% end %>
37
+
38
+ <footer class="footer">
39
+ <p class="totals">
40
+ <span class="commits"><%= total_commits %>.</span>
41
+ <span class="files"><%= total_files %>.</span>
42
+ <span class="deletions"><%= total_deletions %>.</span>
43
+ <span class="insertions"><%= total_insertions %>.</span>
44
+ </p>
45
+ </footer>
46
+ </article>
@@ -0,0 +1,9 @@
1
+ # <%= project_label %> <%= project_version %> (<%= date %>)
2
+
3
+ <% if commits.empty? %>
4
+ **<%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.**
5
+ <% else %>
6
+ <% commits.each do |commit| %><%= commit.render :commit %><% end %>
7
+
8
+ **<%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.**
9
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <%= project_label %> <%= project_version %> (<%= date %>)
2
+
3
+ <% if commits.empty? %>
4
+ <%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.
5
+ <% else %>
6
+ <% commits.each do |commit| %><%= commit.render :commit %><% end %>
7
+
8
+ <%= total_commits %>. <%= total_files %>. <%= total_deletions %>. <%= total_insertions %>.
9
+ <% end %>
@@ -0,0 +1,373 @@
1
+ :root {
2
+ --font-family: Verdana;
3
+ }
4
+
5
+ .milestone {
6
+ --border-width: 0.15rem;
7
+ --color-black: hsl(0, 0%, 0%);
8
+ --color-butter: hsl(52, 100%, 83%);
9
+ --color-carbon: hsl(219, 6%, 58%);
10
+ --color-cheese: hsl(51, 100%, 93%);
11
+ --color-cloud: hsl(219, 100%, 93%);
12
+ --color-ghost: hsl(171.4, 17.1%, 92%);
13
+ --color-green: hsl(110, 88%, 37%);
14
+ --color-grey: hsl(240, 7%, 97%);
15
+ --color-sea: hsl(210, 24%, 15%);
16
+ --color-ice: hsl(216, 100%, 98%);
17
+ --color-major: hsl(231, 97%, 29%);
18
+ --color-minor: hsl(203, 74%, 45%);
19
+ --color-orange: hsl(24.8, 100%, 50.2%);
20
+ --color-patch: hsl(199, 83%, 62%);
21
+ --color-powder: hsl(0, 0%, 98%);
22
+ --color-red: hsl(0, 100%, 50%);
23
+ --color-slate: hsl(211, 23%, 41%);
24
+ --color-smoke: hsl(229, 31%, 93%);
25
+ --color-white: hsl(0, 0%, 100%);
26
+
27
+ display: flex;
28
+ flex-direction: column;
29
+ font-family: var(--font-family);
30
+ margin: 0 12vw;
31
+
32
+ .header {
33
+ display: flex;
34
+ justify-content: space-between;
35
+ margin: 1rem 0 1rem 0;
36
+
37
+ .title {
38
+ margin: 0;
39
+ }
40
+
41
+ .date {
42
+ font-size: 1.4rem;
43
+ font-weight: 600;
44
+ margin: 0;
45
+ }
46
+ }
47
+
48
+ .actions {
49
+ display: flex;
50
+ justify-content: flex-end;
51
+ margin-bottom: 0.5rem;
52
+ }
53
+
54
+ .toggle {
55
+ background-color: var(--color-white);
56
+ border: 0.1rem solid var(--color-sea);
57
+ border-radius: 0.5rem;
58
+ color: var(--color-sea);
59
+ cursor: pointer;
60
+ padding: 0.2rem;
61
+ font-size: 0.9rem;
62
+ width: 5rem;
63
+ }
64
+
65
+ .normal {
66
+ border-width: var(--border-width);
67
+ border-style: solid;
68
+ border-color: transparent;
69
+ border-bottom-color: var(--color-ghost);
70
+ }
71
+
72
+ .alert {
73
+ border: var(--border-width) solid var(--color-orange);
74
+ }
75
+
76
+ .error {
77
+ border: var(--border-width) solid var(--color-red);
78
+ }
79
+
80
+ .avatar {
81
+ border-radius: 50%;
82
+ }
83
+
84
+ .columns {
85
+ background-color: var(--color-black);
86
+ border-top-left-radius: 0.5rem;
87
+ border-top-right-radius: 0.5rem;
88
+ color: var(--color-white);
89
+ display: grid;
90
+ grid-template: 1fr / 4.7fr 1fr 1fr 1fr 1fr 1fr;
91
+ padding: 0.3rem 0;
92
+
93
+ .label {
94
+ font-weight: 600;
95
+ text-align: center;
96
+ }
97
+ }
98
+
99
+ .row {
100
+ .label {
101
+ font-weight: 600;
102
+ }
103
+ }
104
+
105
+ .row[open] > .summary::before {
106
+ content: "\25BC";
107
+ width: 0.5rem;
108
+ }
109
+
110
+ .summary {
111
+ align-items: center;
112
+ display: grid;
113
+ gap: 0 1rem;
114
+ grid-template: 1fr / auto 5fr 1fr 1fr 1fr 1fr 1fr;
115
+ padding: 0.15rem 0;
116
+ margin: 0.25rem 0 0 0;
117
+
118
+ &::-webkit-details-marker {
119
+ display:none;
120
+ }
121
+
122
+ &::before {
123
+ content: "\25B6";
124
+ cursor: pointer;
125
+ width: 0.5rem;
126
+ }
127
+
128
+ &:hover {
129
+ background-color: var(--color-powder);
130
+ }
131
+
132
+ .title {
133
+ align-items: center;
134
+ display: flex;
135
+ gap: 0 0.5rem;
136
+ }
137
+
138
+ .subject {
139
+ word-break: break-word;
140
+ }
141
+
142
+ .author,
143
+ .files,
144
+ .lines,
145
+ .issue,
146
+ .review {
147
+ text-align: center;
148
+ }
149
+
150
+ .avatar {
151
+ vertical-align: middle;
152
+ }
153
+
154
+ .lines {
155
+ .deletions {
156
+ color: var(--color-green);
157
+ }
158
+
159
+ .insertions {
160
+ color: var(--color-red);
161
+ }
162
+ }
163
+ }
164
+
165
+ .details {
166
+ display: grid;
167
+ gap: 1rem;
168
+ grid-template: auto auto auto / auto 1fr;
169
+ grid-template-areas:
170
+ "tag message"
171
+ "tag notes"
172
+ "tag info";
173
+
174
+ @media (width >= 1000px) {
175
+ grid-template: 1fr auto / auto 2fr 1fr;
176
+ grid-template-areas:
177
+ "tag message info"
178
+ "tag notes info";
179
+ }
180
+
181
+ .tag {
182
+ align-self: stretch;
183
+ grid-area: tag;
184
+ padding: 0.5rem 0.2rem 0.5rem 0.1rem;
185
+ text-align: center;
186
+ text-transform: capitalize;
187
+ writing-mode: vertical-lr;
188
+ padding: 0 0.2rem;
189
+ }
190
+
191
+ .major {
192
+ background-color: var(--color-major);
193
+ color: var(--color-white);
194
+ }
195
+
196
+ .minor {
197
+ background-color: var(--color-minor);
198
+ color: var(--color-white);
199
+ }
200
+
201
+ .patch {
202
+ background-color: var(--color-patch);
203
+ color: var(--color-black);
204
+ }
205
+
206
+ .rebase {
207
+ background-color: var(--color-orange);
208
+ color: var(--color-white);
209
+ }
210
+
211
+ .invalid {
212
+ background-color: var(--color-red);
213
+ color: var(--color-white);
214
+ }
215
+
216
+ .unknown {
217
+ background-color: var(--color-carbon);
218
+ color: var(--color-white);
219
+ }
220
+
221
+ .bar {
222
+ border-radius: 0.5rem 0.5rem 0 0;
223
+ color: var(--color-black);
224
+ font-size: 1rem;
225
+ font-weight: 600;
226
+ padding: 0 0 0 0.5rem;
227
+ margin: 0;
228
+ }
229
+
230
+ .panel {
231
+ display: flex;
232
+ flex-direction: column;
233
+ padding: 0 0.5rem 0.5rem 0.5rem;
234
+ }
235
+
236
+ .message {
237
+ background-color: var(--color-grey);
238
+ border-radius: 0.5rem;
239
+ grid-area: message;
240
+ margin-top: 1rem;
241
+
242
+ .bar {
243
+ background-color: var(--color-smoke);
244
+ }
245
+
246
+ .content {
247
+ margin: 0 0.5rem;
248
+ word-break: break-word;
249
+ }
250
+ }
251
+
252
+ .notes {
253
+ background-color: var(--color-cheese);
254
+ border-radius: 0.5rem;
255
+ grid-area: notes;
256
+ margin-bottom: 1rem;
257
+
258
+ .bar {
259
+ background-color: var(--color-butter);
260
+ }
261
+
262
+ .content {
263
+ margin: 0 0.5rem;
264
+ }
265
+ }
266
+
267
+ .info {
268
+ grid-area: info;
269
+ background-color: var(--color-ice);
270
+ border-radius: 0.5rem;
271
+ margin: 1rem 0;
272
+
273
+ .bar {
274
+ background-color: var(--color-cloud);
275
+ }
276
+
277
+ .label {
278
+ font-size: 0.9rem;
279
+ }
280
+
281
+ .item {
282
+ align-self: start;
283
+ display: flex;
284
+ gap: 0.5rem;
285
+ margin: 0;
286
+ }
287
+
288
+ .pill {
289
+ border-radius: 0.5rem;
290
+ padding: 0.1rem 0.4rem;
291
+ }
292
+
293
+ .secure {
294
+ background-color: var(--color-green);
295
+ color: var(--color-white);
296
+
297
+ .signature::before {
298
+ content: "\1F512";
299
+ margin-right: 0.5rem;
300
+ }
301
+ }
302
+
303
+ .insecure {
304
+ background-color: var(--color-red);
305
+ color: var(--color-white);
306
+
307
+ .signature::before {
308
+ content: "\1F513";
309
+ margin-right: 0.5rem;
310
+ }
311
+ }
312
+
313
+ .at {
314
+ flex-wrap: wrap;
315
+
316
+ .weekday {
317
+ &:before {
318
+ content: "(";
319
+ }
320
+
321
+ &:after {
322
+ content: ")";
323
+ }
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ .dormant {
330
+ align-items: center;
331
+ display: flex;
332
+ justify-content: center;
333
+ flex-direction: column;
334
+
335
+ &::before {
336
+ content: "\1F303";
337
+ font-size: 10rem;
338
+ }
339
+ }
340
+
341
+ .totals {
342
+ display: flex;
343
+ gap: 0 0.5rem;
344
+ font-weight: 600;
345
+ justify-content: center;
346
+
347
+ .files {
348
+ color: var(--color-slate);
349
+ }
350
+
351
+ .deletions {
352
+ color: var(--color-green);
353
+ }
354
+
355
+ .insertions {
356
+ color: var(--color-red);
357
+ }
358
+ }
359
+ }
360
+
361
+ .footer {
362
+ .generator {
363
+ display: flex;
364
+ font-family: var(--font-family);
365
+ font-style: italic;
366
+ justify-content: center;
367
+ margin-top: 2rem;
368
+ }
369
+
370
+ .link {
371
+ padding-left: 0.3rem;
372
+ }
373
+ }
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require "hanami/view"
5
+
6
+ module Milestoner
7
+ module Views
8
+ # Provides a common context for all views.
9
+ class Context < Hanami::View::Context
10
+ extend Forwardable
11
+
12
+ include Import[:input]
13
+
14
+ delegate %i[
15
+ generator_label
16
+ generator_uri
17
+ project_author
18
+ project_description
19
+ project_generator
20
+ project_label
21
+ project_version
22
+ ] => :input
23
+
24
+ def project_title = [project_label, project_version].compact.join " "
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/view"
4
+ require "pathname"
5
+ require "refinements/string"
6
+
7
+ module Milestoner
8
+ module Views
9
+ module Milestones
10
+ # Produces release notes in HTML format.
11
+ class Show < Hanami::View
12
+ using Refinements::String
13
+
14
+ config.default_context = Context.new
15
+ config.part_namespace = Parts
16
+ config.paths = Container[:configuration].build_template_paths
17
+ config.template = "milestones/show"
18
+
19
+ expose :commits
20
+ expose :uri, default: Container[:configuration].project_uri
21
+ expose :at, default: Time.now.utc
22
+ expose(:date) { |at| at.strftime "%Y-%m-%d" }
23
+ expose(:datetime) { |at| at.strftime "%Y-%m-%dT%H:%M:%S%z" }
24
+
25
+ expose :total_commits do |commits|
26
+ total = commits.size
27
+ "#{total} commit".pluralize "s", total
28
+ end
29
+
30
+ expose :total_files do |commits|
31
+ total = commits.sum(&:files_changed)
32
+ "#{total} file".pluralize "s", total
33
+ end
34
+
35
+ expose :total_deletions do |commits|
36
+ total = commits.sum(&:deletions)
37
+ "#{total} deletion".pluralize "s", total
38
+ end
39
+
40
+ expose :total_insertions do |commits|
41
+ total = commits.sum(&:insertions)
42
+ "#{total} insertion".pluralize "s", total
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end