milestoner 16.2.1 → 17.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +1 -1
- data/README.adoc +274 -47
- data/lib/milestoner/builders/container.rb +15 -0
- data/lib/milestoner/builders/import.rb +9 -0
- data/lib/milestoner/builders/stream.rb +29 -0
- data/lib/milestoner/builders/web.rb +41 -0
- data/lib/milestoner/cli/actions/build/format.rb +24 -0
- data/lib/milestoner/cli/actions/build/label.rb +26 -0
- data/lib/milestoner/cli/actions/build/layout.rb +36 -0
- data/lib/milestoner/cli/actions/build/root.rb +25 -0
- data/lib/milestoner/cli/actions/build/version.rb +31 -0
- data/lib/milestoner/cli/actions/cache/create.rb +35 -0
- data/lib/milestoner/cli/actions/cache/delete.rb +34 -0
- data/lib/milestoner/cli/actions/cache/find.rb +34 -0
- data/lib/milestoner/cli/actions/cache/info.rb +29 -0
- data/lib/milestoner/cli/actions/cache/list.rb +33 -0
- data/lib/milestoner/cli/actions/publish.rb +9 -5
- data/lib/milestoner/cli/commands/build.rb +55 -0
- data/lib/milestoner/cli/commands/cache.rb +27 -0
- data/lib/milestoner/cli/shell.rb +3 -2
- data/lib/milestoner/commits/categorizer.rb +21 -29
- data/lib/milestoner/commits/collector.rb +18 -0
- data/lib/milestoner/commits/enricher.rb +52 -0
- data/lib/milestoner/commits/enrichers/author.rb +26 -0
- data/lib/milestoner/commits/enrichers/body.rb +28 -0
- data/lib/milestoner/commits/enrichers/colleague.rb +33 -0
- data/lib/milestoner/commits/enrichers/container.rb +25 -0
- data/lib/milestoner/commits/enrichers/format.rb +23 -0
- data/lib/milestoner/commits/enrichers/import.rb +11 -0
- data/lib/milestoner/commits/enrichers/issue.rb +28 -0
- data/lib/milestoner/commits/enrichers/milestone.rb +24 -0
- data/lib/milestoner/commits/enrichers/note.rb +28 -0
- data/lib/milestoner/commits/enrichers/review.rb +23 -0
- data/lib/milestoner/commits/enrichers/uri.rb +14 -0
- data/lib/milestoner/commits/versioner.rb +48 -0
- data/lib/milestoner/configuration/contract.rb +29 -3
- data/lib/milestoner/configuration/defaults.yml +31 -8
- data/lib/milestoner/configuration/model.rb +24 -1
- data/lib/milestoner/configuration/transformers/build/root.rb +21 -0
- data/lib/milestoner/configuration/transformers/build/template_paths.rb +35 -0
- data/lib/milestoner/configuration/transformers/citations/description.rb +37 -0
- data/lib/milestoner/configuration/transformers/citations/label.rb +37 -0
- data/lib/milestoner/configuration/transformers/gems/description.rb +36 -0
- data/lib/milestoner/configuration/transformers/gems/label.rb +36 -0
- data/lib/milestoner/configuration/transformers/gems/name.rb +36 -0
- data/lib/milestoner/configuration/transformers/gems/uri.rb +36 -0
- data/lib/milestoner/configuration/transformers/project/author.rb +33 -0
- data/lib/milestoner/configuration/transformers/project/generator.rb +28 -0
- data/lib/milestoner/configuration/transformers/project/label.rb +23 -0
- data/lib/milestoner/configuration/transformers/project/name.rb +19 -0
- data/lib/milestoner/configuration/transformers/project/version.rb +31 -0
- data/lib/milestoner/configuration/transformers/uri/avatar.rb +21 -0
- data/lib/milestoner/configuration/transformers/uri/commit.rb +24 -0
- data/lib/milestoner/configuration/transformers/uri/profile.rb +21 -0
- data/lib/milestoner/configuration/transformers/uri/review.rb +24 -0
- data/lib/milestoner/configuration/transformers/uri/tracker.rb +24 -0
- data/lib/milestoner/container.rb +51 -9
- data/lib/milestoner/models/commit.rb +42 -0
- data/lib/milestoner/models/link.rb +12 -0
- data/lib/milestoner/models/user.rb +12 -0
- data/lib/milestoner/renderers/asciidoc.rb +20 -0
- data/lib/milestoner/renderers/markdown.rb +20 -0
- data/lib/milestoner/renderers/universal.rb +26 -0
- data/lib/milestoner/tags/creator.rb +31 -23
- data/lib/milestoner/tags/publisher.rb +5 -5
- data/lib/milestoner/tags/pusher.rb +9 -3
- data/lib/milestoner/templates/layouts/page.html.erb +29 -0
- data/lib/milestoner/templates/layouts/page.stream.erb +1 -0
- data/lib/milestoner/templates/milestones/_avatar.html.erb +5 -0
- data/lib/milestoner/templates/milestones/_commit.html.erb +104 -0
- data/lib/milestoner/templates/milestones/_commit.stream.erb +1 -0
- data/lib/milestoner/templates/milestones/_icon.html.erb +6 -0
- data/lib/milestoner/templates/milestones/_profile.html.erb +5 -0
- data/lib/milestoner/templates/milestones/show.html.erb +46 -0
- data/lib/milestoner/templates/milestones/show.stream.erb +5 -0
- data/lib/milestoner/templates/public/page.css.erb +356 -0
- data/lib/milestoner/views/context.rb +25 -0
- data/lib/milestoner/views/milestones/show.rb +46 -0
- data/lib/milestoner/views/parts/commit.rb +85 -0
- data/lib/milestoner.rb +1 -1
- data/milestoner.gemspec +17 -11
- data.tar.gz.sig +0 -0
- metadata +172 -26
- metadata.gz.sig +0 -0
- data/lib/milestoner/cli/actions/status.rb +0 -37
- data/lib/milestoner/presenters/commit.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62c3705bded27a22253cc186854ca6f39a73aa441fa5ff065ea76c23250e0e5d
|
4
|
+
data.tar.gz: 187d16fc088ae2f84774f77ba3bfb35b3875481f127c73dd1ac66b082332a814
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd2db5bbb280f82e2cc40530e183cc2e822d8df0e5ce3260893606a25b3ca5ba37cc5a016d11ecc26d0f2e306eb0f1f56bc6996cfdc990719dc4ddcca3b7fb22
|
7
|
+
data.tar.gz: 99d0e185f7861d29bfb701b229a248298a361848bbabbc4c6e43adb96376c3051370eb8546887a134e18eaefa25573455edede1f9d0c0bf519660cea8a2f7740
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
���/��B�iF<�/X�Co.��+��t囑��#U}5��KzSYO��������xD��y���BH�?�NZc���sk�*����\���`�W30GS��T��As@^C�N��~����ra�&7��`(Ĩ�(�j����Wv��%�I|&%Q�s�R�H( �
|
data/README.adoc
CHANGED
@@ -2,40 +2,58 @@
|
|
2
2
|
:toclevels: 5
|
3
3
|
:figure-caption!:
|
4
4
|
|
5
|
+
:asciidoc_link: link:https://asciidoctor.org/docs/what-is-asciidoc[ASCII Doc]
|
6
|
+
:cff_link: link:https://github.com/citation-file-format/ruby-cff[CFF]
|
7
|
+
:etcher_link: link:https://alchemists.io/projects/etcher[Etcher]
|
8
|
+
:gem_specification_link: link:https://guides.rubygems.org/specification-reference/[Gem Specification]
|
9
|
+
:git_commit_anatomy_link: link:https://alchemists.io/articles/git_commit_anatomy[Git Commit Anatomy]
|
10
|
+
:git_lint_link: link:https://alchemists.io/projects/git-lint[Git Lint]
|
11
|
+
:hanami_views_link: link:https://alchemists.io/articles/hanami_views[Hanami Views]
|
12
|
+
:lode_link: link:https://alchemists.io/projects/lode[Lode]
|
13
|
+
:markdown_link: link:https://daringfireball.net/projects/markdown[Markdown]
|
14
|
+
:runcom_link: link:https://alchemists.io/projects/runcom[Runcom]
|
15
|
+
:string_formats_link: link:https://ruby-doc.org/3.3.0/format_specifications_rdoc.html[String Formats]
|
16
|
+
:versionaire_link: link:https://alchemists.io/projects/versionaire[Versionaire]
|
17
|
+
:xdg_link: link:https://alchemists.io/projects/xdg[XDG]
|
18
|
+
|
5
19
|
= Milestoner
|
6
20
|
|
7
|
-
Milestoner is a
|
8
|
-
link:https://semver.org[semantic versions]. Each milestone is a summary of all commits made since
|
9
|
-
the last milestone. You can use Milestoner to inspect what is currently pending or create a new
|
10
|
-
release via a single command. By having a tool, like Milestoner, you can automate releases in a
|
11
|
-
consistent and reliable fashion. Milestoner pairs well with the following gems:
|
21
|
+
Milestoner is a Command Line Interface (CLI) for automating software deployments complete with feature rich release notes that celebrate the team members who worked on the version release. This includes the automation of Git repository tags (milestones) using link:https://semver.org[semantic versions]. Each milestone is a summary of all commits made since the last milestone. You can use Milestoner to inspect what is currently pending or create a new release via a single command. By having a tool, like Milestoner, you can automate releases in a consistent and reliable fashion. Milestoner pairs well with the following gems:
|
12
22
|
|
13
23
|
- link:https://alchemists.io/projects/git-lint[Git Lint] - Ensures your commit messages are of
|
14
|
-
high quality
|
15
|
-
- link:https://alchemists.io/projects/rubysmith[Rubysmith] -
|
16
|
-
|
17
|
-
- link:https://alchemists.io/projects/gemsmith[Gemsmith] - Is built on top of Milestoner and is
|
18
|
-
used to publish new Ruby gem versions.
|
24
|
+
high quality for release note purposes.
|
25
|
+
- link:https://alchemists.io/projects/rubysmith[Rubysmith] - Automates the publishing of new or existing Ruby project versions.
|
26
|
+
- link:https://alchemists.io/projects/gemsmith[Gemsmith] - Automates the publishing of new or existing Ruby gem versions.
|
19
27
|
|
20
28
|
toc::[]
|
21
29
|
|
30
|
+
== Screenshots
|
31
|
+
|
32
|
+
*Web Format* (i.e. `milestoner build --format web`)
|
33
|
+
|
34
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-collapsed.png[Usage,width=1011,height=345,role=focal_point]
|
35
|
+
|
36
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-expanded.png[Usage,width=1005,height=643,role=focal_point]
|
37
|
+
|
38
|
+
*Stream Format* (i.e. `milestoner build --format stream`)
|
39
|
+
|
40
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-stream.png[Usage,width=464,height=245,role=focal_point]
|
41
|
+
|
22
42
|
== Features
|
23
43
|
|
24
44
|
* Uses link:https://alchemists.io/projects/versionaire[Versionaire] for
|
25
45
|
link:https://semver.org[Semantic Versioning].
|
26
46
|
** Format: `+<major>.<minor>.<patch>+`.
|
27
|
-
** Example:
|
28
|
-
* Ensures Git commits since last tag (or initialization of repository) are included.
|
29
|
-
* Ensures Git commit messages are grouped by prefix, in order defined. For more details, see
|
30
|
-
|
31
|
-
|
32
|
-
**
|
33
|
-
**
|
34
|
-
**
|
35
|
-
|
36
|
-
|
37
|
-
* Ensures Git commit messages are alphabetically sorted.
|
38
|
-
* Ensures duplicate Git commit messages are removed (if any).
|
47
|
+
** Example: `0.0.0`.
|
48
|
+
* Ensures Git commits since last tag (or initialization of repository) are included in the release notes.
|
49
|
+
* Ensures Git commit messages are grouped by prefix, in order defined, for categorization. For more details, see link:https://alchemists.io/projects/git-lint/#_commit_subject_prefix[Git Lint Commit Subject Prefix]. Defaults (can be customized):
|
50
|
+
** image:https://alchemists.io/images/projects/milestoner/icons/commits/fixed.png[Fixed] Fixed
|
51
|
+
** image:https://alchemists.io/images/projects/milestoner/icons/commits/added.png[Added] Added
|
52
|
+
** image:https://alchemists.io/images/projects/milestoner/icons/commits/updated.png[Updated] Updated
|
53
|
+
** image:https://alchemists.io/images/projects/milestoner/icons/commits/removed.png[Removed] Removed
|
54
|
+
** image:https://alchemists.io/images/projects/milestoner/icons/commits/refactored.png[Refactored] Refactored
|
55
|
+
* Ensures Git commit messages are alphabetically sorted for release note categorization and readability.
|
56
|
+
* Provides automatic versioning based on last Git tag and current Git commit trailers. See {git_commit_anatomy_link} for details.
|
39
57
|
|
40
58
|
== Requirements
|
41
59
|
|
@@ -67,7 +85,7 @@ gem install milestoner
|
|
67
85
|
|
68
86
|
From the command line, type: `milestoner --help`
|
69
87
|
|
70
|
-
image:https://alchemists.io/images/projects/milestoner/screenshots/usage.png[Usage,width=
|
88
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/usage.png[Usage,width=690,height=398,role=focal_point]
|
71
89
|
|
72
90
|
=== Customization
|
73
91
|
|
@@ -77,34 +95,243 @@ This gem can be configured via a global configuration:
|
|
77
95
|
~/.config/milestoner/configuration.yml
|
78
96
|
....
|
79
97
|
|
80
|
-
It can also be configured via
|
98
|
+
It can also be configured via {xdg_link} environment variables.
|
81
99
|
|
82
|
-
The default configuration is
|
100
|
+
The default configuration is:
|
83
101
|
|
84
102
|
[source,yaml]
|
85
103
|
----
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
avatar:
|
105
|
+
domain: https://avatars.githubusercontent.com
|
106
|
+
uri: "%<domain>s/u/%<id>s"
|
107
|
+
build:
|
108
|
+
format: web
|
109
|
+
layout: page
|
110
|
+
root: tmp/milestone
|
111
|
+
commit:
|
112
|
+
categories:
|
113
|
+
- emoji: ✅
|
114
|
+
label: Fixed
|
115
|
+
- emoji: 🟢
|
116
|
+
label: Added
|
117
|
+
- emoji: 🔼
|
118
|
+
label: Updated
|
119
|
+
- emoji: ⛔️
|
120
|
+
label: Removed
|
121
|
+
- emoji: 🔁
|
122
|
+
label: Refactored
|
123
|
+
domain: https://github.com
|
124
|
+
format: asciidoc
|
125
|
+
uri: "%<domain>s/%<owner>s/%<name>s/commit/%<id>s"
|
126
|
+
profile:
|
127
|
+
domain: https://github.com
|
128
|
+
uri: "%<domain>s/%<id>s"
|
129
|
+
project:
|
130
|
+
author:
|
131
|
+
description:
|
132
|
+
generator:
|
133
|
+
label:
|
134
|
+
name:
|
135
|
+
owner:
|
136
|
+
uri:
|
137
|
+
version:
|
138
|
+
review:
|
139
|
+
domain: https://github.com
|
140
|
+
uri: "%<domain>s/%<owner>s/%<name>s/pulls/%<id>s"
|
141
|
+
tracker:
|
142
|
+
domain: https://github.com
|
143
|
+
uri: "%<domain>s/%<owner>s/%<name>s/issues/%<id>s"
|
144
|
+
----
|
145
|
+
|
146
|
+
The above can be customized as follows:
|
147
|
+
|
148
|
+
* `avatar`: Manages team member avatar information.
|
149
|
+
** `domain`: The domain of your team member avatars.
|
150
|
+
** `uri`: The URI format for linking to avatars as formatted using {string_formats_link}. The `id` is dynamically calculated via the `external_id` of the user stored in the {lode_link} cache.
|
151
|
+
* `build`: Manages release note builds.
|
152
|
+
** `format`: The build output format. Multiple formats are supported.
|
153
|
+
** `layout`: The layout used by {hanami_views_link} when building release notes.
|
154
|
+
** `root`: The output location. This can be a relative or absolute path.
|
155
|
+
* `commit`: Manages commit categories, emojis, and hyperlinks.
|
156
|
+
** `categories`: By default, only five categories are supported which pairs well with the {git_lint_link} gem. Category order is important with the first taking precedence over the second and so forth. Special characters are allowed for prefixes but should be enclosed in quotes. To disable categories, use an empty array. Example: `categories: []`.
|
157
|
+
*** `emoji`: The emoji associated with the label for output purposes. _Only used by the stream build format_.
|
158
|
+
*** `label`: Allows you to customize the category label. All commits are grouped by label which equates to the prefix, or first word, used in each commit message. The defaults pair well with the {git_lint_link} gem.
|
159
|
+
** `domain`: The Git repository domain for all commits.
|
160
|
+
** `format`: Defines the default format used for rendering commit messages unless specified in the commit trailer metadata which takes higher precedence. Defaults to {asciidoc_link} but {markdown_link} is also supported.
|
161
|
+
** `uri`: The URI format for linking to commits as formatted using {string_formats_link}. The `id` is dynamically calculated via the commit SHA of each commit analyzed at runtime.
|
162
|
+
* `profile`: Manages team member profile information.
|
163
|
+
** `domain`: The domain of your Git repository.
|
164
|
+
** `uri`: The URI format for linking to profiles as formatted using {string_formats_link}. The `id` is dynamically calculated via the `handle` of the user stored in the {lode_link} cache.
|
165
|
+
* `project`: Manages project information.
|
166
|
+
** `author`: Optional. The project author. Dynamically calculated by the {etcher_link} gem in the following order: Git configuration user name or this value.
|
167
|
+
** `description`: Optional. The project description. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} summary, {cff_link} abstract, or this value.
|
168
|
+
** `generator`: Optional. The project generator (i.e. this gem).
|
169
|
+
** `label`: Optional. The project label. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} metadata label, {cff_link} title, or this value.
|
170
|
+
** `name`: Optional. The project name. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} name or this value.
|
171
|
+
** `owner`: Required. The project owner. This would be your source code organization or user handle. This is used when formatting URL information (mentioned above).
|
172
|
+
** `uri`: Optional. The project URI. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} homepage or this value.
|
173
|
+
** `version`: Optional. The project version. Dynamically calculated based on the last Git tag of your project and Git `Milestone` commit trailer metadata. Otherwise, defaults to: `0.0.0`. For more on this see, the _Automatic Versioning_ section below.
|
174
|
+
* `review`: Manages code review information.
|
175
|
+
** `domain`: The domain of your code review service.
|
176
|
+
** `uri`: The URI format for linking to code reviews as formatted using {string_formats_link}. The `id` is currently a _placeholder_ for future feature support when API support is added. For now this links to _all_ code reviews with the goal to link to individual code reviews based on issue tracker metadata from Git commit trailers.
|
177
|
+
* `tracker`: Allows you to customize the issue tracker service you are using.
|
178
|
+
** `domain`: The domain of your issue tracker service.
|
179
|
+
** `uri`: The URI format for linking to issues as formatted using {string_formats_link}. The `id` is dynamically calculated via the commit `Issue` trailer as linted by {git_lint_link}.
|
180
|
+
|
181
|
+
💡 If you ever need to know what your currrent configuration looks like you can jump into your applications IRB console and inspect `Milestoner::Container[:configuration]` to see full details.
|
182
|
+
|
183
|
+
=== Config
|
184
|
+
|
185
|
+
Milestoner can be configured via the command line using: `milestoner config`. Using this command will allow you to create, edit, view, and/or delete your global or local configuration as desired. The configuration is managed by the {runcom_link} gem which is built atop the {xdg_link} gem for managing global or local configurations. Please read the documentation of each gem to learn more.
|
186
|
+
|
187
|
+
=== Cache
|
188
|
+
|
189
|
+
Milestoner's cache allows you to enrich user information (i.e. authors, collaborators, etc) by storing information in a `PStore` database as managed by the {lode_link} gem. Cache location, as with the Config, is managed by the {runcom_link} gem.
|
190
|
+
|
191
|
+
User information should be sourced from whatever service you use for managing your source code. For example, when using GitHub, your workflow might look like this:
|
192
|
+
|
193
|
+
[source,bash]
|
194
|
+
----
|
195
|
+
milestoner cache --list
|
196
|
+
# 🟢 Listing users...
|
197
|
+
# 🟢 No users found.
|
198
|
+
|
199
|
+
milestoner cache --create "111,jsmith,Jane Smith"
|
200
|
+
# 🟢 Created: "Jane Smith"
|
201
|
+
|
202
|
+
milestoner cache --create "222,jdoe,John Doe"
|
203
|
+
# 🟢 Created: "John Doe"
|
204
|
+
|
205
|
+
milestoner cache --create "333,jgrey,Jill Grey"
|
206
|
+
# 🟢 Created: "Jill Grey"
|
207
|
+
|
208
|
+
milestoner cache --list
|
209
|
+
# 🟢 Listing users...
|
210
|
+
# 111, jsmith, Jane Smith
|
211
|
+
# 222, jdoe, John Doe
|
212
|
+
# 333, jgrey, Jill Grey
|
213
|
+
|
214
|
+
milestoner cache --delete "Jill Grey"
|
215
|
+
🟢 Deleted: "Jill Grey".
|
216
|
+
|
217
|
+
milestoner cache --list
|
218
|
+
# 🟢 Listing users...
|
219
|
+
# 111, jsmith, Jane Smith
|
220
|
+
# 222, jdoe, John Doe
|
221
|
+
|
222
|
+
milestoner cache --info
|
223
|
+
# 🟢 Path: /Users/demo/.cache/milestoner/database.store.
|
224
|
+
----
|
225
|
+
|
226
|
+
💡 Use `+https://api.github.com/users/<handle>+` to acquire the external ID for any GitHub user.
|
227
|
+
|
228
|
+
Once team member information is stored in your cache, you'll be able to build release notes which automatically link to GitHub user information without constantly hitting the GitHub API. _Users are identified by name so the full author name used for each commit message needs to match the same user name as stored in your source repository hosting service._
|
229
|
+
|
230
|
+
=== Build
|
231
|
+
|
232
|
+
The build command allows you to quickly build release notes for checking the current status of your project or for deployment automation. 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:
|
233
|
+
|
234
|
+
[source,bash]
|
235
|
+
----
|
236
|
+
milestoner build --format html
|
237
|
+
# 🟢 Building milestone...
|
238
|
+
# 🟢 Milestone built: /Users/bkuhlmann/Engineering/OSS/milestoner/tmp/milestone
|
239
|
+
----
|
240
|
+
|
241
|
+
💡 The above command is so useful that I use the following `msb` (i.e. Milestoner Build) Bash alias: `rm -rf tmp/milestone && milestoner build --format html && open tmp/milestone/index.html`. This allows me to quickly rebuild release notes for any project and immediately view them in my default browser.
|
242
|
+
|
243
|
+
Check out the help documentation (i.e. `milestoner build --help`) for addition usage that explains what command line options you can use to overwrite the current configuration.
|
244
|
+
|
245
|
+
==== Automatic Versioning
|
246
|
+
|
247
|
+
As mentioned earlier, the calculation of version information happens automatically for you based on your last Git tag and any Git commit trailer metadata used. If none of this information is present, then the default version of `0.0.0` is used instead. All of this information is available to you via the following command:
|
248
|
+
|
249
|
+
[source,bash]
|
250
|
+
----
|
251
|
+
milestoner build --help
|
252
|
+
----
|
253
|
+
|
254
|
+
Running the above will dynamically show you latest version information -- along with help documentation -- in case you have doubts. You can use this as a status check as well. If you don't want to use the automatic version, you can override by using the `--version` option when building. Example:
|
255
|
+
|
256
|
+
[source,bash]
|
257
|
+
----
|
258
|
+
# Uses automatic version.
|
259
|
+
milestoner build --format stream
|
260
|
+
|
261
|
+
# Uses manual version.
|
262
|
+
milestoner build --format stream --version 1.2.3
|
263
|
+
----
|
264
|
+
|
265
|
+
By default, automatic versioning is based on your last known Git tag and the version is bumped based on Git commit trailer information from untagged commits (i.e. those commits created since the last tag). All of this is managed via the {versionaire_link} gem. To ensure automatic versioning works properly, you only need to add the `Milestone` Git commit trailer with a value of: `patch`, `minor`, or `major`. Here's an example assuming you have published Version 1.0.0:
|
266
|
+
|
267
|
+
....
|
268
|
+
# First commit.
|
269
|
+
Milestone: patch
|
270
|
+
|
271
|
+
# Second commit.
|
272
|
+
Milestone: minor
|
273
|
+
|
274
|
+
# Third commit
|
275
|
+
Milestone: patch
|
276
|
+
....
|
277
|
+
|
278
|
+
Given the above, the resulting version would be: 1.1.0. This is because the highest milestone was a _minor_ milestone. The highest milestone wins and doesn't matter how many commits you made with the same milestone trailer information or the order in which the commits were made. Here's another example:
|
279
|
+
|
280
|
+
....
|
281
|
+
# First commit.
|
282
|
+
Milestone: patch
|
283
|
+
|
284
|
+
# Second commit.
|
285
|
+
Milestone: patch
|
286
|
+
|
287
|
+
# Third commit
|
288
|
+
Milestone: patch
|
289
|
+
....
|
290
|
+
|
291
|
+
Given the above, the resulting version would be: 1.0.1. This is because the highest milestone was a _patch_. Here's a final example:
|
292
|
+
|
293
|
+
....
|
294
|
+
# First commit.
|
295
|
+
Milestone: major
|
296
|
+
|
297
|
+
# Second commit.
|
298
|
+
Milestone: minor
|
299
|
+
|
300
|
+
# Third commit
|
301
|
+
Milestone: patch
|
302
|
+
....
|
303
|
+
|
304
|
+
Given the above, the resulting version would be: 2.0.0. This is because the highest milestone was a _major_ milestone.
|
305
|
+
|
306
|
+
==== Templates
|
307
|
+
|
308
|
+
Build template functionality is powered by {hanami_views_link} which means you can customize the HTML structure, CSS style, and more. The quickest way to get started is to copy the `templates` folder structure -- included with this gem -- to your preferred {runcom_link} configuration. For example, this gem's template structure is:
|
309
|
+
|
310
|
+
....
|
311
|
+
lib/milestoner/templates
|
312
|
+
├── layouts
|
313
|
+
│ ├── page.html.erb
|
314
|
+
│ └── page.stream.erb
|
315
|
+
├── milestones
|
316
|
+
│ ├── _avatar.html.erb
|
317
|
+
│ ├── _commit.html.erb
|
318
|
+
│ ├── _commit.stream.erb
|
319
|
+
│ ├── _icon.html.erb
|
320
|
+
│ ├── _profile.html.erb
|
321
|
+
│ ├── show.html.erb
|
322
|
+
│ └── show.stream.erb
|
323
|
+
└── public
|
324
|
+
└── page.css.erb
|
325
|
+
....
|
326
|
+
|
327
|
+
This means you could, for example, copy all of this gem's templates to your own {runcom_link} configuration to customize how you like. Example:
|
328
|
+
|
329
|
+
[source,bash]
|
330
|
+
----
|
331
|
+
cp -r <milestoner_gem_root>/lib/milestoner/templates $HOME/.config/milestoner/templates
|
332
|
+
----
|
333
|
+
|
334
|
+
Milestoner searches your {runcom_link} configuration first and, if templates are detected, will be used instead. Otherwise, Milestoner will fall back to it's own templates. Once {runcom_link} has calculated all possible template locations, {hanami_views_link} handles the final loading and evaluation of your templates.
|
108
335
|
|
109
336
|
== Security
|
110
337
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-container"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module Builders
|
7
|
+
# Registers all builders for injection.
|
8
|
+
module Container
|
9
|
+
extend Dry::Container::Mixin
|
10
|
+
|
11
|
+
register(:stream, memoize: true) { Stream.new }
|
12
|
+
register(:web, memoize: true) { Web.new }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module Builders
|
5
|
+
# Builds I/O stream output.
|
6
|
+
class Stream
|
7
|
+
include Milestoner::Import[:input, :kernel]
|
8
|
+
|
9
|
+
using Refinements::Pathname
|
10
|
+
|
11
|
+
def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
|
12
|
+
@view = view
|
13
|
+
@enricher = enricher
|
14
|
+
super(**)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
enricher.call.fmap do |commits|
|
19
|
+
kernel.puts view.call(commits:, layout: input.build_layout, format: :stream).to_s
|
20
|
+
kernel
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :view, :enricher
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module Builders
|
5
|
+
# Builds web page output (i.e. HTML and CSS).
|
6
|
+
class Web
|
7
|
+
include Milestoner::Import[:input]
|
8
|
+
|
9
|
+
using Refinements::Pathname
|
10
|
+
|
11
|
+
def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
|
12
|
+
@view = view
|
13
|
+
@enricher = enricher
|
14
|
+
super(**)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
input.build_root.tap do |path|
|
19
|
+
stylesheet_path.copy path.make_path.join("page.css")
|
20
|
+
write path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :view, :enricher
|
27
|
+
|
28
|
+
def stylesheet_path
|
29
|
+
input.build_template_paths
|
30
|
+
.map { |path| path.join "public/page.css.erb" }
|
31
|
+
.find(&:exist?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def write path
|
35
|
+
enricher.call.fmap do |commits|
|
36
|
+
path.join("index.html").write view.call commits:, layout: input.build_layout
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -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 output format.
|
10
|
+
class Format < Sod::Action
|
11
|
+
include Import[:input]
|
12
|
+
|
13
|
+
description "Set output format."
|
14
|
+
|
15
|
+
on %w[-f --format], argument: "[KIND]", allow: %w[stream web]
|
16
|
+
|
17
|
+
default { Container[:configuration].build_format }
|
18
|
+
|
19
|
+
def call(kind = nil) = input.build_format = kind || default
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "sod"
|
5
|
+
require "spek"
|
6
|
+
|
7
|
+
module Milestoner
|
8
|
+
module CLI
|
9
|
+
module Actions
|
10
|
+
module Build
|
11
|
+
# Handles build label.
|
12
|
+
class Label < Sod::Action
|
13
|
+
include Import[:input]
|
14
|
+
|
15
|
+
description "Set label."
|
16
|
+
|
17
|
+
on %w[-l --label], argument: "[TEXT]"
|
18
|
+
|
19
|
+
default { Spek::Loader.call("#{Pathname.pwd.basename}.gemspec").label }
|
20
|
+
|
21
|
+
def call(label = nil) = input.project_label = label || default
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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 layout.
|
10
|
+
class Layout < Sod::Action
|
11
|
+
include Import[:input]
|
12
|
+
|
13
|
+
description "Set layout."
|
14
|
+
|
15
|
+
ancillary "Use false to disable."
|
16
|
+
|
17
|
+
on %w[-L --layout], argument: "[LAYOUT]"
|
18
|
+
|
19
|
+
default { Container[:configuration].build_layout }
|
20
|
+
|
21
|
+
def call(layout = nil) = input.build_layout = parse(layout)
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse value
|
26
|
+
case value
|
27
|
+
in "false" then false
|
28
|
+
in String then value
|
29
|
+
else default
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "sod"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module CLI
|
8
|
+
module Actions
|
9
|
+
module Build
|
10
|
+
# Handles build root path.
|
11
|
+
class Root < Sod::Action
|
12
|
+
include Import[:input]
|
13
|
+
|
14
|
+
description "Set root output path."
|
15
|
+
|
16
|
+
on %w[-r --root], argument: "[PATH]"
|
17
|
+
|
18
|
+
default { Container[:configuration].build_root }
|
19
|
+
|
20
|
+
def call(path = nil) = input.build_root = (path || default).expand_path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "sod"
|
5
|
+
require "spek"
|
6
|
+
require "versionaire"
|
7
|
+
|
8
|
+
module Milestoner
|
9
|
+
module CLI
|
10
|
+
module Actions
|
11
|
+
module Build
|
12
|
+
# Handles build version.
|
13
|
+
class Version < Sod::Action
|
14
|
+
include Import[:input]
|
15
|
+
|
16
|
+
using Versionaire::Cast
|
17
|
+
|
18
|
+
description "Set version."
|
19
|
+
|
20
|
+
ancillary "Calculated from commit trailers when not supplied."
|
21
|
+
|
22
|
+
on %w[-v --version], argument: "[VERSION]"
|
23
|
+
|
24
|
+
default { Commits::Versioner.new.call }
|
25
|
+
|
26
|
+
def call(version = nil) = input.project_version = Version(version || default)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sod"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module CLI
|
7
|
+
module Actions
|
8
|
+
module Cache
|
9
|
+
# Handles creating or updating a user within the cache.
|
10
|
+
class Create < Sod::Action
|
11
|
+
include Import[:logger, client: :cache]
|
12
|
+
|
13
|
+
description "Create user."
|
14
|
+
|
15
|
+
ancillary %(Example: "1,zoe,Zoë Washburne".)
|
16
|
+
|
17
|
+
on %w[-c --create], argument: "external_id,handle,name"
|
18
|
+
|
19
|
+
def call values
|
20
|
+
process(values).bind { |user| log_info "Created: #{user.name.inspect}" }
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def process values
|
26
|
+
external_id, handle, name = values.split ","
|
27
|
+
client.commit(:users) { upsert({external_id:, handle:, name:}) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def log_info(message) = logger.info { message }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|