milestoner 11.2.0 → 12.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 +0 -0
- data.tar.gz.sig +2 -2
- data/README.adoc +48 -50
- data/bin/milestoner +1 -3
- data/lib/milestoner.rb +9 -10
- data/lib/milestoner/cli/actions/config.rb +35 -0
- data/lib/milestoner/cli/actions/publish.rb +20 -0
- data/lib/milestoner/cli/actions/status.rb +33 -0
- data/lib/milestoner/cli/configuration/content.rb +21 -0
- data/lib/milestoner/cli/configuration/defaults.yml +12 -0
- data/lib/milestoner/cli/configuration/loader.rb +37 -0
- data/lib/milestoner/cli/parsers.rb +11 -0
- data/lib/milestoner/cli/parsers/assembler.rb +34 -0
- data/lib/milestoner/cli/parsers/core.rb +78 -0
- data/lib/milestoner/cli/parsers/security.rb +48 -0
- data/lib/milestoner/cli/shell.rb +51 -0
- data/lib/milestoner/commits/categorizer.rb +51 -0
- data/lib/milestoner/container.rb +40 -0
- data/lib/milestoner/error.rb +7 -0
- data/lib/milestoner/identity.rb +2 -1
- data/lib/milestoner/presenters/commit.rb +34 -0
- data/lib/milestoner/tags/creator.rb +70 -0
- data/lib/milestoner/tags/publisher.rb +26 -0
- data/lib/milestoner/tags/pusher.rb +40 -0
- metadata +56 -18
- metadata.gz.sig +0 -0
- data/lib/milestoner/cli.rb +0 -120
- data/lib/milestoner/commit.rb +0 -24
- data/lib/milestoner/errors/base.rb +0 -12
- data/lib/milestoner/errors/duplicate_tag.rb +0 -9
- data/lib/milestoner/errors/git.rb +0 -12
- data/lib/milestoner/publisher.rb +0 -21
- data/lib/milestoner/pusher.rb +0 -34
- data/lib/milestoner/tagger.rb +0 -89
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e354d38d2b846b1a2a81a3ca0d028162996117fc085456aa51f4e9d43c304abc
|
4
|
+
data.tar.gz: a8ea79c2c41ad41aefa14227732730ecf5641019767f02babbd98b92fbfcc6cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bedab4bb46309260ae5f06f04eab4039d612ac70eeed58bcefee7051895a3c455c56d7650764d9174c96741f2a300bc709a8004d6d34208942f81ce9d2e955db
|
7
|
+
data.tar.gz: e395deb28d54854f649bcbfa1c8f995d04e482b8bd05e66b2af531c283abe145b2de3dc2e776a8c06760946c1b5dc8a6c3e6ed861c5233379059f562fdb80b37
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
�
|
1
|
+
�r�Il S���zA���-Q�oErq���h�-�`����
|
2
|
+
\�P�d�:a�վ�#� �ƻ�,������eȃ@�<�s�ƌ�)���E��r��qV�V������4m�@�R��N��{-)���6Qݴ���4sX�=3��վ z#�]Y�7�V�cJɕ-we����*����+Jf�.�kB&<W��
|
data/README.adoc
CHANGED
@@ -23,8 +23,8 @@ toc::[]
|
|
23
23
|
** Example: `+0.1.0+`.
|
24
24
|
* Ensures Git commits since last tag (or initialization of repository) are included.
|
25
25
|
* Ensures Git commit messages are grouped by prefix, in order defined. For more details, see
|
26
|
-
link:https://www.alchemists.io/projects/git-
|
27
|
-
for details. Defaults (can be customized):
|
26
|
+
link:https://www.alchemists.io/projects/git-lint/#_commit_subject_prefix[Git Lint Commit Subject
|
27
|
+
Prefix] for details. Defaults (can be customized):
|
28
28
|
** Fixed
|
29
29
|
** Added
|
30
30
|
** Updated
|
@@ -34,11 +34,6 @@ toc::[]
|
|
34
34
|
* Ensures duplicate Git commit messages are removed (if any).
|
35
35
|
* Provides optional security for signing Git tags with https://www.gnupg.org[GnuPG] signing key.
|
36
36
|
|
37
|
-
== Screencasts
|
38
|
-
|
39
|
-
[link=https://www.alchemists.io/screencasts/milestoner]
|
40
|
-
image::https://www.alchemists.io/images/screencasts/milestoner/cover.svg[Screencast,600,240,role=focal_point]
|
41
|
-
|
42
37
|
== Requirements
|
43
38
|
|
44
39
|
. A UNIX-based system.
|
@@ -58,41 +53,36 @@ gem install milestoner
|
|
58
53
|
|
59
54
|
=== Command Line Interface (CLI)
|
60
55
|
|
61
|
-
From the command line, type:
|
56
|
+
From the command line, type: `milestoner --help`
|
62
57
|
|
63
58
|
....
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
59
|
+
USAGE:
|
60
|
+
-c, --config ACTION Manage gem configuration. Actions: edit || view.
|
61
|
+
-h, --help Show this message.
|
62
|
+
-P, --publish VERSION Tag and push milestone to remote repository.
|
63
|
+
-s, --status Show project status.
|
64
|
+
-v, --version Show gem version.
|
65
|
+
|
66
|
+
SECURITY OPTIONS:
|
67
|
+
--[no-]sign Sign with GPG key. Default: true.
|
71
68
|
....
|
72
69
|
|
73
|
-
|
70
|
+
Examples:
|
74
71
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
For tag options, type: `+milestoner help --tag+`
|
81
|
-
|
82
|
-
....
|
83
|
-
-s, [--sign], [--no-sign] # Sign tag with GPG key.
|
84
|
-
....
|
72
|
+
[source,bash]
|
73
|
+
----
|
74
|
+
milestoner --config edit
|
75
|
+
milestoner --config view
|
85
76
|
|
86
|
-
|
77
|
+
milestoner --help
|
87
78
|
|
88
|
-
|
89
|
-
|
90
|
-
|
79
|
+
milestoner --publish 0.1.0
|
80
|
+
milestoner --publish 0.1.0 --sign
|
81
|
+
milestoner --publish 0.1.0 --no-sign
|
91
82
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
available.
|
83
|
+
milestoner --status
|
84
|
+
milestoner --version
|
85
|
+
----
|
96
86
|
|
97
87
|
=== Customization
|
98
88
|
|
@@ -108,13 +98,18 @@ The default configuration is as follows:
|
|
108
98
|
|
109
99
|
[source,yaml]
|
110
100
|
----
|
111
|
-
:
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
101
|
+
:documentation:
|
102
|
+
:format: "md"
|
103
|
+
:git:
|
104
|
+
:commit:
|
105
|
+
:prefixes:
|
106
|
+
- Fixed
|
107
|
+
- Added
|
108
|
+
- Updated
|
109
|
+
- Removed
|
110
|
+
- Refactored
|
111
|
+
:tag:
|
112
|
+
:sign: false
|
118
113
|
----
|
119
114
|
|
120
115
|
Feel free to take this default configuration, modify, and save as your own custom
|
@@ -122,15 +117,18 @@ Feel free to take this default configuration, modify, and save as your own custo
|
|
122
117
|
|
123
118
|
The `+configuration.yml+` file can be configured as follows:
|
124
119
|
|
125
|
-
*
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
120
|
+
* *Documenation Format*: Determines what format the status information should be rendered. Defaults
|
121
|
+
to link:https://daringfireball.net/projects/markdown[Markdown] (i.e. `md`) but
|
122
|
+
link:https://asciidoctor.org/docs/what-is-asciidoc[ASCII Doc] (i.e. `adoc`) is supported too.
|
123
|
+
* *Git Commit Prefixes*: Should the default prefixes not be desired, you can define Git commit
|
124
|
+
prefixes that match your style. _NOTE: Prefix order is important with the first prefix defined
|
125
|
+
taking precedence over the second and so forth._ Special characters are allowed for prefixes but
|
126
|
+
should be enclosed in quotes. To disable prefix usage completely, use an empty array. Example:
|
127
|
+
`:prefixes: []`.
|
128
|
+
* *Git Tag Sign*: Defaults to `false` but can be enabled by setting to `true`. When enabled, a
|
129
|
+
Git tag will require GPG signing for enhanced security and include a signed signature as part of
|
130
|
+
the Git tag. This is useful for public milestones where the author of a milestone can be verified
|
131
|
+
to ensure milestone integrity/security.
|
134
132
|
|
135
133
|
== Security
|
136
134
|
|
data/bin/milestoner
CHANGED
data/lib/milestoner.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
require "milestoner/cli"
|
3
|
+
require "zeitwerk"
|
4
|
+
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
6
|
+
loader.inflector.inflect "cli" => "CLI"
|
7
|
+
loader.setup
|
8
|
+
|
9
|
+
# Main namespace.
|
10
|
+
module Milestoner
|
11
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
# Handles the gem configuration action.
|
7
|
+
class Config
|
8
|
+
def initialize configuration: Configuration::Loader::HANDLER, container: Container
|
9
|
+
@configuration = configuration
|
10
|
+
@container = container
|
11
|
+
end
|
12
|
+
|
13
|
+
def call action
|
14
|
+
case action
|
15
|
+
when :edit then edit
|
16
|
+
when :view then view
|
17
|
+
else logger.error { "Invalid configuration action: #{action}." }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :configuration, :container
|
24
|
+
|
25
|
+
def edit = kernel.system("$EDITOR #{configuration.current}")
|
26
|
+
|
27
|
+
def view = kernel.system("cat #{configuration.current}")
|
28
|
+
|
29
|
+
def kernel = container[__method__]
|
30
|
+
|
31
|
+
def logger = container[__method__]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
# Handles tag creation and pushing of tag to local repository.
|
7
|
+
class Publish
|
8
|
+
def initialize publisher: Tags::Publisher.new
|
9
|
+
@publisher = publisher
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(configuration) = publisher.call(configuration)
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :publisher
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
# Handles listing project status of untagged commit history.
|
7
|
+
class Status
|
8
|
+
def initialize presenter: Presenters::Commit,
|
9
|
+
categorizer: Commits::Categorizer.new,
|
10
|
+
container: Container
|
11
|
+
@presenter = presenter
|
12
|
+
@categorizer = categorizer
|
13
|
+
@container = container
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
categorizer.call
|
18
|
+
.tap { |records| info "All is quiet." if records.empty? }
|
19
|
+
.map { |record| presenter.new(record).line_item }
|
20
|
+
.each { |line_item| info line_item }
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :presenter, :categorizer, :container
|
26
|
+
|
27
|
+
def info(message) = logger.info { message }
|
28
|
+
|
29
|
+
def logger = container[__method__]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module CLI
|
5
|
+
module Configuration
|
6
|
+
# Defines configuration content as the primary source of truth for use throughout the gem.
|
7
|
+
Content = Struct.new :action_config,
|
8
|
+
:action_publish,
|
9
|
+
:action_push,
|
10
|
+
:action_status,
|
11
|
+
:action_tag,
|
12
|
+
:action_version,
|
13
|
+
:action_help,
|
14
|
+
:documentation_format,
|
15
|
+
:git_commit_prefixes,
|
16
|
+
:git_tag_sign,
|
17
|
+
:git_tag_version,
|
18
|
+
keyword_init: true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "refinements/hashes"
|
5
|
+
require "refinements/structs"
|
6
|
+
require "runcom"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
module Milestoner
|
10
|
+
module CLI
|
11
|
+
module Configuration
|
12
|
+
# Represents the fully assembled Command Line Interface (CLI) configuration.
|
13
|
+
class Loader
|
14
|
+
using Refinements::Hashes
|
15
|
+
using Refinements::Structs
|
16
|
+
|
17
|
+
DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
|
18
|
+
HANDLER = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
|
19
|
+
|
20
|
+
def self.call = new.call
|
21
|
+
|
22
|
+
def self.with_defaults = new(handler: DEFAULTS)
|
23
|
+
|
24
|
+
def initialize content: Content.new, handler: HANDLER
|
25
|
+
@content = content
|
26
|
+
@handler = handler
|
27
|
+
end
|
28
|
+
|
29
|
+
def call = content.merge(**handler.to_h.flatten_keys)
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :content, :handler
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "runcom"
|
4
|
+
|
5
|
+
module Milestoner
|
6
|
+
module CLI
|
7
|
+
module Parsers
|
8
|
+
SECTIONS = [Core, Security].freeze # Order is important.
|
9
|
+
|
10
|
+
# Assembles and parses all Command Line Interface (CLI) options.
|
11
|
+
class Assembler
|
12
|
+
def initialize configuration = CLI::Configuration::Loader.call,
|
13
|
+
sections: SECTIONS,
|
14
|
+
client: CLIENT
|
15
|
+
@configuration = configuration
|
16
|
+
@sections = sections
|
17
|
+
@client = client
|
18
|
+
end
|
19
|
+
|
20
|
+
def call arguments = []
|
21
|
+
sections.each { |parser| parser.call configuration, client: client }
|
22
|
+
client.parse! arguments
|
23
|
+
configuration
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s = client.to_s
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :configuration, :client, :sections
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "versionaire/extensions/option_parser"
|
4
|
+
require "refinements/structs"
|
5
|
+
|
6
|
+
module Milestoner
|
7
|
+
module CLI
|
8
|
+
# Handles parsing of Command Line Interface (CLI) primary options.
|
9
|
+
module Parsers
|
10
|
+
using Refinements::Structs
|
11
|
+
|
12
|
+
# Handles parsing of Command Line Interface (CLI) core options.
|
13
|
+
class Core
|
14
|
+
def self.call configuration = Configuration::Loader.call, client: CLIENT
|
15
|
+
new(configuration, client: client).call
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize configuration = Configuration::Loader.call, client: CLIENT
|
19
|
+
@configuration = configuration
|
20
|
+
@client = client
|
21
|
+
end
|
22
|
+
|
23
|
+
def call arguments = []
|
24
|
+
client.banner = "#{Identity::LABEL} - #{Identity::SUMMARY}"
|
25
|
+
client.separator "\nUSAGE:\n"
|
26
|
+
collate
|
27
|
+
arguments.empty? ? arguments : client.parse!(arguments)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :configuration, :client
|
33
|
+
|
34
|
+
def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
|
35
|
+
|
36
|
+
def add_config
|
37
|
+
client.on(
|
38
|
+
"-c",
|
39
|
+
"--config ACTION",
|
40
|
+
%i[edit view],
|
41
|
+
"Manage gem configuration. Actions: edit || view."
|
42
|
+
) do |action|
|
43
|
+
configuration.action_config = action
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_publish
|
48
|
+
client.on(
|
49
|
+
"-P",
|
50
|
+
"--publish VERSION",
|
51
|
+
Versionaire::Version,
|
52
|
+
"Tag and push milestone to remote repository."
|
53
|
+
) do |version|
|
54
|
+
configuration.merge! action_publish: true, git_tag_version: version
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_status
|
59
|
+
client.on "-s", "--status", "Show project status." do
|
60
|
+
configuration.action_status = true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_version
|
65
|
+
client.on "-v", "--version", "Show gem version." do
|
66
|
+
configuration.action_version = Identity::VERSION_LABEL
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_help
|
71
|
+
client.on "-h", "--help", "Show this message." do
|
72
|
+
configuration.action_help = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|