milestoner 10.4.0 → 12.0.0

Sign up to get free protection for your applications and to get access to all the features.
metadata.gz.sig CHANGED
Binary file
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "thor"
4
- require "thor/actions"
5
- require "runcom"
6
-
7
- module Milestoner
8
- # The Command Line Interface (CLI) for the gem.
9
- class CLI < Thor
10
- include Thor::Actions
11
-
12
- package_name Identity::VERSION_LABEL
13
-
14
- def self.configuration
15
- Runcom::Config.new "#{Identity::NAME}/configuration.yml",
16
- defaults: {
17
- git_commit_prefixes: %w[Fixed Added Updated Removed Refactored],
18
- git_tag_sign: false
19
- }
20
- end
21
-
22
- def initialize args = [], options = {}, config = {}
23
- super args, options, config
24
- @configuration = self.class.configuration
25
- @tagger = Tagger.new commit_prefixes: @configuration.to_h[:git_commit_prefixes]
26
- @pusher = Pusher.new
27
- @publisher = Publisher.new tagger: tagger, pusher: pusher
28
- rescue Runcom::Errors::Base => error
29
- abort error.message
30
- end
31
-
32
- desc "-C, [--commits]", "Show commits for next milestone."
33
- map %w[-C --commits] => :commits
34
- def commits
35
- tagger.commit_list.each { |commit| say commit }
36
- rescue StandardError => error
37
- say_status :error, error.message, :red
38
- end
39
-
40
- desc "-t, [--tag=VERSION]", "Tag local repository with new version."
41
- map %w[-t --tag] => :tag
42
- method_option :sign,
43
- aliases: "-s",
44
- desc: "Sign tag with GPG key.",
45
- type: :boolean,
46
- default: false
47
- def tag version
48
- tagger.create version, sign: sign_tag?(options[:sign])
49
- say "Repository tagged: #{tagger.version}."
50
- rescue StandardError => error
51
- say_status :error, error.message, :red
52
- end
53
-
54
- desc "-p, [--push=VERSION]", "Push local tag to remote repository."
55
- map %w[-p --push] => :push
56
- def push version
57
- pusher.push version
58
- say_status :info, "Tags pushed to remote repository.", :green
59
- rescue StandardError => error
60
- say_status :error, error.message, :red
61
- end
62
-
63
- desc "-P, [--publish=VERSION]", "Tag and push milestone to remote repository."
64
- map %w[-P --publish] => :publish
65
- method_option :sign,
66
- aliases: "-s",
67
- desc: "Sign tag with GPG key.",
68
- type: :boolean,
69
- default: false
70
- def publish version
71
- publisher.publish version, sign: sign_tag?(options[:sign])
72
- say_status :info, "Repository tagged and pushed: #{tagger.version}.", :green
73
- say_status :info, "Milestone published!", :green
74
- rescue StandardError => error
75
- say_status :error, error.message, :red
76
- end
77
-
78
- desc "-c, [--config]", "Manage gem configuration."
79
- map %w[-c --config] => :config
80
- method_option :edit,
81
- aliases: "-e",
82
- desc: "Edit gem configuration.",
83
- type: :boolean,
84
- default: false
85
- method_option :info,
86
- aliases: "-i",
87
- desc: "Print gem configuration.",
88
- type: :boolean,
89
- default: false
90
- def config
91
- path = configuration.current
92
-
93
- if options.edit? then `#{ENV["EDITOR"]} #{path}`
94
- elsif options.info?
95
- path ? say(path) : say("Configuration doesn't exist.")
96
- else help :config
97
- end
98
- end
99
-
100
- desc "-v, [--version]", "Show gem version."
101
- map %w[-v --version] => :version
102
- def version
103
- say Identity::VERSION_LABEL
104
- end
105
-
106
- desc "-h, [--help=COMMAND]", "Show this message or get help for a command."
107
- map %w[-h --help] => :help
108
- def help task = nil
109
- say and super
110
- end
111
-
112
- private
113
-
114
- attr_reader :configuration, :tagger, :pusher, :publisher
115
-
116
- def sign_tag? sign
117
- sign | configuration.to_h[:git_tag_sign]
118
- end
119
- end
120
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- module Errors
5
- # The base class for all Milestoner related errors.
6
- class Base < StandardError
7
- def initialize message = "Invalid Milestoner action."
8
- super message
9
- end
10
- end
11
- end
12
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- module Errors
5
- # Raised for duplicate tags.
6
- class DuplicateTag < Base
7
- end
8
- end
9
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- module Errors
5
- # Raised for projects not initialized as Git repositories.
6
- class Git < Base
7
- def initialize message = "Invalid Git repository."
8
- super message
9
- end
10
- end
11
- end
12
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
-
5
- module Milestoner
6
- module Git
7
- # A lightweight Git Config wrapper.
8
- class Config
9
- def initialize shell: Open3
10
- @shell = shell
11
- end
12
-
13
- def get key
14
- shell.capture3 "git config --get #{key}"
15
- end
16
-
17
- def set key, value
18
- shell.capture3 %(git config --add #{key} "#{value}")
19
- end
20
-
21
- def value key
22
- get(key).first.chomp
23
- end
24
-
25
- private
26
-
27
- attr_reader :shell
28
- end
29
- end
30
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- module Git
5
- # A lightweight Git wrapper.
6
- class Kit
7
- def initialize
8
- @git_dir = File.join Dir.pwd, ".git"
9
- end
10
-
11
- def supported?
12
- File.exist? git_dir
13
- end
14
-
15
- def commits?
16
- !shell("git log").empty?
17
- end
18
-
19
- def push_tags
20
- shell "git push --tags"
21
- end
22
-
23
- def tagged?
24
- !shell("git tag").empty?
25
- end
26
-
27
- def tag_local? tag
28
- shell("git tag --list #{tag}").match?(/\A#{tag}\Z/)
29
- end
30
-
31
- def tag_remote? tag
32
- shell("git ls-remote --tags origin #{tag}").match?(%r(.+tags/#{tag}\Z))
33
- end
34
-
35
- def remote?
36
- !shell("git config remote.origin.url").empty?
37
- end
38
-
39
- private
40
-
41
- attr_reader :git_dir
42
-
43
- def shell command
44
- String `#{command}`
45
- end
46
- end
47
- end
48
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- # Handles the tagging and pushing of a milestone to a remote repository.
5
- class Publisher
6
- def initialize tagger: Tagger.new, pusher: Pusher.new
7
- @tagger = tagger
8
- @pusher = pusher
9
- end
10
-
11
- # :reek:BooleanParameter
12
- def publish version, sign: false
13
- tagger.create version, sign: sign
14
- pusher.push version
15
- end
16
-
17
- private
18
-
19
- attr_reader :tagger, :pusher
20
- end
21
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milestoner
4
- # Handles publishing of Git tags to remote repository.
5
- class Pusher
6
- def initialize git: Git::Kit.new
7
- @git = git
8
- end
9
-
10
- def push version
11
- version = Versionaire::Version version
12
-
13
- fail Errors::Git, "Remote repository not configured." unless git.remote?
14
- fail Errors::Git, "Remote tag exists: #{version}." if tag_exists? version
15
- return if git.push_tags.empty?
16
-
17
- fail Errors::Git, "Tags could not be pushed to remote repository."
18
- end
19
-
20
- private
21
-
22
- attr_reader :git, :version
23
-
24
- def tag_exists? version
25
- git.tag_remote? version
26
- end
27
- end
28
- end
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
- require "thor"
5
- require "versionaire"
6
- require "tempfile"
7
-
8
- module Milestoner
9
- # Handles the tagging of a project repository.
10
- # :reek:TooManyMethods
11
- # :reek:InstanceVariableAssumption
12
- class Tagger
13
- attr_reader :version, :commit_prefixes
14
-
15
- def initialize commit_prefixes: [], git: Git::Kit.new
16
- @commit_prefixes = commit_prefixes
17
- @git = git
18
- @shell = Thor::Shell::Color.new
19
- end
20
-
21
- def commit_prefix_regex
22
- return Regexp.new "" if commit_prefixes.empty?
23
-
24
- Regexp.union commit_prefixes
25
- end
26
-
27
- def commits
28
- groups = build_commit_prefix_groups
29
- group_by_commit_prefix groups
30
- groups.each_value(&:sort!)
31
- groups.values.flatten.uniq
32
- end
33
-
34
- def commit_list
35
- commits.map { |commit| "- #{commit}" }
36
- end
37
-
38
- # :reek:BooleanParameter
39
- def create version, sign: false
40
- @version = Versionaire::Version version
41
- fail Errors::Git, "Unable to tag without commits." unless git.commits?
42
- return if existing_tag?
43
-
44
- git_tag sign: sign
45
- end
46
-
47
- private
48
-
49
- attr_reader :git, :shell
50
-
51
- def git_log_command
52
- "git log --oneline --no-merges --format='%s'"
53
- end
54
-
55
- def git_tag_command
56
- "$(git describe --abbrev=0 --tags --always)..HEAD"
57
- end
58
-
59
- def git_commits_command
60
- return "#{git_log_command} #{git_tag_command}" if git.tagged?
61
-
62
- git_log_command
63
- end
64
-
65
- def raw_commits
66
- `#{git_commits_command}`.split "\n"
67
- end
68
-
69
- def build_commit_prefix_groups
70
- groups = commit_prefixes.map.with_object({}) { |prefix, group| group.merge! prefix => [] }
71
- groups.merge! "Other" => []
72
- end
73
-
74
- def group_by_commit_prefix groups = {}
75
- raw_commits.each do |commit|
76
- prefix = commit[commit_prefix_regex]
77
- key = groups.key?(prefix) ? prefix : "Other"
78
- groups[key] << commit.gsub(/\[ci\sskip\]/, "").squeeze(" ").strip
79
- end
80
- end
81
-
82
- def git_message
83
- %(Version #{@version}\n\n#{commit_list.join "\n"}\n\n)
84
- end
85
-
86
- # :reek:BooleanParameter
87
- # :reek:ControlParameter
88
- def git_options message_file, sign: false
89
- options = %(--sign --annotate "#{@version}" ) +
90
- %(--cleanup verbatim --file "#{message_file.path}")
91
- return options.gsub "--sign ", "" unless sign
92
-
93
- options
94
- end
95
-
96
- def existing_tag?
97
- return false unless git.tag_local? @version
98
-
99
- shell.say_status :warn, "Local tag exists: #{@version}. Skipped.", :yellow
100
- true
101
- end
102
-
103
- # :reek:BooleanParameter
104
- # :reek:TooManyStatements
105
- def git_tag sign: false
106
- message_file = Tempfile.new Identity::NAME
107
- File.open(message_file, "w") { |file| file.write git_message }
108
- status = system "git tag #{git_options message_file, sign: sign}"
109
- fail Errors::Git, "Unable to create tag: #{@version}." unless status
110
- ensure
111
- message_file.close
112
- message_file.unlink
113
- end
114
- end
115
- end