milestoner 16.2.0 → 17.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -1
  3. data/README.adoc +274 -47
  4. data/lib/milestoner/builders/container.rb +15 -0
  5. data/lib/milestoner/builders/import.rb +9 -0
  6. data/lib/milestoner/builders/stream.rb +29 -0
  7. data/lib/milestoner/builders/web.rb +41 -0
  8. data/lib/milestoner/cli/actions/build/format.rb +24 -0
  9. data/lib/milestoner/cli/actions/build/label.rb +26 -0
  10. data/lib/milestoner/cli/actions/build/layout.rb +36 -0
  11. data/lib/milestoner/cli/actions/build/root.rb +25 -0
  12. data/lib/milestoner/cli/actions/build/version.rb +31 -0
  13. data/lib/milestoner/cli/actions/cache/create.rb +35 -0
  14. data/lib/milestoner/cli/actions/cache/delete.rb +34 -0
  15. data/lib/milestoner/cli/actions/cache/find.rb +34 -0
  16. data/lib/milestoner/cli/actions/cache/info.rb +29 -0
  17. data/lib/milestoner/cli/actions/cache/list.rb +33 -0
  18. data/lib/milestoner/cli/actions/publish.rb +9 -5
  19. data/lib/milestoner/cli/commands/build.rb +55 -0
  20. data/lib/milestoner/cli/commands/cache.rb +27 -0
  21. data/lib/milestoner/cli/shell.rb +3 -2
  22. data/lib/milestoner/commits/categorizer.rb +21 -29
  23. data/lib/milestoner/commits/collector.rb +18 -0
  24. data/lib/milestoner/commits/enricher.rb +52 -0
  25. data/lib/milestoner/commits/enrichers/author.rb +26 -0
  26. data/lib/milestoner/commits/enrichers/body.rb +28 -0
  27. data/lib/milestoner/commits/enrichers/colleague.rb +33 -0
  28. data/lib/milestoner/commits/enrichers/container.rb +25 -0
  29. data/lib/milestoner/commits/enrichers/format.rb +23 -0
  30. data/lib/milestoner/commits/enrichers/import.rb +11 -0
  31. data/lib/milestoner/commits/enrichers/issue.rb +28 -0
  32. data/lib/milestoner/commits/enrichers/milestone.rb +24 -0
  33. data/lib/milestoner/commits/enrichers/note.rb +28 -0
  34. data/lib/milestoner/commits/enrichers/review.rb +23 -0
  35. data/lib/milestoner/commits/enrichers/uri.rb +14 -0
  36. data/lib/milestoner/commits/versioner.rb +48 -0
  37. data/lib/milestoner/configuration/contract.rb +29 -3
  38. data/lib/milestoner/configuration/defaults.yml +31 -8
  39. data/lib/milestoner/configuration/model.rb +24 -1
  40. data/lib/milestoner/configuration/transformers/build/root.rb +21 -0
  41. data/lib/milestoner/configuration/transformers/build/template_paths.rb +35 -0
  42. data/lib/milestoner/configuration/transformers/citations/description.rb +37 -0
  43. data/lib/milestoner/configuration/transformers/citations/label.rb +37 -0
  44. data/lib/milestoner/configuration/transformers/gems/description.rb +36 -0
  45. data/lib/milestoner/configuration/transformers/gems/label.rb +36 -0
  46. data/lib/milestoner/configuration/transformers/gems/name.rb +36 -0
  47. data/lib/milestoner/configuration/transformers/gems/uri.rb +36 -0
  48. data/lib/milestoner/configuration/transformers/project/author.rb +33 -0
  49. data/lib/milestoner/configuration/transformers/project/generator.rb +28 -0
  50. data/lib/milestoner/configuration/transformers/project/label.rb +23 -0
  51. data/lib/milestoner/configuration/transformers/project/name.rb +19 -0
  52. data/lib/milestoner/configuration/transformers/project/version.rb +31 -0
  53. data/lib/milestoner/configuration/transformers/uri/avatar.rb +21 -0
  54. data/lib/milestoner/configuration/transformers/uri/commit.rb +24 -0
  55. data/lib/milestoner/configuration/transformers/uri/profile.rb +21 -0
  56. data/lib/milestoner/configuration/transformers/uri/review.rb +24 -0
  57. data/lib/milestoner/configuration/transformers/uri/tracker.rb +24 -0
  58. data/lib/milestoner/container.rb +51 -9
  59. data/lib/milestoner/models/commit.rb +42 -0
  60. data/lib/milestoner/models/link.rb +12 -0
  61. data/lib/milestoner/models/user.rb +12 -0
  62. data/lib/milestoner/renderers/asciidoc.rb +20 -0
  63. data/lib/milestoner/renderers/markdown.rb +20 -0
  64. data/lib/milestoner/renderers/universal.rb +26 -0
  65. data/lib/milestoner/tags/creator.rb +31 -23
  66. data/lib/milestoner/tags/publisher.rb +5 -5
  67. data/lib/milestoner/tags/pusher.rb +9 -3
  68. data/lib/milestoner/templates/layouts/page.html.erb +29 -0
  69. data/lib/milestoner/templates/layouts/page.stream.erb +1 -0
  70. data/lib/milestoner/templates/milestones/_avatar.html.erb +5 -0
  71. data/lib/milestoner/templates/milestones/_commit.html.erb +104 -0
  72. data/lib/milestoner/templates/milestones/_commit.stream.erb +1 -0
  73. data/lib/milestoner/templates/milestones/_icon.html.erb +6 -0
  74. data/lib/milestoner/templates/milestones/_profile.html.erb +5 -0
  75. data/lib/milestoner/templates/milestones/show.html.erb +46 -0
  76. data/lib/milestoner/templates/milestones/show.stream.erb +5 -0
  77. data/lib/milestoner/templates/public/page.css.erb +356 -0
  78. data/lib/milestoner/views/context.rb +25 -0
  79. data/lib/milestoner/views/milestones/show.rb +46 -0
  80. data/lib/milestoner/views/parts/commit.rb +85 -0
  81. data/lib/milestoner.rb +4 -2
  82. data/milestoner.gemspec +17 -11
  83. data.tar.gz.sig +0 -0
  84. metadata +172 -23
  85. metadata.gz.sig +0 -0
  86. data/lib/milestoner/cli/actions/status.rb +0 -37
  87. data/lib/milestoner/presenters/commit.rb +0 -36
