milestoner 19.1.0 → 19.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +95 -2
- data/lib/milestoner/builders/container.rb +1 -0
- data/lib/milestoner/builders/manifest.rb +41 -0
- data/lib/milestoner/builders/path_resolver.rb +1 -1
- data/lib/milestoner/builders/site/indexer.rb +1 -0
- data/lib/milestoner/builders/syndication/builder.rb +1 -1
- data/lib/milestoner/cli/actions/build/manifest.rb +24 -0
- data/lib/milestoner/cli/commands/build.rb +4 -1
- data/lib/milestoner/configuration/contract.rb +1 -0
- data/lib/milestoner/configuration/defaults.yml +1 -0
- data/lib/milestoner/configuration/model.rb +1 -0
- data/lib/milestoner/durationer.rb +15 -8
- data/lib/milestoner/tags/manifest.rb +52 -0
- data/lib/milestoner/templates/layouts/page.html.erb +8 -3
- data/lib/milestoner/templates/milestones/_commit.html.erb +8 -9
- data/lib/milestoner/templates/milestones/index.adoc.erb +1 -1
- data/lib/milestoner/templates/milestones/index.html.erb +26 -17
- data/lib/milestoner/templates/milestones/index.md.erb +1 -1
- data/lib/milestoner/templates/milestones/show.adoc.erb +1 -1
- data/lib/milestoner/templates/milestones/show.html.erb +29 -18
- data/lib/milestoner/templates/milestones/show.md.erb +1 -1
- data/lib/milestoner/templates/public/page.css.erb +95 -38
- data/lib/milestoner/views/context.rb +9 -0
- data/milestoner.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +6 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1216fdfa3ee558e0f321b79ad864c5fdca540233896721aaa416841a061423c
|
4
|
+
data.tar.gz: 203a5d11b22360d123413129ba3a83ae6f93fc8cf44d09ccfb7f40f1cf2c5ecc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4394df1c89804ceafbbbe5b85e67239288430b23216bb251ec11f1bb00f67fee947d3b06cc1da6f3792e222453d6a986c154561390e1da04c74c38c32482f29b
|
7
|
+
data.tar.gz: b4769cd20edf13fea347875433974c6b510ec22aaa58c4b7d345685103e6e5e92a8a80ac823601f62ac71b54b23d346e0b35ffe2bf8b2ba5087729ef4b390887
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.adoc
CHANGED
@@ -171,6 +171,7 @@ build:
|
|
171
171
|
format: "stream"
|
172
172
|
index: true
|
173
173
|
layout: "page"
|
174
|
+
manifest: false
|
174
175
|
max: 1
|
175
176
|
output: "tmp/milestones"
|
176
177
|
stylesheet: true
|
@@ -236,7 +237,8 @@ The above can be customized as follows:
|
|
236
237
|
** `basename`: Required. The build file basename. Default: `index`. Used to customize the built file name.
|
237
238
|
** `format`: Required. The build output format. Default: `stream`. Used to determine what format to build the release notes as. Multiple formats are supported.
|
238
239
|
** `index`: Required. Enables (or disables) building the versions index page for web format only. Default: true.
|
239
|
-
** `layout`: Required. The {hanami_views_link} layout used when building release notes. Default: page
|
240
|
+
** `layout`: Required. The {hanami_views_link} layout used when building release notes. Default: `page`. This can be disabled when using `false` or customized further -- via your own {xdg_link} configuration -- when providing your own templates and/or partials.
|
241
|
+
** `manifest`: Required. The JSON manifest of milestones built. Handy for when you've built/cached previous milestones and want a quick way to check for differences (if any). Default: `false`.
|
240
242
|
** `max`: Required. The maximum number of {git_link} tags to build. Default: 1. By default, you are limited to building release notes for changes (commits) since the last tag but you can increase the maximum to build release notes for as many tags as you like.
|
241
243
|
** `output`: Required. The the directory for all generated output. Default: `tmp/milestones`. This can be a relative or absolute path and defaults to the current working directory. The path is automatically created if missing.
|
242
244
|
** `stylesheet`: Required. Enables (or disables) building the stylesheet for web format only. Default: true.
|
@@ -357,7 +359,7 @@ image:https://alchemists.io/images/projects/milestoner/screenshots/no_cache.png[
|
|
357
359
|
|
358
360
|
=== Build
|
359
361
|
|
360
|
-
image:https://alchemists.io/images/projects/milestoner/screenshots/usage-build.png[Usage,width=
|
362
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/usage-build.png[Usage,width=786,height=708,role=focal_point]
|
361
363
|
|
362
364
|
The build command allows you to quickly build release notes to check the current status of your project or deploy a new milestone. By default, the build command uses either the default or custom configuration as documented in the _Configuration_ section above. This means, when using the defaults, you can immediately build the release notes for your project in a temporary directory:
|
363
365
|
|
@@ -548,6 +550,97 @@ Milestone: patch
|
|
548
550
|
|
549
551
|
Given the above, the resulting version would be: 2.0.0. This is because the highest milestone was a _major_ milestone.
|
550
552
|
|
553
|
+
==== Manifest
|
554
|
+
|
555
|
+
When the manifest is enabled via the global/local {xdg_link} configuration or via the CLI, then a `manifest.json` file will be created for you in the root of your build output folder with contents similar to the following:
|
556
|
+
|
557
|
+
[source,json]
|
558
|
+
----
|
559
|
+
{
|
560
|
+
"generator": {
|
561
|
+
"label": "Milestoner",
|
562
|
+
"version": "19.0.0"
|
563
|
+
},
|
564
|
+
"latest": "1.0.0",
|
565
|
+
"versions": [
|
566
|
+
"0.0.1",
|
567
|
+
"0.1.0",
|
568
|
+
"1.0.0"
|
569
|
+
]
|
570
|
+
}
|
571
|
+
----
|
572
|
+
|
573
|
+
The above breaks down as follows:
|
574
|
+
|
575
|
+
* `generator`: Captures generator details at time of manifest creation.
|
576
|
+
* `latest`: The most recent version built.
|
577
|
+
* `versions`: The array of versions built based on max build settings.
|
578
|
+
|
579
|
+
The manifest allows you to capture build details which can be useful when needing to compare differences between a previous and current build. For convience, you can use the `Milestoner::Tags::Manifest` class to manage manifests. Example:
|
580
|
+
|
581
|
+
[source,ruby]
|
582
|
+
----
|
583
|
+
manifest = Milestoner::Tags::Manifest.new
|
584
|
+
latest_path = Pathname "$HOME/Engineering/OSS/demo/tmp/milestones/latest.json"
|
585
|
+
|
586
|
+
manifest.write generator: {label: "Milestoner", version: "19.0.0"},
|
587
|
+
latest: "0.0.1",
|
588
|
+
versions: %w[0.0.0 0.0.1]
|
589
|
+
# $HOME/Engineering/OSS/demo/tmp/milestones/manifest.json
|
590
|
+
|
591
|
+
manifest.write latest_path,
|
592
|
+
generator: {label: "Milestoner", version: "19.0.0"},
|
593
|
+
latest: "0.0.2",
|
594
|
+
versions: %w[0.0.0 0.0.1 0.0.2]
|
595
|
+
# $HOME/Engineering/OSS/demo/tmp/milestones/latest.json
|
596
|
+
|
597
|
+
manifest.read
|
598
|
+
# {
|
599
|
+
# :generator => {
|
600
|
+
# :label => "Milestoner",
|
601
|
+
# :version => "19.0.0"
|
602
|
+
# },
|
603
|
+
# :latest => "0.0.1",
|
604
|
+
# :versions => [
|
605
|
+
# "0.0.0",
|
606
|
+
# "0.0.1"
|
607
|
+
# ]
|
608
|
+
# }
|
609
|
+
|
610
|
+
manifest.read latest_path
|
611
|
+
# {
|
612
|
+
# :generator => {
|
613
|
+
# :label => "Milestoner",
|
614
|
+
# :version => "19.0.0"
|
615
|
+
# },
|
616
|
+
# :latest => "0.0.2",
|
617
|
+
# :versions => [
|
618
|
+
# "0.0.0",
|
619
|
+
# "0.0.1",
|
620
|
+
# "0.0.2"
|
621
|
+
# ]
|
622
|
+
# }
|
623
|
+
|
624
|
+
manifest.diff latest_path
|
625
|
+
# {
|
626
|
+
# :latest => [
|
627
|
+
# "0.0.2",
|
628
|
+
# "0.0.1"
|
629
|
+
# ],
|
630
|
+
# :versions => [
|
631
|
+
# [
|
632
|
+
# "0.0.0",
|
633
|
+
# "0.0.1",
|
634
|
+
# "0.0.2"
|
635
|
+
# ],
|
636
|
+
# [
|
637
|
+
# "0.0.0",
|
638
|
+
# "0.0.1"
|
639
|
+
# ]
|
640
|
+
# ]
|
641
|
+
# }
|
642
|
+
----
|
643
|
+
|
551
644
|
==== Templates
|
552
645
|
|
553
646
|
Template functionality is powered by {hanami_views_link} which means you can completely customize _all_ build formats, templates, partials, stylesheets, images, and much more.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Builders
|
7
|
+
# Builds JSON manifest.
|
8
|
+
class Manifest
|
9
|
+
include Dry::Monads[:result]
|
10
|
+
include Milestoner::Dependencies[:settings, :git, :logger]
|
11
|
+
|
12
|
+
def initialize(writer: Tags::Manifest.new, path_resolver: PathResolver, **)
|
13
|
+
super(**)
|
14
|
+
@writer = writer
|
15
|
+
@path_resolver = path_resolver
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
return Success writer.build_path unless settings.build_manifest
|
20
|
+
|
21
|
+
git.tags.either -> tags { write tags }, -> message { failure message }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :writer, :path_resolver
|
27
|
+
|
28
|
+
def write tags
|
29
|
+
path_resolver.call writer.build_path, logger: do
|
30
|
+
versions = tags.map(&:version)
|
31
|
+
writer.write latest: versions.last, versions:
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure message
|
36
|
+
logger.error { message }
|
37
|
+
Failure message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -103,7 +103,7 @@ module Milestoner
|
|
103
103
|
|
104
104
|
node.merge id: format(settings.syndication_id, id: version),
|
105
105
|
title: format(settings.syndication_entry_label, id: version),
|
106
|
-
link: format(settings.syndication_entry_uri, id: version),
|
106
|
+
link: format(settings.syndication_entry_uri, id: "#{version}/"),
|
107
107
|
rights: committed_at.strftime("%Y"),
|
108
108
|
published: committed_at,
|
109
109
|
updated: committed_at
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sod"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module CLI
|
7
|
+
module Actions
|
8
|
+
module Build
|
9
|
+
# Handles build manifest.
|
10
|
+
class Manifest < Sod::Action
|
11
|
+
include Dependencies[:settings]
|
12
|
+
|
13
|
+
description "Enable/disable manifest."
|
14
|
+
|
15
|
+
on "--[no-]manifest"
|
16
|
+
|
17
|
+
default { Container[:settings].build_manifest }
|
18
|
+
|
19
|
+
def call(boolean) = settings.build_manifest = boolean
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -8,7 +8,7 @@ module Milestoner
|
|
8
8
|
# Handles the building of different milestone formats.
|
9
9
|
class Build < Sod::Command
|
10
10
|
include Dependencies[:settings, :logger, :io]
|
11
|
-
include Builders::Dependencies[:ascii_doc, :feed, :markdown, :stream, :web]
|
11
|
+
include Builders::Dependencies[:ascii_doc, :feed, :manifest, :markdown, :stream, :web]
|
12
12
|
|
13
13
|
handle "build"
|
14
14
|
|
@@ -19,6 +19,7 @@ module Milestoner
|
|
19
19
|
on Actions::Build::Index
|
20
20
|
on Actions::Build::Label
|
21
21
|
on Actions::Build::Layout
|
22
|
+
on Actions::Build::Manifest
|
22
23
|
on Actions::Build::Max
|
23
24
|
on Actions::Build::Output
|
24
25
|
on Actions::Build::Stylesheet
|
@@ -35,6 +36,8 @@ module Milestoner
|
|
35
36
|
else
|
36
37
|
logger.abort "Invalid build format: #{format}."
|
37
38
|
end
|
39
|
+
|
40
|
+
manifest.call
|
38
41
|
end
|
39
42
|
|
40
43
|
private
|
@@ -14,6 +14,7 @@ module Milestoner
|
|
14
14
|
required(:build_index).filled :bool
|
15
15
|
required(:build_layout) { str? | bool? }
|
16
16
|
required(:build_max).filled :integer
|
17
|
+
required(:build_manifest).filled :bool
|
17
18
|
required(:build_output).filled Etcher::Types::Pathname
|
18
19
|
required(:build_stylesheet).filled :bool
|
19
20
|
required(:build_tail).filled :string
|
@@ -3,23 +3,30 @@
|
|
3
3
|
require "refinements/array"
|
4
4
|
require "refinements/string"
|
5
5
|
|
6
|
-
# Computes duration (in seconds) into human readable days, hours, minutes, and seconds.
|
6
|
+
# Computes duration (in seconds) into human readable years, days, hours, minutes, and seconds.
|
7
7
|
module Milestoner
|
8
8
|
using Refinements::Array
|
9
9
|
using Refinements::String
|
10
10
|
|
11
|
-
DURATION_UNITS = {
|
11
|
+
DURATION_UNITS = {
|
12
|
+
"year" => 31_536_000, # 60 * 60 * 25 * 365
|
13
|
+
"day" => 86_400, # 60 * 60 * 25
|
14
|
+
"hour" => 3_600, # 60 * 60
|
15
|
+
"minute" => 60,
|
16
|
+
"second" => 1
|
17
|
+
}.freeze
|
12
18
|
|
13
19
|
Durationer = lambda do |seconds, units: DURATION_UNITS|
|
14
|
-
|
15
|
-
next unless seconds.positive?
|
20
|
+
return "0 seconds" if seconds.negative? || seconds.zero?
|
16
21
|
|
17
|
-
|
18
|
-
|
22
|
+
result = units.map do |unit, divisor|
|
23
|
+
count, seconds = seconds.divmod divisor
|
19
24
|
|
20
|
-
|
25
|
+
next if count.zero?
|
26
|
+
|
27
|
+
%(#{count} #{unit.pluralize "s", count})
|
21
28
|
end
|
22
29
|
|
23
|
-
result.compact.
|
30
|
+
result.compact.to_sentence
|
24
31
|
end
|
25
32
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "core"
|
4
|
+
require "json"
|
5
|
+
require "refinements/hash"
|
6
|
+
require "refinements/pathname"
|
7
|
+
|
8
|
+
module Milestoner
|
9
|
+
module Tags
|
10
|
+
# Manages build manifest.
|
11
|
+
class Manifest
|
12
|
+
include Dependencies[:settings, :git]
|
13
|
+
|
14
|
+
using Refinements::Hash
|
15
|
+
using Refinements::Pathname
|
16
|
+
|
17
|
+
def initialize(name: "manifest.json", **)
|
18
|
+
super(**)
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_path = settings.build_output.join name
|
23
|
+
|
24
|
+
def diff path = build_path
|
25
|
+
git.tags.value_or(Core::EMPTY_ARRAY).then do |tags|
|
26
|
+
return Core::EMPTY_HASH if tags.empty?
|
27
|
+
|
28
|
+
content_for(tags).diff read(path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def read(path = build_path) = JSON(path.read, {symbolize_names: true})
|
33
|
+
|
34
|
+
def write(path = build_path, **)
|
35
|
+
path.make_ancestors.write JSON.pretty_generate(generator.deep_merge(**))
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :name
|
41
|
+
|
42
|
+
# :reek:FeatureEnvy
|
43
|
+
def content_for tags
|
44
|
+
generator.merge latest: tags.last.version, versions: tags.map(&:version)
|
45
|
+
end
|
46
|
+
|
47
|
+
def generator
|
48
|
+
{generator: {label: settings.generator_label, version: settings.generator_version.to_s}}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<html lang="en">
|
4
4
|
<head>
|
5
|
-
<title><%=
|
5
|
+
<title><%= page_title %></title>
|
6
6
|
|
7
7
|
<meta charset="utf-8">
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
@@ -30,8 +30,8 @@
|
|
30
30
|
href="<%= stylesheet_uri %>.css"
|
31
31
|
type="text/css">
|
32
32
|
|
33
|
-
<script src="https://unpkg.com/alpinejs@3.14.
|
34
|
-
integrity="sha384-
|
33
|
+
<script src="https://unpkg.com/alpinejs@3.14.8"
|
34
|
+
integrity="sha384-X9kJyAubVxnP0hcA+AMMs21U445qsnqhnUF8EBlEpP3a42Kh/JwWjlv2ZcvGfphb"
|
35
35
|
crossorigin="anonymous"
|
36
36
|
defer>
|
37
37
|
</script>
|
@@ -40,6 +40,11 @@
|
|
40
40
|
integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+"
|
41
41
|
crossorigin="anonymous">
|
42
42
|
</script>
|
43
|
+
|
44
|
+
<script src="https://unpkg.com/htmx-select@0.0.0"
|
45
|
+
integrity="sha384-sHXxspXI+1G3Mb+k1zPcNdkBRL2Q+nKLcOtkbUPE0USxJFJtjf5pQpuykwTDAcPc"
|
46
|
+
crossorigin="anonymous">
|
47
|
+
</script>
|
43
48
|
</head>
|
44
49
|
|
45
50
|
<body class="milestoner">
|
@@ -1,14 +1,13 @@
|
|
1
1
|
<details id="<%= commit.sha %>" class="row" x-bind:open="open">
|
2
2
|
<summary class="summary <%= commit.kind %>">
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
</div>
|
3
|
+
<img src="https://alchemists.io/images/projects/milestoner/icons/<%= commit.icon %>.png"
|
4
|
+
alt="<%= commit.kind %>"
|
5
|
+
class="icon"
|
6
|
+
width="24"
|
7
|
+
height="24"
|
8
|
+
loading="lazy">
|
9
|
+
|
10
|
+
<span class="subject"><%= commit.subject %></span>
|
12
11
|
|
13
12
|
<a href="<%= commit.author.profile_url %>" class="author">
|
14
13
|
<%= render :avatar, user: commit.author %>
|
@@ -9,5 +9,5 @@ All versions adhere to the link:https://alchemists.io/articles/strict_semantic_v
|
|
9
9
|
=== History
|
10
10
|
|
11
11
|
<% tags.each do |tag| %>
|
12
|
-
* link
|
12
|
+
* link:/<%= tag.version %>/[<%= tag.version %>] (<%= tag.committed_date %>)
|
13
13
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<section class="milestones">
|
2
2
|
<h1 class="title">
|
3
|
-
<a href="<%= project_uri_home %>" class="label"><%= project_label %></a>
|
3
|
+
<a href="<%= project_uri_home %>" class="label"><%= project_label %></a>
|
4
4
|
</h1>
|
5
5
|
|
6
6
|
<p>All versions adhere to the <a href="https://alchemists.io/articles/strict_semantic_versioning">Strict Semantic Versioning</a> as enforced with <a href="https://alchemists.io/projects/versionaire">Versionaire</a> and automated by <a href="<%= generator_uri %>"><%= generator_label %></a>. Briefly, this means:</p>
|
@@ -11,21 +11,30 @@
|
|
11
11
|
<li><strong>Patch</strong> (x.y.Z): Incremented for small, backwards compatible, bug fixes.</li>
|
12
12
|
</ul>
|
13
13
|
|
14
|
-
<
|
15
|
-
|
16
|
-
<li class="item">
|
17
|
-
<a href="<%= tag.version %>"
|
18
|
-
class="version"
|
19
|
-
hx-get="<%= tag.version %>"
|
20
|
-
hx-select=".milestone"
|
21
|
-
hx-target=".milestones"
|
22
|
-
hx-swap="outerHTML"
|
23
|
-
hx-push-url="true">
|
24
|
-
<%= tag.version %>
|
25
|
-
</a>
|
14
|
+
<div class="selection fragment">
|
15
|
+
<label for="version" class="label">Version:</label>
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
<select id="version"
|
18
|
+
name="version"
|
19
|
+
class="versions"
|
20
|
+
hx-get=""
|
21
|
+
hx-trigger="change"
|
22
|
+
hx-select=".milestone"
|
23
|
+
hx-target=".milestones"
|
24
|
+
hx-swap="outerHTML"
|
25
|
+
hx-push-url="true"
|
26
|
+
hx-indicator=".spinner"
|
27
|
+
hx-ext="select">
|
28
|
+
|
29
|
+
<option value="" class="option">Select...</option>
|
30
|
+
|
31
|
+
<% tags.each do |tag| %>
|
32
|
+
<option value="<%= tag.version %>/" class="option">
|
33
|
+
<%= tag.version %> (<%= tag.committed_date %>)
|
34
|
+
</option>
|
35
|
+
<% end %>
|
36
|
+
</select>
|
37
|
+
|
38
|
+
<div class="spinner htmx-indicator"></div>
|
39
|
+
</div>
|
31
40
|
</section>
|
@@ -9,5 +9,5 @@ All versions adhere to the [Strict Semantic Versioning](https://alchemists.io/ar
|
|
9
9
|
## History
|
10
10
|
|
11
11
|
<% tags.each do |tag| %>
|
12
|
-
- [<%= tag.version %>](
|
12
|
+
- [<%= tag.version %>](/<%= tag.version %>/) (<%= tag.committed_date %>)
|
13
13
|
<% end %>
|
@@ -13,5 +13,5 @@
|
|
13
13
|
*<%= tag.total_commits %>. <%= tag.total_files %>. <%= tag.total_deletions %>. <%= tag.total_insertions %>.* +
|
14
14
|
*<%= tag.total_duration %>.*
|
15
15
|
|
16
|
-
link
|
16
|
+
link:../<%= past.version %>/[Previous (<%= past.version %>)] | link:../<%= future.version %>/[Next (<%= future.version %>)]
|
17
17
|
<% end %>
|
@@ -1,16 +1,21 @@
|
|
1
1
|
<article class="milestone">
|
2
2
|
<header class="header">
|
3
3
|
<% if tag.index? %>
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
<div class="fragment">
|
5
|
+
<a href="../"
|
6
|
+
class="root"
|
7
|
+
hx-get="../"
|
8
|
+
hx-select=".milestones"
|
9
|
+
hx-trigger="click, keyup[key=='v'] from:body"
|
10
|
+
hx-target=".milestone"
|
11
|
+
hx-swap="outerHTML"
|
12
|
+
hx-push-url="true"
|
13
|
+
hx-indicator=".index">
|
14
|
+
Versions
|
15
|
+
</a>
|
16
|
+
|
17
|
+
<div class="index spinner htmx-indicator"></div>
|
18
|
+
</div>
|
14
19
|
<% end %>
|
15
20
|
|
16
21
|
<h1 class="title">
|
@@ -71,19 +76,22 @@
|
|
71
76
|
</p>
|
72
77
|
|
73
78
|
<ul class="actions">
|
74
|
-
<li>
|
75
|
-
<a href="
|
79
|
+
<li class="fragment">
|
80
|
+
<a href="../<%= past.version %>/"
|
76
81
|
class="action"
|
77
82
|
data-direction="previous"
|
78
|
-
hx-get="
|
83
|
+
hx-get="../<%= past.version %>/"
|
79
84
|
hx-select=".milestone"
|
80
85
|
hx-trigger="click, keyup[key=='ArrowLeft'] from:body"
|
81
86
|
hx-target=".milestone"
|
82
87
|
hx-swap="outerHTML"
|
83
|
-
hx-push-url="true"
|
88
|
+
hx-push-url="true"
|
89
|
+
hx-indicator=".previous">
|
84
90
|
Previous
|
85
91
|
(<%= past.version %>)
|
86
92
|
</a>
|
93
|
+
|
94
|
+
<div class="previous spinner htmx-indicator"></div>
|
87
95
|
</li>
|
88
96
|
|
89
97
|
<li>
|
@@ -100,16 +108,19 @@
|
|
100
108
|
</div>
|
101
109
|
</li>
|
102
110
|
|
103
|
-
<li>
|
104
|
-
<
|
111
|
+
<li class="fragment">
|
112
|
+
<div class="next spinner htmx-indicator"></div>
|
113
|
+
|
114
|
+
<a href="../<%= future.version %>/"
|
105
115
|
class="action"
|
106
116
|
data-direction="next"
|
107
|
-
hx-get="
|
117
|
+
hx-get="../<%= future.version %>/"
|
108
118
|
hx-select=".milestone"
|
109
119
|
hx-trigger="click, keyup[key=='ArrowRight'] from:body"
|
110
120
|
hx-target=".milestone"
|
111
121
|
hx-swap="outerHTML"
|
112
|
-
hx-push-url="true"
|
122
|
+
hx-push-url="true"
|
123
|
+
hx-indicator=".next">
|
113
124
|
Next
|
114
125
|
(<%= future.version %>)
|
115
126
|
</a>
|
@@ -12,5 +12,5 @@
|
|
12
12
|
**<%= tag.total_commits %>. <%= tag.total_files %>. <%= tag.total_deletions %>. <%= tag.total_insertions %>.**
|
13
13
|
**<%= tag.total_duration %>.**
|
14
14
|
|
15
|
-
[Previous (<%= past.version %>)](
|
15
|
+
[Previous (<%= past.version %>)](../<%= past.version %>/) | [Next (<%= future.version %>)](../<%= future.version %>/)
|
16
16
|
<% end %>
|
@@ -1,3 +1,8 @@
|
|
1
|
+
@keyframes spin {
|
2
|
+
0% { transform: rotate(0deg); }
|
3
|
+
100% { transform: rotate(360deg); }
|
4
|
+
}
|
5
|
+
|
1
6
|
/* Rouge (https://rouge.jneen.net) */
|
2
7
|
.rouge.highlight {
|
3
8
|
--color-berry: hsl(240, 18%, 40%);
|
@@ -479,6 +484,21 @@
|
|
479
484
|
}
|
480
485
|
}
|
481
486
|
|
487
|
+
.spinner {
|
488
|
+
animation: spin 1.5s linear infinite;
|
489
|
+
border-radius: 50%;
|
490
|
+
border: 0.3rem solid var(--color-grey);
|
491
|
+
border-top: 0.3rem solid var(--color-green);
|
492
|
+
height: 1rem;
|
493
|
+
width: 1rem;
|
494
|
+
}
|
495
|
+
|
496
|
+
.fragment {
|
497
|
+
align-items: center;
|
498
|
+
display: flex;
|
499
|
+
gap: 0.5rem;
|
500
|
+
}
|
501
|
+
|
482
502
|
.toggle {
|
483
503
|
background-color: var(--color-white);
|
484
504
|
border: 0.15rem solid var(--color-smoke);
|
@@ -500,24 +520,20 @@
|
|
500
520
|
flex-direction: column;
|
501
521
|
margin: 0 12vw;
|
502
522
|
|
503
|
-
.
|
504
|
-
|
505
|
-
|
506
|
-
border-radius: 0.5rem;
|
507
|
-
display: flex;
|
508
|
-
gap: 0.5rem;
|
509
|
-
flex-direction: column;
|
510
|
-
margin: 1rem 0;
|
511
|
-
padding: 1rem;
|
523
|
+
.label {
|
524
|
+
font-weight: 600;
|
525
|
+
}
|
512
526
|
|
513
|
-
|
514
|
-
|
515
|
-
justify-content: space-between;
|
516
|
-
}
|
527
|
+
.selection {
|
528
|
+
margin: 1rem 0 0.5rem 0;
|
517
529
|
}
|
518
530
|
|
519
|
-
.
|
520
|
-
color: var(--color-
|
531
|
+
.versions {
|
532
|
+
background-color: var(--color-ice);
|
533
|
+
border-radius: 0.5rem;
|
534
|
+
border: 0.15rem solid var(--color-black);
|
535
|
+
font-size: 1rem;
|
536
|
+
padding: 0.2rem 0.5rem;
|
521
537
|
}
|
522
538
|
}
|
523
539
|
|
@@ -551,21 +567,6 @@
|
|
551
567
|
color: var(--color-white);
|
552
568
|
}
|
553
569
|
|
554
|
-
.columns {
|
555
|
-
background-color: var(--color-black);
|
556
|
-
border-top-left-radius: 0.5rem;
|
557
|
-
border-top-right-radius: 0.5rem;
|
558
|
-
color: var(--color-white);
|
559
|
-
display: grid;
|
560
|
-
grid-template: 1fr / 4.7fr 1fr 1fr 1fr 1fr 1fr;
|
561
|
-
padding: 0.3rem 0;
|
562
|
-
|
563
|
-
.label {
|
564
|
-
font-weight: 600;
|
565
|
-
text-align: center;
|
566
|
-
}
|
567
|
-
}
|
568
|
-
|
569
570
|
.header {
|
570
571
|
align-items: center;
|
571
572
|
display: grid;
|
@@ -633,6 +634,27 @@
|
|
633
634
|
}
|
634
635
|
}
|
635
636
|
|
637
|
+
.columns {
|
638
|
+
background-color: var(--color-black);
|
639
|
+
border-top-left-radius: 0.5rem;
|
640
|
+
border-top-right-radius: 0.5rem;
|
641
|
+
color: var(--color-white);
|
642
|
+
display: none;
|
643
|
+
padding: 0.3rem 0;
|
644
|
+
|
645
|
+
@media (width >= 700px) {
|
646
|
+
display: grid;
|
647
|
+
grid-template: 1fr / 4.7fr repeat(5, 1fr);
|
648
|
+
}
|
649
|
+
|
650
|
+
.label {
|
651
|
+
font-weight: 600;
|
652
|
+
overflow: hidden;
|
653
|
+
texdt-overflow: ellipsis;
|
654
|
+
text-align: center;
|
655
|
+
}
|
656
|
+
}
|
657
|
+
|
636
658
|
.row {
|
637
659
|
.label {
|
638
660
|
font-weight: 600;
|
@@ -646,20 +668,25 @@
|
|
646
668
|
|
647
669
|
.summary {
|
648
670
|
align-items: center;
|
671
|
+
border-radius: 0.5rem;
|
649
672
|
display: grid;
|
650
673
|
gap: 0 1rem;
|
651
|
-
grid-template: 1fr / auto
|
674
|
+
grid-template: 1fr 1fr / auto auto auto repeat(5, 1fr);
|
675
|
+
grid-template-areas:
|
676
|
+
"toggle icon subject subject subject subject subject subject"
|
677
|
+
"toggle icon author files lines issue review review";
|
652
678
|
padding: 0.15rem 0;
|
653
679
|
margin: 0.25rem 0 0 0;
|
654
680
|
|
655
681
|
&::-webkit-details-marker {
|
656
|
-
display:none;
|
682
|
+
display: none;
|
657
683
|
}
|
658
684
|
|
659
685
|
&::before {
|
660
686
|
color: var(--color-carbon);
|
661
|
-
content: "\25B6";
|
687
|
+
content: "\25B6\FE0E";
|
662
688
|
cursor: pointer;
|
689
|
+
grid-area: toggle;
|
663
690
|
width: 0.5rem;
|
664
691
|
}
|
665
692
|
|
@@ -688,10 +715,25 @@
|
|
688
715
|
border-radius: 0.5rem;
|
689
716
|
}
|
690
717
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
718
|
+
@media (width >= 700px) {
|
719
|
+
grid-template: 1fr / auto auto 5fr repeat(5, 1fr);
|
720
|
+
grid-template-areas: "toggle icon subject author files lines issue review";
|
721
|
+
}
|
722
|
+
|
723
|
+
.icon {
|
724
|
+
grid-area: icon;
|
725
|
+
}
|
726
|
+
|
727
|
+
.subject {
|
728
|
+
grid-area: subject;
|
729
|
+
}
|
730
|
+
|
731
|
+
.author {
|
732
|
+
grid-area: author;
|
733
|
+
}
|
734
|
+
|
735
|
+
.files {
|
736
|
+
grid-area: files;
|
695
737
|
}
|
696
738
|
|
697
739
|
.author,
|
@@ -707,6 +749,13 @@
|
|
707
749
|
}
|
708
750
|
|
709
751
|
.lines {
|
752
|
+
grid-area: lines;
|
753
|
+
white-space: nowrap;
|
754
|
+
|
755
|
+
@media (width >= 700px) {
|
756
|
+
white-space: normal;
|
757
|
+
}
|
758
|
+
|
710
759
|
.deletions {
|
711
760
|
color: var(--color-green);
|
712
761
|
}
|
@@ -715,6 +764,14 @@
|
|
715
764
|
color: var(--color-red);
|
716
765
|
}
|
717
766
|
}
|
767
|
+
|
768
|
+
.issue {
|
769
|
+
grid-area: issue;
|
770
|
+
}
|
771
|
+
|
772
|
+
.review {
|
773
|
+
grid-area: review;
|
774
|
+
}
|
718
775
|
}
|
719
776
|
|
720
777
|
.details {
|
@@ -734,7 +791,6 @@
|
|
734
791
|
}
|
735
792
|
|
736
793
|
.tag {
|
737
|
-
align-self: stretch;
|
738
794
|
border-radius: 0.3rem;
|
739
795
|
grid-area: tag;
|
740
796
|
margin: 1rem 0;
|
@@ -832,6 +888,7 @@
|
|
832
888
|
}
|
833
889
|
|
834
890
|
.line {
|
891
|
+
align-items: center;
|
835
892
|
align-self: start;
|
836
893
|
display: flex;
|
837
894
|
gap: 0.5rem;
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "core"
|
4
4
|
require "forwardable"
|
5
5
|
require "hanami/view"
|
6
|
+
require "refinements/array"
|
6
7
|
|
7
8
|
module Milestoner
|
8
9
|
module Views
|
@@ -12,11 +13,15 @@ module Milestoner
|
|
12
13
|
|
13
14
|
include Dependencies[:settings]
|
14
15
|
|
16
|
+
using Refinements::Array
|
17
|
+
|
15
18
|
delegate %i[
|
16
19
|
build_stylesheet
|
17
20
|
generator_label
|
18
21
|
generator_uri
|
19
22
|
generator_version
|
23
|
+
organization_label
|
24
|
+
organization_uri
|
20
25
|
project_author
|
21
26
|
project_description
|
22
27
|
project_label
|
@@ -29,6 +34,10 @@ module Milestoner
|
|
29
34
|
stylesheet_uri
|
30
35
|
] => :settings
|
31
36
|
|
37
|
+
def page_title delimiter: " | "
|
38
|
+
[project_title, organization_label].compress.join delimiter
|
39
|
+
end
|
40
|
+
|
32
41
|
def project_slug
|
33
42
|
[project_name, project_version].compact.join("_").tr ".", Core::EMPTY_STRING
|
34
43
|
end
|
data/milestoner.gemspec
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: milestoner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 19.
|
4
|
+
version: 19.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
34
34
|
3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
|
35
35
|
gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date: 2025-
|
37
|
+
date: 2025-02-20 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: asciidoctor
|
@@ -379,6 +379,7 @@ files:
|
|
379
379
|
- lib/milestoner/builders/container.rb
|
380
380
|
- lib/milestoner/builders/dependencies.rb
|
381
381
|
- lib/milestoner/builders/feed.rb
|
382
|
+
- lib/milestoner/builders/manifest.rb
|
382
383
|
- lib/milestoner/builders/markdown.rb
|
383
384
|
- lib/milestoner/builders/md/container.rb
|
384
385
|
- lib/milestoner/builders/md/dependencies.rb
|
@@ -401,6 +402,7 @@ files:
|
|
401
402
|
- lib/milestoner/cli/actions/build/index.rb
|
402
403
|
- lib/milestoner/cli/actions/build/label.rb
|
403
404
|
- lib/milestoner/cli/actions/build/layout.rb
|
405
|
+
- lib/milestoner/cli/actions/build/manifest.rb
|
404
406
|
- lib/milestoner/cli/actions/build/max.rb
|
405
407
|
- lib/milestoner/cli/actions/build/output.rb
|
406
408
|
- lib/milestoner/cli/actions/build/stylesheet.rb
|
@@ -464,6 +466,7 @@ files:
|
|
464
466
|
- lib/milestoner/tags/builder.rb
|
465
467
|
- lib/milestoner/tags/creator.rb
|
466
468
|
- lib/milestoner/tags/enricher.rb
|
469
|
+
- lib/milestoner/tags/manifest.rb
|
467
470
|
- lib/milestoner/tags/publisher.rb
|
468
471
|
- lib/milestoner/tags/pusher.rb
|
469
472
|
- lib/milestoner/templates/layouts/page.adoc.erb
|
@@ -552,7 +555,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
552
555
|
- !ruby/object:Gem::Version
|
553
556
|
version: '0'
|
554
557
|
requirements: []
|
555
|
-
rubygems_version: 3.6.
|
558
|
+
rubygems_version: 3.6.4
|
556
559
|
specification_version: 4
|
557
560
|
summary: A command line interface for automated Git repository milestones.
|
558
561
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|