milestoner 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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