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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 048fc5e408dc33ae259639732315a07158ae5531
4
- data.tar.gz: e6f3f12e4329cb47c58b1413f87aea235effab16
3
+ metadata.gz: c0f6d4ae3cad5d263731f769567b7ea089dd6b01
4
+ data.tar.gz: 32d6f0cc922a456c84c0428450d06b9e36863652
5
5
  SHA512:
6
- metadata.gz: d176b7238258c0ba630ef0dfd81c05657b8da54463bb5c2b00844c22fbe3280d8cc13eee80d73520b238bbbb106bed144018b53be95a489212950fe4c49998e2
7
- data.tar.gz: 61ee34af933007993308d74765d8375fe7a7e1c583a8f8a9f0e4d50774690c39f1d9df3b815d7a900a03af994d0af2ca75d6d18e8a32e953c908e5f61e8a195e
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 -h, [--help=HELP] # Show this message or get help for a command.
61
- milestoner -t, [--tag=TAG] # Tag repository with new version.
62
- milestoner -v, [--version] # Show version.
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 more gem creation options, type: milestoner help tag
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
@@ -1,3 +1,4 @@
1
1
  require "milestoner/identity"
2
2
  require "milestoner/exceptions"
3
- require "milestoner/release"
3
+ require "milestoner/pusher"
4
+ require "milestoner/tagger"
@@ -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
- release = Milestoner::Release.new version
23
- release.tag sign: options[:sign]
24
- say "Repository tagged: #{release.version_label}."
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
@@ -2,4 +2,8 @@ module Milestoner
2
2
  # Raised for invalid version formats.
3
3
  class VersionError < StandardError
4
4
  end
5
+
6
+ # Raised for duplicate tags.
7
+ class DuplicateTagError < StandardError
8
+ end
5
9
  end
@@ -10,7 +10,7 @@ module Milestoner
10
10
  end
11
11
 
12
12
  def self.version
13
- "0.1.0"
13
+ "0.2.0"
14
14
  end
15
15
 
16
16
  def self.label_version
@@ -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.1.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-06 00:00:00.000000000 Z
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/release.rb
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
@@ -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