ballantine 0.1.4.pre.beta2 → 0.1.4.pre.beta3
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
- data/lib/ballantine/author.rb +18 -9
- data/lib/ballantine/cli.rb +20 -22
- data/lib/ballantine/commit.rb +26 -14
- data/lib/ballantine/config.rb +16 -5
- data/lib/ballantine/repository.rb +28 -29
- data/lib/ballantine/version.rb +1 -1
- data/lib/ballantine.rb +1 -0
- data/lib/printable.rb +28 -0
- data/lib/string.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: faa1e978d804f0d6db7c1c8b2d0d46a1fee27cd0a1f11c811b34f700fa99ac4d
|
4
|
+
data.tar.gz: 17a176cabd94e64d662bde533f605b6d36ebc19f301f6f77df3afc7870fdfedb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 014f30ad7a7764ef9d2d8619a62c541de3e23115e9d9eddebf16da3d1e6f958fc5d2567f57d3072907f8df1d398ca9ff8e8f785675095ad95e8adabfa76e0080
|
7
|
+
data.tar.gz: eed48b827efdbab0ff935444936431ac08a8ef97b15a9291679ec45f64ea9b56a295ad4ae40049749d516d385e7daaad18017449638af38d7c0579cf2be155ff
|
data/lib/ballantine/author.rb
CHANGED
@@ -2,16 +2,22 @@
|
|
2
2
|
|
3
3
|
module Ballantine
|
4
4
|
class Author
|
5
|
+
include Printable
|
6
|
+
|
5
7
|
attr_reader :name, :commits_hash
|
6
8
|
|
7
9
|
class << self
|
8
10
|
# @param [String] name
|
9
|
-
# @return [Author]
|
10
|
-
def
|
11
|
+
# @return [Author, NilClass]
|
12
|
+
def find(name:)
|
11
13
|
@_collections = {} unless defined?(@_collections)
|
12
|
-
|
14
|
+
@_collections[name]
|
15
|
+
end
|
13
16
|
|
14
|
-
|
17
|
+
# @param [String] name
|
18
|
+
# @return [Author]
|
19
|
+
def find_or_create_by(name:)
|
20
|
+
find(name:) || @_collections[name] = new(name:)
|
15
21
|
end
|
16
22
|
|
17
23
|
# @return [Array<Author>] authors
|
@@ -33,8 +39,10 @@ module Ballantine
|
|
33
39
|
puts "\n" + "@#{name}".green
|
34
40
|
commits_hash.each do |repo_name, commits|
|
35
41
|
count, word = retrieve_count_and_word(commits)
|
36
|
-
puts " > #{repo_name.blue}: #{count} new #{word}
|
37
|
-
|
42
|
+
puts " > #{repo_name.blue}: #{count} new #{word}"
|
43
|
+
commits.each do |commit|
|
44
|
+
puts_r " - #{commit.hash.yellow} #{commit.subject}", commit.url.gray
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
true
|
@@ -42,11 +50,12 @@ module Ballantine
|
|
42
50
|
|
43
51
|
# returns an array to use slack attachments field
|
44
52
|
# reference: https://api.slack.com/messaging/composing/layouts#building-attachments
|
45
|
-
# @return [Hash]
|
46
|
-
def
|
53
|
+
# @return [Hash]
|
54
|
+
def slack_message
|
47
55
|
message = commits_hash.map do |repo_name, commits|
|
48
56
|
count, word = retrieve_count_and_word(commits)
|
49
|
-
"*#{repo_name}*: #{count} new #{word}\n
|
57
|
+
"*#{repo_name}*: #{count} new #{word}\n" \
|
58
|
+
"#{commits.map(&:slack_message).join("\n")}"
|
50
59
|
end.join("\n")
|
51
60
|
|
52
61
|
{
|
data/lib/ballantine/cli.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
module Ballantine
|
4
4
|
class CLI < Thor
|
5
|
-
|
6
|
-
TYPE_SLACK = "slack"
|
5
|
+
include Printable
|
7
6
|
|
8
|
-
attr_reader :
|
7
|
+
attr_reader :repo
|
9
8
|
|
10
9
|
class << self
|
11
10
|
def exit_on_failure?; exit(1) end
|
@@ -32,14 +31,15 @@ module Ballantine
|
|
32
31
|
raise NotAllowed, "Environment value must be unique."
|
33
32
|
end
|
34
33
|
|
35
|
-
|
36
|
-
raise AssertionFailed, "Environment value must exist: #{
|
34
|
+
env = Config::AVAILABLE_ENVIRONMENTS.find { |key| options[key] }
|
35
|
+
raise AssertionFailed, "Environment value must exist: #{env}" if env.nil?
|
37
36
|
|
37
|
+
conf.env = env
|
38
38
|
value ? conf.set_data(key, value) : conf.print_data(key)
|
39
39
|
end
|
40
40
|
|
41
41
|
desc "diff [TARGET] [SOURCE]", "Diff commits between TARGET and SOURCE"
|
42
|
-
option TYPE_SLACK, type: :boolean, aliases: "-s", default: false, desc: "Send to slack using slack webhook URL."
|
42
|
+
option Config::TYPE_SLACK, type: :boolean, aliases: "-s", default: false, desc: "Send to slack using slack webhook URL."
|
43
43
|
def diff(target, source = %x(git rev-parse --abbrev-ref HEAD).chomp)
|
44
44
|
# validate arguments
|
45
45
|
validate(target, source, **options)
|
@@ -53,8 +53,8 @@ module Ballantine
|
|
53
53
|
# check commits
|
54
54
|
check_commits(**options)
|
55
55
|
|
56
|
-
#
|
57
|
-
|
56
|
+
# print commits
|
57
|
+
print_commits(target, source, **options)
|
58
58
|
|
59
59
|
exit(0)
|
60
60
|
end
|
@@ -68,7 +68,7 @@ module Ballantine
|
|
68
68
|
|
69
69
|
private
|
70
70
|
|
71
|
-
def conf;
|
71
|
+
def conf; Config.instance end
|
72
72
|
|
73
73
|
# @param [String] target
|
74
74
|
# @param [String] source
|
@@ -87,7 +87,7 @@ module Ballantine
|
|
87
87
|
raise NotAllowed, "ERROR: target(#{target}) and source(#{source}) can't be equal."
|
88
88
|
end
|
89
89
|
|
90
|
-
if options[TYPE_SLACK] && !conf.get_data(Config::KEY_SLACK_WEBHOOK)
|
90
|
+
if options[Config::TYPE_SLACK] && !conf.get_data(Config::KEY_SLACK_WEBHOOK)
|
91
91
|
raise NotAllowed, "ERROR: Can't find any slack webhook. Set slack webhook using `ballantine config --#{Config::ENV_LOCAL} slack_webhook [YOUR_WEBHOOK]'."
|
92
92
|
end
|
93
93
|
|
@@ -99,8 +99,7 @@ module Ballantine
|
|
99
99
|
# @param [Hash] options
|
100
100
|
# @return [Boolean]
|
101
101
|
def init_variables(target, source, **options)
|
102
|
-
|
103
|
-
Repository.send_type = @send_type
|
102
|
+
conf.print_type = options[Config::TYPE_SLACK] ? Config::TYPE_SLACK : Config::TYPE_TERMINAL
|
104
103
|
@repo = Repository.find_or_create_by(
|
105
104
|
path: Dir.pwd,
|
106
105
|
remote_url: %x(git config --get remote.origin.url).chomp,
|
@@ -123,24 +122,23 @@ module Ballantine
|
|
123
122
|
# @param [String] source
|
124
123
|
# @param [Hash] options
|
125
124
|
# @return [Boolean]
|
126
|
-
def
|
125
|
+
def print_commits(target, source, **options)
|
127
126
|
authors = Author.all
|
128
127
|
if authors.empty?
|
129
128
|
raise ArgumentError, "ERROR: There is no commits between \"#{target}\" and \"#{source}\""
|
130
129
|
end
|
131
130
|
|
132
131
|
number = authors.size
|
133
|
-
last_commit = repo.print_last_commit
|
134
132
|
|
135
|
-
case
|
136
|
-
when TYPE_TERMINAL
|
137
|
-
|
133
|
+
case conf.print_type
|
134
|
+
when Config::TYPE_TERMINAL
|
135
|
+
puts_r "Check commits before #{repo.name.red} deployment. (#{target.cyan} <- #{source.cyan})", "#{repo.url}/compare/#{repo.from.hash}...#{repo.to.hash}".gray
|
138
136
|
puts "Author".yellow + ": #{number}"
|
139
|
-
|
137
|
+
puts_r "#{"Last commit".blue}: #{repo.to.hash.yellow} #{repo.to.subject}", repo.to.url.gray
|
140
138
|
authors.map(&:print_commits)
|
141
|
-
when TYPE_SLACK
|
139
|
+
when Config::TYPE_SLACK
|
142
140
|
# set message for each author
|
143
|
-
messages = authors.map(&:
|
141
|
+
messages = authors.map(&:slack_message)
|
144
142
|
actor = %x(git config user.name).chomp
|
145
143
|
|
146
144
|
# send message to slack
|
@@ -152,14 +150,14 @@ module Ballantine
|
|
152
150
|
request.body = JSON.dump({
|
153
151
|
"text" => ":white_check_mark: *#{repo.name}* deployment request by <@#{actor}>" \
|
154
152
|
" (\`<#{repo.url}/tree/#{repo.from.hash}|#{target}>\` <- \`<#{repo.url}/tree/#{repo.to.hash}|#{source}>\` <#{repo.url}/compare/#{repo.from.hash}...#{repo.to.hash}|compare>)" \
|
155
|
-
"\n:technologist: Author: #{number}\nLast commit: #{
|
153
|
+
"\n:technologist: Author: #{number}\nLast commit: #{repo.to.slack_message}",
|
156
154
|
"attachments" => messages,
|
157
155
|
})
|
158
156
|
req_options = { use_ssl: uri.scheme == "https" }
|
159
157
|
response = Net::HTTP.start(uri.hostname, uri.port, req_options) { |http| http.request(request) }
|
160
158
|
puts response.message
|
161
159
|
else
|
162
|
-
raise AssertionFailed, "Unknown
|
160
|
+
raise AssertionFailed, "Unknown print type: #{conf.print_type}"
|
163
161
|
end
|
164
162
|
|
165
163
|
true
|
data/lib/ballantine/commit.rb
CHANGED
@@ -2,33 +2,45 @@
|
|
2
2
|
|
3
3
|
module Ballantine
|
4
4
|
class Commit
|
5
|
-
attr_reader :hash, :
|
5
|
+
attr_reader :hash, :long_hash, :subject # attributes
|
6
6
|
attr_reader :repo, :author # associations
|
7
7
|
|
8
8
|
class << self
|
9
9
|
# @param [String] hash
|
10
10
|
# @param [Repository] repo
|
11
|
-
# @
|
12
|
-
|
13
|
-
# @return [Commit]
|
14
|
-
def find_or_create_by(hash:, repo:, message: nil, author: nil)
|
11
|
+
# @return [Commit, NilClass]
|
12
|
+
def find(hash:, repo:)
|
15
13
|
@_collections = {} unless defined?(@_collections)
|
16
|
-
|
17
|
-
|
14
|
+
@_collections["#{hash[...7]}-#{repo.name}"]
|
15
|
+
end
|
18
16
|
|
19
|
-
|
17
|
+
# @param [String] hash
|
18
|
+
# @param [Repository] repo
|
19
|
+
# @return [Commit]
|
20
|
+
def find_or_create_by(hash:, repo:)
|
21
|
+
find(hash:, repo:) || @_collections["#{hash[...7]}-#{repo.name}"] = new(hash:, repo:)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
# @param [String] hash
|
24
26
|
# @param [Repository] repo
|
25
|
-
|
26
|
-
|
27
|
-
def initialize(hash:, repo:, message:, author:)
|
28
|
-
@hash = hash
|
27
|
+
def initialize(hash:, repo:)
|
28
|
+
@hash = hash[...7]
|
29
29
|
@repo = repo
|
30
|
-
|
31
|
-
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Commit]
|
33
|
+
def update(**kwargs)
|
34
|
+
# TODO: validate keys and values
|
35
|
+
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def url; @url ||= "#{repo.url}/commit/#{long_hash}" end
|
40
|
+
|
41
|
+
# @return [String]
|
42
|
+
def slack_message
|
43
|
+
"\`<#{url}|#{hash}>\` #{subject} - #{author.name}"
|
32
44
|
end
|
33
45
|
end
|
34
46
|
end
|
data/lib/ballantine/config.rb
CHANGED
@@ -2,24 +2,35 @@
|
|
2
2
|
|
3
3
|
module Ballantine
|
4
4
|
class Config
|
5
|
+
FILE_BALLANTINE_CONFIG = ".ballantine.json"
|
5
6
|
ENV_LOCAL = "local"
|
6
7
|
ENV_GLOBAL = "global"
|
8
|
+
TYPE_TERMINAL = "terminal"
|
9
|
+
TYPE_SLACK = "slack"
|
7
10
|
AVAILABLE_ENVIRONMENTS = [
|
8
11
|
ENV_LOCAL,
|
9
12
|
ENV_GLOBAL,
|
10
13
|
].freeze
|
11
|
-
|
12
14
|
KEY_SLACK_WEBHOOK = "slack_webhook"
|
13
15
|
AVAILABLE_KEYS = [
|
14
16
|
KEY_SLACK_WEBHOOK,
|
15
17
|
].freeze
|
16
18
|
|
17
|
-
|
19
|
+
attr_reader :data, :loaded
|
20
|
+
attr_accessor :env, :print_type
|
18
21
|
|
19
|
-
|
22
|
+
class << self
|
23
|
+
# @note singleton method
|
24
|
+
# @return [Config]
|
25
|
+
def instance(...)
|
26
|
+
return @_instance if defined?(@_instance)
|
27
|
+
|
28
|
+
@_instance = new(...)
|
29
|
+
end
|
30
|
+
end
|
20
31
|
|
21
|
-
def initialize
|
22
|
-
@env =
|
32
|
+
def initialize
|
33
|
+
@env = ENV_LOCAL
|
23
34
|
@data = {}
|
24
35
|
@loaded = false
|
25
36
|
end
|
@@ -13,21 +13,24 @@ module Ballantine
|
|
13
13
|
'^ssh://git@(.+)/(.+)/(.+)\.git$', # protocol: ssh -> ssh://git@github.com/oohyun15/ballantine.git
|
14
14
|
].freeze
|
15
15
|
FILE_GITMODULES = ".gitmodules"
|
16
|
-
DEFAULT_LJUST = 70
|
17
16
|
PARSER_TOKEN = "!#!#"
|
18
17
|
|
19
|
-
attr_reader :name, :path, :owner, :
|
18
|
+
attr_reader :name, :path, :owner, :from, :to # attributes
|
20
19
|
attr_reader :main_repo, :sub_repos, :commits # associations
|
21
20
|
|
22
21
|
class << self
|
22
|
+
# @param [String] path
|
23
|
+
# @return [Repository, NilClass]
|
24
|
+
def find(path:)
|
25
|
+
@_collections = {} unless defined?(@_collections)
|
26
|
+
@_collections[path]
|
27
|
+
end
|
28
|
+
|
23
29
|
# @param [String] path
|
24
30
|
# @param [String] remote_url
|
25
31
|
# @return [Repository]
|
26
32
|
def find_or_create_by(path:, remote_url: nil)
|
27
|
-
@_collections =
|
28
|
-
return @_collections[path] unless @_collections[path].nil?
|
29
|
-
|
30
|
-
@_collections[path] = new(path:, remote_url:)
|
33
|
+
find(path:) || @_collections[path] = new(path:, remote_url:)
|
31
34
|
end
|
32
35
|
|
33
36
|
# @return [Array<Repository>]
|
@@ -36,9 +39,6 @@ module Ballantine
|
|
36
39
|
|
37
40
|
@_collections.values
|
38
41
|
end
|
39
|
-
|
40
|
-
def send_type; @_send_type end
|
41
|
-
def send_type=(value); @_send_type = value end
|
42
42
|
end
|
43
43
|
|
44
44
|
# @param [String] path
|
@@ -51,10 +51,10 @@ module Ballantine
|
|
51
51
|
str = remote_url.match(regex)
|
52
52
|
break [str[2], str[3]] if str
|
53
53
|
end
|
54
|
-
@url = "https://github.com/#{owner}/#{name}"
|
55
|
-
@format = check_format
|
56
54
|
end
|
57
55
|
|
56
|
+
def url; @url ||= "https://github.com/#{owner}/#{name}" end
|
57
|
+
|
58
58
|
# @param [String] target
|
59
59
|
# @param [String] source
|
60
60
|
# @return [Boolean]
|
@@ -76,7 +76,7 @@ module Ballantine
|
|
76
76
|
if sub_repos.any?
|
77
77
|
%x(git ls-tree HEAD #{sub_repos.map(&:path).join(" ")}).split("\n").map do |line|
|
78
78
|
_, _, sub_hash, sub_path = line.split(" ")
|
79
|
-
sub_repo = Repository.
|
79
|
+
sub_repo = Repository.find(
|
80
80
|
path: path + "/" + sub_path,
|
81
81
|
)
|
82
82
|
sub_commit = Commit.find_or_create_by(
|
@@ -120,16 +120,9 @@ module Ballantine
|
|
120
120
|
true
|
121
121
|
end
|
122
122
|
|
123
|
-
# @return [String]
|
124
|
-
def print_last_commit
|
125
|
-
%x(git --no-pager log --reverse --format="#{check_format(ljust: DEFAULT_LJUST - 12)}" --abbrev=7 #{from.hash}..#{to.hash} -1).strip
|
126
|
-
end
|
127
|
-
|
128
123
|
private
|
129
124
|
|
130
|
-
def
|
131
|
-
self.class.send_type
|
132
|
-
end
|
125
|
+
def conf; Config.instance end
|
133
126
|
|
134
127
|
# @param [String] name
|
135
128
|
# @return [String] hash
|
@@ -141,16 +134,15 @@ module Ballantine
|
|
141
134
|
%x(git rev-list -n 1 #{name}).chomp[0...7]
|
142
135
|
end
|
143
136
|
|
144
|
-
# @param [Integer] ljust
|
145
137
|
# @return [String]
|
146
|
-
def check_format
|
147
|
-
case
|
148
|
-
when
|
138
|
+
def check_format
|
139
|
+
case conf.print_type
|
140
|
+
when Config::TYPE_TERMINAL
|
149
141
|
" - " + "%h".yellow + " %<(#{ljust})%s " + "#{url}/commit/%H".gray
|
150
|
-
when
|
142
|
+
when Config::TYPE_SLACK
|
151
143
|
"\\\`<#{url}/commit/%H|%h>\\\` %s - %an"
|
152
144
|
else
|
153
|
-
raise AssertionFailed, "Unknown
|
145
|
+
raise AssertionFailed, "Unknown print type: #{conf.print_type}"
|
154
146
|
end
|
155
147
|
end
|
156
148
|
|
@@ -187,19 +179,26 @@ module Ballantine
|
|
187
179
|
# @param [Author] author
|
188
180
|
# @return [Array<Commit>]
|
189
181
|
def retrieve_commits(author)
|
182
|
+
command = <<~CMD.tr("\n", " ").strip
|
183
|
+
git --no-pager log --reverse --no-merges --author="#{author.name}"
|
184
|
+
--format="%h#{PARSER_TOKEN}%H#{PARSER_TOKEN}%s"
|
185
|
+
--abbrev=7 #{from.hash}..#{to.hash}
|
186
|
+
CMD
|
190
187
|
results =
|
191
|
-
%x(
|
188
|
+
%x(#{command})
|
192
189
|
.gsub('"', '\"')
|
193
190
|
.gsub(/[\u0080-\u00ff]/, "")
|
194
191
|
.split("\n")
|
195
192
|
|
196
193
|
results.map do |result|
|
197
|
-
hash,
|
194
|
+
hash, long_hash, subject = result.split(PARSER_TOKEN)
|
198
195
|
Commit.find_or_create_by(
|
199
196
|
hash: hash,
|
200
197
|
repo: self,
|
201
|
-
|
198
|
+
).update(
|
202
199
|
author: author,
|
200
|
+
long_hash: long_hash,
|
201
|
+
subject: subject,
|
203
202
|
)
|
204
203
|
end
|
205
204
|
end
|
data/lib/ballantine/version.rb
CHANGED
data/lib/ballantine.rb
CHANGED
data/lib/printable.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Printable
|
4
|
+
# @param [String] msg
|
5
|
+
# @param [String] msg_r
|
6
|
+
# @return [NilClass]
|
7
|
+
def puts_r(msg, msg_r)
|
8
|
+
size = rjust_size(msg, msg_r)
|
9
|
+
puts msg + msg_r.rjust(size)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [String] msg
|
13
|
+
# @param [String] msg_r
|
14
|
+
# @return [Integer]
|
15
|
+
def rjust_size(msg, msg_r)
|
16
|
+
sanitized = ->(str) { str.sanitize_colored.size + str.scan(/\p{Hangul}/).size }
|
17
|
+
cols - sanitized.call(msg) - sanitized.call(msg_r) + msg_r.size
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Integer]
|
21
|
+
def cols
|
22
|
+
return @_cols if defined?(@_cols)
|
23
|
+
|
24
|
+
require "io/console"
|
25
|
+
_lines, @_cols = IO.console.winsize
|
26
|
+
@_cols
|
27
|
+
end
|
28
|
+
end
|
data/lib/string.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ballantine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.4.pre.
|
4
|
+
version: 0.1.4.pre.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- oohyun15
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- lib/ballantine/config.rb
|
56
56
|
- lib/ballantine/repository.rb
|
57
57
|
- lib/ballantine/version.rb
|
58
|
+
- lib/printable.rb
|
58
59
|
- lib/string.rb
|
59
60
|
homepage: https://github.com/oohyun15/ballantine
|
60
61
|
licenses:
|