milestoner 0.1.0 → 0.2.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.tar.gz.sig +0 -0
- data/README.md +14 -4
- data/lib/milestoner.rb +2 -1
- data/lib/milestoner/cli.rb +38 -4
- data/lib/milestoner/exceptions.rb +4 -0
- data/lib/milestoner/identity.rb +1 -1
- data/lib/milestoner/pusher.rb +16 -0
- data/lib/milestoner/tagger.rb +96 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
- data/lib/milestoner/release.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0f6d4ae3cad5d263731f769567b7ea089dd6b01
|
4
|
+
data.tar.gz: 32d6f0cc922a456c84c0428450d06b9e36863652
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 237f10aa51dccebe908b0ccbea8de79cb33bb7dbb6e48d589a8460923a2aff576715ac86442deda9442acb03063ca26dee4eac8c99fbaec53289cd77ff33b972
|
7
|
+
data.tar.gz: 059b456ca8328cb62c923ddd11df136ea022bfb99262549fedceeecb9a540d912aef8202b3c977cbe275a718d3ae0e295259b592fd43a2362dd937f80b508c63
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -57,14 +57,24 @@ For an insecure install, type the following (not recommended):
|
|
57
57
|
|
58
58
|
From the command line, type: milestoner help
|
59
59
|
|
60
|
-
milestoner -
|
61
|
-
milestoner -
|
62
|
-
milestoner -
|
60
|
+
milestoner -P, [--publish=PUBLISH] # Tag and push to remote repository.
|
61
|
+
milestoner -h, [--help=HELP] # Show this message or get help for a command.
|
62
|
+
milestoner -p, [--push] # Push tags to remote repository.
|
63
|
+
milestoner -t, [--tag=TAG] # Tag local repository with new version.
|
64
|
+
milestoner -v, [--version] # Show version.
|
63
65
|
|
64
|
-
For
|
66
|
+
For tag options, type: milestoner help tag
|
65
67
|
|
66
68
|
-s, [--sign], [--no-sign] # Sign tag with GPG key.
|
67
69
|
|
70
|
+
For publish options, type: milestoner help publish
|
71
|
+
|
72
|
+
-s, [--sign], [--no-sign] # Sign tag with GPG key.
|
73
|
+
|
74
|
+
When using Milestoner, the `--publish` command is intended to be the only command necessary for publishing a new
|
75
|
+
release as it handles all of the steps necessary for tagging and pushing a new release. Should individual steps
|
76
|
+
be needed, then the `--tag` and `--push` options are available.
|
77
|
+
|
68
78
|
# Tests
|
69
79
|
|
70
80
|
To test, run:
|
data/lib/milestoner.rb
CHANGED
data/lib/milestoner/cli.rb
CHANGED
@@ -15,15 +15,38 @@ module Milestoner
|
|
15
15
|
super args, options, config
|
16
16
|
end
|
17
17
|
|
18
|
-
desc "-t, [--tag=TAG]", "Tag repository with new version."
|
18
|
+
desc "-t, [--tag=TAG]", "Tag local repository with new version."
|
19
19
|
map %w(-t --tag) => :tag
|
20
20
|
method_option :sign, aliases: "-s", desc: "Sign tag with GPG key.", type: :boolean, default: false
|
21
21
|
def tag version
|
22
|
-
|
23
|
-
|
24
|
-
say "Repository tagged: #{
|
22
|
+
tagger = Milestoner::Tagger.new version
|
23
|
+
tagger.create sign: options[:sign]
|
24
|
+
say "Repository tagged: #{tagger.version_label}."
|
25
25
|
rescue Milestoner::VersionError => version_error
|
26
26
|
error version_error.message
|
27
|
+
rescue Milestoner::DuplicateTagError => tag_error
|
28
|
+
error tag_error.message
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "-p, [--push]", "Push tags to remote repository."
|
32
|
+
map %w(-p --push) => :push
|
33
|
+
def push
|
34
|
+
pusher = Milestoner::Pusher.new
|
35
|
+
pusher.push
|
36
|
+
info "Tags pushed to remote repository."
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "-P, [--publish=PUBLISH]", "Tag and push to remote repository."
|
40
|
+
map %w(-P --publish) => :publish
|
41
|
+
method_option :sign, aliases: "-s", desc: "Sign tag with GPG key.", type: :boolean, default: false
|
42
|
+
def publish version
|
43
|
+
tagger = Milestoner::Tagger.new version
|
44
|
+
pusher = Milestoner::Pusher.new
|
45
|
+
tag_and_push tagger, pusher, options
|
46
|
+
rescue Milestoner::VersionError => version_error
|
47
|
+
error version_error.message
|
48
|
+
rescue Milestoner::DuplicateTagError => tag_error
|
49
|
+
error tag_error.message
|
27
50
|
end
|
28
51
|
|
29
52
|
desc "-v, [--version]", "Show version."
|
@@ -37,5 +60,16 @@ module Milestoner
|
|
37
60
|
def help task = nil
|
38
61
|
say && super
|
39
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def tag_and_push tagger, pusher, options
|
67
|
+
if tagger.create(sign: options[:sign]) && pusher.push
|
68
|
+
say "Repository tagged and pushed: #{tagger.version_label}."
|
69
|
+
say "Milestone published!"
|
70
|
+
else
|
71
|
+
tagger.destroy
|
72
|
+
end
|
73
|
+
end
|
40
74
|
end
|
41
75
|
end
|
data/lib/milestoner/identity.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Milestoner
|
2
|
+
# Handles publishing of Git tags to remote repository.
|
3
|
+
class Pusher
|
4
|
+
def initialize kernel: Kernel
|
5
|
+
@kernel = kernel
|
6
|
+
end
|
7
|
+
|
8
|
+
def push
|
9
|
+
kernel.system "git push --tags"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :kernel
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Milestoner
|
2
|
+
# Handles the tagging of a project repository.
|
3
|
+
class Tagger
|
4
|
+
attr_reader :version
|
5
|
+
|
6
|
+
def self.commit_prefixes
|
7
|
+
%w(Fixed Added Updated Removed Refactored) # Order is important for controlling the sort.
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.commit_prefix_regex
|
11
|
+
/\A(#{commit_prefixes.join "|"})/
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.version_regex
|
15
|
+
/\A\d{1}\.\d{1}\.\d{1}\z/
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize version
|
19
|
+
@version = validate_version version
|
20
|
+
end
|
21
|
+
|
22
|
+
def version_label
|
23
|
+
"v#{version}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def version_message
|
27
|
+
"Version #{version}."
|
28
|
+
end
|
29
|
+
|
30
|
+
def tagged?
|
31
|
+
response = `git tag`
|
32
|
+
!(response.nil? || response.empty?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def duplicate?
|
36
|
+
system "git rev-parse #{version_label} > /dev/null 2>&1"
|
37
|
+
end
|
38
|
+
|
39
|
+
def commits
|
40
|
+
groups = build_commit_prefix_groups
|
41
|
+
group_by_commit_prefix! groups
|
42
|
+
groups.values.flatten
|
43
|
+
end
|
44
|
+
|
45
|
+
def create sign: false
|
46
|
+
fail(DuplicateTagError, "Duplicate tag exists: #{version_label}.") if duplicate?
|
47
|
+
`git tag #{tag_options sign: sign}`
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
`git tag --delete #{version_label}`
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def validate_version version
|
57
|
+
message = "Invalid version: #{version}. Use: <major>.<minor>.<maintenance>."
|
58
|
+
fail(VersionError, message) unless version.match(self.class.version_regex)
|
59
|
+
version
|
60
|
+
end
|
61
|
+
|
62
|
+
def raw_commits
|
63
|
+
tag_command = "$(git describe --abbrev=0 --tags --always)..HEAD"
|
64
|
+
full_command = "git log --oneline --reverse --no-merges --format='%s' #{tag_command}"
|
65
|
+
full_command.gsub!(tag_command, "") unless tagged?
|
66
|
+
|
67
|
+
`#{full_command}`.split("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_commit_prefix_groups
|
71
|
+
groups = self.class.commit_prefixes.map.with_object({}) do |prefix, group|
|
72
|
+
group.merge! prefix => []
|
73
|
+
end
|
74
|
+
groups.merge! "Other" => []
|
75
|
+
end
|
76
|
+
|
77
|
+
def group_by_commit_prefix! groups = {}
|
78
|
+
raw_commits.each do |commit|
|
79
|
+
prefix = commit[self.class.commit_prefix_regex]
|
80
|
+
key = groups.key?(prefix) ? prefix : "Other"
|
81
|
+
groups[key] << commit
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def tag_message
|
86
|
+
commit_list = commits.map { |commit| "- #{commit}\n" }
|
87
|
+
%(#{version_message}\n\n#{commit_list.join})
|
88
|
+
end
|
89
|
+
|
90
|
+
def tag_options sign: false
|
91
|
+
options = %(--sign --annotate "#{version_label}" --message "#{tag_message}")
|
92
|
+
return options.gsub("--sign ", "") unless sign
|
93
|
+
options
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
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: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
aSif+qBc6oHD7EQWPF5cZkzkIURuwNwPBngZGxIKaMAgRhjGFXzUMAaq++r59cS9
|
31
31
|
xTfQ4k6fglKEgpnLAXiKdo2c8Ym+X4rIKFfedQ==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2015-09-
|
33
|
+
date: 2015-09-07 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: thor
|
@@ -315,7 +315,8 @@ files:
|
|
315
315
|
- lib/milestoner/cli.rb
|
316
316
|
- lib/milestoner/exceptions.rb
|
317
317
|
- lib/milestoner/identity.rb
|
318
|
-
- lib/milestoner/
|
318
|
+
- lib/milestoner/pusher.rb
|
319
|
+
- lib/milestoner/tagger.rb
|
319
320
|
- lib/milestoner/tasks/rspec.rake
|
320
321
|
- lib/milestoner/tasks/rubocop.rake
|
321
322
|
homepage: https://www.alchemists.io
|
metadata.gz.sig
CHANGED
Binary file
|
data/lib/milestoner/release.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
module Milestoner
|
2
|
-
# Handles the release of new project milestones.
|
3
|
-
class Release
|
4
|
-
attr_reader :version
|
5
|
-
|
6
|
-
def self.commit_prefixes
|
7
|
-
%w(Fixed Added Updated Removed Refactored) # Order is important for controlling the sort.
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.commit_prefix_regex
|
11
|
-
/\A(#{commit_prefixes.join "|"})/
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.version_regex
|
15
|
-
/\A\d{1}\.\d{1}\.\d{1}\z/
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize version
|
19
|
-
@version = validate_version version
|
20
|
-
end
|
21
|
-
|
22
|
-
def version_label
|
23
|
-
"v#{version}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def version_message
|
27
|
-
"Version #{version}."
|
28
|
-
end
|
29
|
-
|
30
|
-
def tagged?
|
31
|
-
response = `git tag`
|
32
|
-
!(response.nil? || response.empty?)
|
33
|
-
end
|
34
|
-
|
35
|
-
def commits
|
36
|
-
command = "git log --oneline --reverse --no-merges --format='%s'"
|
37
|
-
|
38
|
-
return `#{command}` unless tagged?
|
39
|
-
`#{command} $(git describe --abbrev=0 --tags --always)..HEAD`
|
40
|
-
end
|
41
|
-
|
42
|
-
def commits_sorted
|
43
|
-
prefix_regex = self.class.commit_prefix_regex
|
44
|
-
|
45
|
-
commits.split("\n").sort do |a, b|
|
46
|
-
next 1 unless a.match(prefix_regex) && b.match(prefix_regex)
|
47
|
-
sort_by_prefix a, b
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def tag sign: false
|
52
|
-
`git tag #{tag_options sign: sign}`
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def validate_version version
|
58
|
-
message = "Invalid version: #{version}. Use: <major>.<minor>.<maintenance>."
|
59
|
-
raise(VersionError, message) unless version.match(self.class.version_regex)
|
60
|
-
version
|
61
|
-
end
|
62
|
-
|
63
|
-
def index_for_prefix message
|
64
|
-
self.class.commit_prefixes.index message[self.class.commit_prefix_regex]
|
65
|
-
end
|
66
|
-
|
67
|
-
def sort_by_prefix a, b
|
68
|
-
a_index = index_for_prefix a
|
69
|
-
b_index = index_for_prefix b
|
70
|
-
|
71
|
-
case
|
72
|
-
when a_index > b_index then 1
|
73
|
-
when a_index == b_index then 0
|
74
|
-
when a_index < b_index then -1
|
75
|
-
else
|
76
|
-
a <=> b
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def tag_message
|
81
|
-
commit_list = commits_sorted.map { |commit| "- #{commit}\n" }
|
82
|
-
%(#{version_message}\n\n#{commit_list.join})
|
83
|
-
end
|
84
|
-
|
85
|
-
def tag_options sign: false
|
86
|
-
options = %(--sign --annotate "#{version_label}" --message "#{tag_message}")
|
87
|
-
return options.gsub("--sign ", "") unless sign
|
88
|
-
options
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|