@@ -0,0 +1,356 @@
1
+ .milestone {
2
+ --border-width: 0.15rem;
3
+ --color-black: hsl(0, 0%, 0%);
4
+ --color-butter: hsl(52, 100%, 83%);
5
+ --color-carbon: hsl(219, 6%, 58%);
6
+ --color-cheese: hsl(51, 100%, 93%);
7
+ --color-cloud: hsl(219, 100%, 93%);
8
+ --color-ghost: hsl(171.4, 17.1%, 92%);
9
+ --color-green: hsl(110, 88%, 37%);
10
+ --color-grey: hsl(240, 7%, 97%);
11
+ --color-sea: hsl(210, 24%, 15%);
12
+ --color-ice: hsl(216, 100%, 98%);
13
+ --color-major: hsl(231, 97%, 29%);
14
+ --color-minor: hsl(203, 74%, 45%);
15
+ --color-orange: hsl(24.8, 100%, 50.2%);
16
+ --color-patch: hsl(199, 83%, 62%);
17
+ --color-powder: hsl(0, 0%, 98%);
18
+ --color-red: hsl(0, 100%, 50%);
19
+ --color-slate: hsl(211, 23%, 41%);
20
+ --color-smoke: hsl(229, 31%, 93%);
21
+ --color-white: hsl(0, 0%, 100%);
22
+ --font-family: Verdana;
23
+
24
+ display: flex;
25
+ flex-direction: column;
26
+ font-family: var(--font-family);
27
+ margin: 0 12vw;
28
+
29
+ .header {
30
+ display: flex;
31
+ justify-content: space-between;
32
+ margin: 1rem 0 1rem 0;
33
+
34
+ .title {
35
+ margin: 0;
36
+ }
37
+
38
+ .date {
39
+ font-size: 1.4rem;
40
+ font-weight: 600;
41
+ margin: 0;
42
+ }
43
+ }
44
+
45
+ .actions {
46
+ display: flex;
47
+ justify-content: flex-end;
48
+ margin-bottom: 0.5rem;
49
+ }
50
+
51
+ .toggle {
52
+ background-color: var(--color-white);
53
+ border: 0.1rem solid var(--color-sea);
54
+ border-radius: 0.5rem;
55
+ color: var(--color-sea);
56
+ cursor: pointer;
57
+ padding: 0.2rem;
58
+ font-size: 0.9rem;
59
+ width: 5rem;
60
+ }
61
+
62
+ .normal {
63
+ border-width: var(--border-width);
64
+ border-style: solid;
65
+ border-color: transparent;
66
+ border-bottom-color: var(--color-ghost);
67
+ }
68
+
69
+ .alert {
70
+ border: var(--border-width) solid var(--color-orange);
71
+ }
72
+
73
+ .error {
74
+ border: var(--border-width) solid var(--color-red);
75
+ }
76
+
77
+ .avatar {
78
+ border-radius: 50%;
79
+ }
80
+
81
+ .columns {
82
+ background-color: var(--color-black);
83
+ border-top-left-radius: 0.5rem;
84
+ border-top-right-radius: 0.5rem;
85
+ color: var(--color-white);
86
+ display: grid;
87
+ grid-template: 1fr / 4.7fr 1fr 1fr 1fr 1fr 1fr;
88
+ padding: 0.3rem 0;
89
+
90
+ .label {
91
+ font-weight: 600;
92
+ text-align: center;
93
+ }
94
+ }
95
+
96
+ .row {
97
+ .label {
98
+ font-weight: 600;
99
+ }
100
+ }
101
+
102
+ .row[open] > .summary::before {
103
+ content: "\25BC";
104
+ width: 0.5rem;
105
+ }
106
+
107
+ .summary {
108
+ align-items: center;
109
+ display: grid;
110
+ gap: 0 1rem;
111
+ grid-template: 1fr / auto 5fr 1fr 1fr 1fr 1fr 1fr;
112
+ padding: 0.15rem 0;
113
+ margin: 0.25rem 0 0 0;
114
+
115
+ &::-webkit-details-marker {
116
+ display:none;
117
+ }
118
+
119
+ &::before {
120
+ content: "\25B6";
121
+ cursor: pointer;
122
+ width: 0.5rem;
123
+ }
124
+
125
+ &:hover {
126
+ background-color: var(--color-powder);
127
+ }
128
+
129
+ .title {
130
+ align-items: center;
131
+ display: flex;
132
+ gap: 0 0.5rem;
133
+ }
134
+
135
+ .subject {
136
+ word-break: break-word;
137
+ }
138
+
139
+ .author,
140
+ .files,
141
+ .lines,
142
+ .issue,
143
+ .review {
144
+ text-align: center;
145
+ }
146
+
147
+ .avatar {
148
+ vertical-align: middle;
149
+ }
150
+
151
+ .lines {
152
+ .deletions {
153
+ color: var(--color-green);
154
+ }
155
+
156
+ .insertions {
157
+ color: var(--color-red);
158
+ }
159
+ }
160
+ }
161
+
162
+ .details {
163
+ display: grid;
164
+ gap: 1rem;
165
+ grid-template: auto auto auto / auto 1fr;
166
+ grid-template-areas:
167
+ "tag message"
168
+ "tag notes"
169
+ "tag info";
170
+
171
+ @media (width >= 1000px) {
172
+ grid-template: 1fr auto / auto 2fr 1fr;
173
+ grid-template-areas:
174
+ "tag message info"
175
+ "tag notes info";
176
+ }
177
+
178
+ .tag {
179
+ align-self: stretch;
180
+ grid-area: tag;
181
+ padding: 0.5rem 0.2rem 0.5rem 0.1rem;
182
+ text-align: center;
183
+ text-transform: capitalize;
184
+ writing-mode: vertical-lr;
185
+ padding: 0 0.2rem;
186
+ }
187
+
188
+ .major {
189
+ background-color: var(--color-major);
190
+ color: var(--color-white);
191
+ }
192
+
193
+ .minor {
194
+ background-color: var(--color-minor);
195
+ color: var(--color-white);
196
+ }
197
+
198
+ .patch {
199
+ background-color: var(--color-patch);
200
+ color: var(--color-black);
201
+ }
202
+
203
+ .rebase {
204
+ background-color: var(--color-orange);
205
+ color: var(--color-white);
206
+ }
207
+
208
+ .invalid {
209
+ background-color: var(--color-red);
210
+ color: var(--color-white);
211
+ }
212
+
213
+ .unknown {
214
+ background-color: var(--color-carbon);
215
+ color: var(--color-white);
216
+ }
217
+
218
+ .bar {
219
+ border-radius: 0.5rem 0.5rem 0 0;
220
+ color: var(--color-black);
221
+ font-size: 1rem;
222
+ font-weight: 600;
223
+ padding: 0 0 0 0.5rem;
224
+ margin: 0;
225
+ }
226
+
227
+ .panel {
228
+ display: flex;
229
+ flex-direction: column;
230
+ padding: 0 0.5rem 0.5rem 0.5rem;
231
+ }
232
+
233
+ .message {
234
+ background-color: var(--color-grey);
235
+ border-radius: 0.5rem;
236
+ grid-area: message;
237
+ margin-top: 1rem;
238
+
239
+ .bar {
240
+ background-color: var(--color-smoke);
241
+ }
242
+
243
+ .content {
244
+ margin: 0 0.5rem;
245
+ word-break: break-word;
246
+ }
247
+ }
248
+
249
+ .notes {
250
+ background-color: var(--color-cheese);
251
+ border-radius: 0.5rem;
252
+ grid-area: notes;
253
+ margin-bottom: 1rem;
254
+
255
+ .bar {
256
+ background-color: var(--color-butter);
257
+ }
258
+
259
+ .content {
260
+ margin: 0 0.5rem;
261
+ }
262
+ }
263
+
264
+ .info {
265
+ grid-area: info;
266
+ background-color: var(--color-ice);
267
+ border-radius: 0.5rem;
268
+ margin: 1rem 0;
269
+
270
+ .bar {
271
+ background-color: var(--color-cloud);
272
+ }
273
+
274
+ .label {
275
+ font-size: 0.9rem;
276
+ }
277
+
278
+ .item {
279
+ align-self: start;
280
+ display: flex;
281
+ gap: 0.5rem;
282
+ margin: 0;
283
+ }
284
+
285
+ .pill {
286
+ border-radius: 0.5rem;
287
+ padding: 0.1rem 0.4rem;
288
+ }
289
+
290
+ .secure {
291
+ background-color: var(--color-green);
292
+ color: var(--color-white);
293
+
294
+ .signature::before {
295
+ content: "\1F512";
296
+ margin-right: 0.5rem;
297
+ }
298
+ }
299
+
300
+ .insecure {
301
+ background-color: var(--color-red);
302
+ color: var(--color-white);
303
+
304
+ .signature::before {
305
+ content: "\1F513";
306
+ margin-right: 0.5rem;
307
+ }
308
+ }
309
+
310
+ .at {
311
+ flex-wrap: wrap;
312
+
313
+ .weekday {
314
+ &:before {
315
+ content: "(";
316
+ }
317
+
318
+ &:after {
319
+ content: ")";
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+
326
+ .quiet {
327
+ align-items: center;
328
+ display: flex;
329
+ justify-content: center;
330
+ flex-direction: column;
331
+
332
+ &::before {
333
+ content: "\1F303";
334
+ font-size: 10rem;
335
+ }
336
+ }
337
+
338
+ .totals {
339
+ display: flex;
340
+ gap: 0 0.5rem;
341
+ font-weight: 600;
342
+ justify-content: center;
343
+
344
+ .files {
345
+ color: var(--color-slate);
346
+ }
347
+
348
+ .deletions {
349
+ color: var(--color-green);
350
+ }
351
+
352
+ .insertions {
353
+ color: var(--color-red);
354
+ }
355
+ }
356
+ }
@@ -0,0 +1,25 @@
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
+ project_author
16
+ project_description
17
+ project_generator
18
+ project_label
19
+ project_version
20
+ ] => :input
21
+
22
+ def project_title = [project_label, project_version].compact.join " "
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
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 :at, default: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S%z")
20
+ expose :date, default: Time.now.utc.strftime("%Y-%m-%d")
21
+ expose :commits
22
+ expose :uri, default: Container[:configuration].project_uri
23
+
24
+ expose :total_commits do |commits|
25
+ total = commits.size
26
+ "#{total} commit".pluralize "s", total
27
+ end
28
+
29
+ expose :total_files do |commits|
30
+ total = commits.sum(&:files_changed)
31
+ "#{total} file".pluralize "s", total
32
+ end
33
+
34
+ expose :total_deletions do |commits|
35
+ total = commits.sum(&:deletions)
36
+ "#{total} deletion".pluralize "s", total
37
+ end
38
+
39
+ expose :total_insertions do |commits|
40
+ total = commits.sum(&:insertions)
41
+ "#{total} insertion".pluralize "s", total
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "asciidoctor"
4
+ require "hanami/view"
5
+ require "refinements/array"
6
+
7
+ module Milestoner
8
+ module Views
9
+ module Parts
10
+ # Provides presentation for an individual commit.
11
+ # :reek:RepeatedConditional
12
+ class Commit < Hanami::View::Part
13
+ include Import[:configuration, :sanitizer]
14
+
15
+ using Refinements::Array
16
+
17
+ def initialize(**)
18
+ super(**)
19
+ @prefixes = configuration.commit_categories.pluck :label
20
+ @authored_at = Time.at(value.authored_at.to_i).utc
21
+ end
22
+
23
+ def avatar_url(user) = format configuration.avatar_uri, id: user.external_id
24
+
25
+ def profile_url(user) = format configuration.profile_uri, id: user.handle
26
+
27
+ def kind
28
+ if prefixes.include? prefix then "normal"
29
+ elsif value.directive? then "alert"
30
+ else "error"
31
+ end
32
+ end
33
+
34
+ def emoji
35
+ configuration.commit_categories
36
+ .find { |category| category.fetch(:label) == prefix }
37
+ .then { |category| category ? category.fetch(:emoji) : "🔶" }
38
+ end
39
+
40
+ def icon
41
+ if prefixes.include? prefix then String(prefix).downcase
42
+ elsif value.directive? then "rebase"
43
+ else "invalid"
44
+ end
45
+ end
46
+
47
+ def safe_body = sanitizer.call(value.body).html_safe
48
+
49
+ def safe_notes = sanitizer.call(value.notes).html_safe
50
+
51
+ def total_deletions = format "%d", -value.deletions
52
+
53
+ # :reek:FeatureEnvy
54
+ def total_insertions
55
+ value.insertions.then { |total| total.positive? ? "+#{total}" : total.to_s }
56
+ end
57
+
58
+ def tag
59
+ return "rebase" if value.directive?
60
+ return "invalid" unless prefixes.include? prefix
61
+
62
+ value.milestone
63
+ end
64
+
65
+ def security = value.signature == "Good" ? "secure" : "insecure"
66
+
67
+ def at = authored_at.strftime "%Y-%m-%dT%H:%M:%S%z"
68
+
69
+ def weekday = authored_at.strftime "%A"
70
+
71
+ def date = authored_at.strftime "%Y-%m-%d"
72
+
73
+ def time = authored_at.strftime "%H:%M %p"
74
+
75
+ def zone = authored_at.strftime "%Z"
76
+
77
+ private
78
+
79
+ attr_reader :prefixes, :authored_at
80
+
81
+ def prefix = value.prefix
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/milestoner.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "zeitwerk"
4
4
 
5
5
  Zeitwerk::Loader.new.then do |loader|
6
- loader.inflector.inflect "cli" => "CLI"
6
+ loader.inflector.inflect "cli" => "CLI", "uri" => "URI"
7
7
  loader.tag = File.basename __FILE__, ".rb"
8
8
  loader.push_dir __dir__
9
9
  loader.setup
@@ -11,5 +11,7 @@ end
11
11
 
12
12
  # Main namespace.
13
13
  module Milestoner
14
- def self.loader(registry = Zeitwerk::Registry) = registry.loader_for __FILE__
14
+ def self.loader registry = Zeitwerk::Registry
15
+ @loader ||= registry.loaders.find { |loader| loader.tag == File.basename(__FILE__, ".rb") }
16
+ end
15
17
  end
data/milestoner.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "milestoner"
5
- spec.version = "16.2.0"
5
+ spec.version = "17.0.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/milestoner"
@@ -22,19 +22,25 @@ Gem::Specification.new do |spec|
22
22
  spec.signing_key = Gem.default_key_path
23
23
  spec.cert_chain = [Gem.default_cert_path]
24
24
 
25
- spec.required_ruby_version = "~> 3.2"
26
- spec.add_dependency "cogger", "~> 0.12"
25
+ spec.required_ruby_version = "~> 3.3"
26
+ spec.add_dependency "asciidoctor", "~> 2.0"
27
+ spec.add_dependency "cff", "~> 1.1"
28
+ spec.add_dependency "cogger", "~> 0.15"
27
29
  spec.add_dependency "dry-container", "~> 0.11"
28
30
  spec.add_dependency "dry-monads", "~> 1.6"
29
31
  spec.add_dependency "dry-schema", "~> 1.13"
30
- spec.add_dependency "etcher", "~> 0.2"
31
- spec.add_dependency "gitt", "~> 2.0"
32
- spec.add_dependency "infusible", "~> 2.2"
33
- spec.add_dependency "refinements", "~> 11.0"
34
- spec.add_dependency "runcom", "~> 10.0"
35
- spec.add_dependency "sod", "~> 0.0"
36
- spec.add_dependency "spek", "~> 2.0"
37
- spec.add_dependency "versionaire", "~> 12.0"
32
+ spec.add_dependency "etcher", "~> 1.0"
33
+ spec.add_dependency "gitt", "~> 3.0"
34
+ spec.add_dependency "hanami-view", "~> 2.1.0.rc2"
35
+ spec.add_dependency "infusible", "~> 3.0"
36
+ spec.add_dependency "lode", "~> 1.0"
37
+ spec.add_dependency "redcarpet", "~> 3.6"
38
+ spec.add_dependency "refinements", "~> 12.0"
39
+ spec.add_dependency "runcom", "~> 11.0"
40
+ spec.add_dependency "sanitize", "~> 6.1"
41
+ spec.add_dependency "sod", "~> 0.4"
42
+ spec.add_dependency "spek", "~> 3.0"
43
+ spec.add_dependency "versionaire", "~> 13.0"
38
44
  spec.add_dependency "zeitwerk", "~> 2.6"
39
45
 
40
46
  spec.bindir = "exe"
data.tar.gz.sig CHANGED
Binary file