hotspots 1.1.0 → 1.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 +7 -0
- data/CHANGELOG.md +10 -1
- data/LICENSE +1 -1
- data/README.md +7 -15
- data/TODO.md +0 -2
- data/bin/hotspots +9 -3
- data/lib/hotspots/configuration.rb +36 -0
- data/lib/hotspots/{option_based_exit.rb → exit.rb} +4 -4
- data/lib/hotspots/options_parser.rb +21 -39
- data/lib/hotspots/repository/git.rb +17 -0
- data/lib/hotspots/repository/git_command.rb +38 -0
- data/lib/hotspots/repository/git_driver.rb +35 -0
- data/lib/hotspots/repository/git_parser.rb +25 -0
- data/lib/hotspots/repository.rb +5 -3
- data/lib/hotspots/store.rb +2 -2
- data/lib/hotspots/version.rb +1 -1
- data/lib/hotspots.rb +32 -53
- data/test/hotspots/configuration_test.rb +65 -0
- data/test/hotspots/options_parser_test.rb +91 -119
- data/test/hotspots/repository/git_command_test.rb +39 -0
- data/test/hotspots/repository/git_parser_test.rb +88 -0
- data/test/hotspots/store_test.rb +13 -13
- data/test/minitest_helper.rb +8 -5
- metadata +57 -73
- data/lib/hotspots/compatibility.rb +0 -4
- data/lib/hotspots/logger.rb +0 -58
- data/lib/hotspots/repository/command/git.rb +0 -40
- data/lib/hotspots/repository/command.rb +0 -1
- data/lib/hotspots/repository/driver/git.rb +0 -27
- data/lib/hotspots/repository/driver.rb +0 -1
- data/lib/hotspots/repository/parser/git.rb +0 -27
- data/lib/hotspots/repository/parser.rb +0 -1
- data/test/hotspots/repository/command/git_test.rb +0 -39
- data/test/hotspots/repository/parser/git_test.rb +0 -84
metadata
CHANGED
@@ -1,89 +1,75 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotspots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Chirantan Mitra
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2024-03-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: ansi
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: 1.5.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: 1.5.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
33
|
+
version: 13.1.0
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
40
|
+
version: 13.1.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: minitest
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
47
|
+
version: 5.22.2
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
54
|
+
version: 5.22.2
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: simplecov
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
61
|
+
version: 0.22.0
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
78
|
-
description:
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
have a corresponding
|
83
|
-
|
84
|
-
test change.
|
85
|
-
|
86
|
-
'
|
68
|
+
version: 0.22.0
|
69
|
+
description: |
|
70
|
+
Find all files that changed over the past days for a git repository. If a file
|
71
|
+
is modified multiple times, it may require a re-design. Watch out for
|
72
|
+
implementation changes without a corresponding test change.
|
87
73
|
email:
|
88
74
|
- chirantan.mitra@gmail.com
|
89
75
|
executables:
|
@@ -91,57 +77,55 @@ executables:
|
|
91
77
|
extensions: []
|
92
78
|
extra_rdoc_files: []
|
93
79
|
files:
|
80
|
+
- CHANGELOG.md
|
81
|
+
- LICENSE
|
82
|
+
- README.md
|
83
|
+
- TODO.md
|
84
|
+
- bin/hotspots
|
85
|
+
- lib/hotspots.rb
|
86
|
+
- lib/hotspots/configuration.rb
|
87
|
+
- lib/hotspots/exit.rb
|
94
88
|
- lib/hotspots/options_parser.rb
|
95
|
-
- lib/hotspots/version.rb
|
96
|
-
- lib/hotspots/option_based_exit.rb
|
97
|
-
- lib/hotspots/logger.rb
|
98
89
|
- lib/hotspots/repository.rb
|
99
|
-
- lib/hotspots/repository/
|
100
|
-
- lib/hotspots/repository/
|
101
|
-
- lib/hotspots/repository/
|
102
|
-
- lib/hotspots/repository/
|
103
|
-
- lib/hotspots/repository/parser.rb
|
104
|
-
- lib/hotspots/repository/parser/git.rb
|
90
|
+
- lib/hotspots/repository/git.rb
|
91
|
+
- lib/hotspots/repository/git_command.rb
|
92
|
+
- lib/hotspots/repository/git_driver.rb
|
93
|
+
- lib/hotspots/repository/git_parser.rb
|
105
94
|
- lib/hotspots/store.rb
|
106
|
-
- lib/hotspots/
|
107
|
-
-
|
108
|
-
- bin/hotspots
|
109
|
-
- test/minitest_helper.rb
|
110
|
-
- test/hotspots/repository/command/git_test.rb
|
111
|
-
- test/hotspots/repository/parser/git_test.rb
|
112
|
-
- test/hotspots/store_test.rb
|
95
|
+
- lib/hotspots/version.rb
|
96
|
+
- test/hotspots/configuration_test.rb
|
113
97
|
- test/hotspots/options_parser_test.rb
|
114
|
-
-
|
115
|
-
-
|
116
|
-
-
|
117
|
-
-
|
98
|
+
- test/hotspots/repository/git_command_test.rb
|
99
|
+
- test/hotspots/repository/git_parser_test.rb
|
100
|
+
- test/hotspots/store_test.rb
|
101
|
+
- test/minitest_helper.rb
|
118
102
|
homepage: https://github.com/chiku/hotspots
|
119
|
-
licenses:
|
120
|
-
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
121
107
|
rdoc_options: []
|
122
108
|
require_paths:
|
123
109
|
- lib
|
124
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
-
none: false
|
126
111
|
requirements:
|
127
|
-
- -
|
112
|
+
- - ">="
|
128
113
|
- !ruby/object:Gem::Version
|
129
|
-
version:
|
114
|
+
version: 3.0.0
|
130
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
-
none: false
|
132
116
|
requirements:
|
133
|
-
- -
|
117
|
+
- - ">="
|
134
118
|
- !ruby/object:Gem::Version
|
135
119
|
version: '0'
|
136
120
|
requirements: []
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
summary: Find all files that changed over the past in a git repository based on conditions
|
121
|
+
rubygems_version: 3.3.7
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Find the files in a git repository that changed the most in recent past
|
142
125
|
test_files:
|
143
|
-
- test/
|
144
|
-
- test/hotspots/repository/command/git_test.rb
|
145
|
-
- test/hotspots/repository/parser/git_test.rb
|
146
|
-
- test/hotspots/store_test.rb
|
126
|
+
- test/hotspots/configuration_test.rb
|
147
127
|
- test/hotspots/options_parser_test.rb
|
128
|
+
- test/hotspots/repository/git_command_test.rb
|
129
|
+
- test/hotspots/repository/git_parser_test.rb
|
130
|
+
- test/hotspots/store_test.rb
|
131
|
+
- test/minitest_helper.rb
|
data/lib/hotspots/logger.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
class Hotspots
|
2
|
-
# TODO : Should understand log levels
|
3
|
-
class Logger #:nodoc: all
|
4
|
-
module Sink
|
5
|
-
class Console
|
6
|
-
def self.<<(message)
|
7
|
-
$stdout << message
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class Null
|
12
|
-
def self.<<(message)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
module Colour
|
18
|
-
class ANSI
|
19
|
-
def self.as(colour, message)
|
20
|
-
::ANSI::Code.send(colour, message)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class Null
|
25
|
-
def self.as(colour, message)
|
26
|
-
message
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_reader :sink, :colour
|
32
|
-
|
33
|
-
def initialize
|
34
|
-
@sink = Sink::Null
|
35
|
-
@colour = Colour::Null
|
36
|
-
end
|
37
|
-
|
38
|
-
def as_console
|
39
|
-
@sink = Sink::Console
|
40
|
-
end
|
41
|
-
|
42
|
-
def colourize
|
43
|
-
require 'ansi/code'
|
44
|
-
@colour = Colour::ANSI
|
45
|
-
end
|
46
|
-
|
47
|
-
def log(message, options = {})
|
48
|
-
sink << format(message, options)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# Time stampimg should be part of log level
|
54
|
-
def format(message, options = {})
|
55
|
-
colour.as(options[:as] || "black", "[#{Time.now}] #{message}\n")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
class Hotspots
|
2
|
-
module Repository #:nodoc: all
|
3
|
-
module Command
|
4
|
-
module Git
|
5
|
-
class Log
|
6
|
-
attr_reader :since_days, :message_filter
|
7
|
-
|
8
|
-
def initialize(options)
|
9
|
-
@since_days = options[:since_days]
|
10
|
-
@message_filter = options[:message_filter].to_s
|
11
|
-
end
|
12
|
-
|
13
|
-
def build
|
14
|
-
"git log --pretty=\"%H\" #{since_clause}#{grep_clause}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def since_clause
|
18
|
-
"--since=\"#{since_days} days ago\""
|
19
|
-
end
|
20
|
-
|
21
|
-
def grep_clause
|
22
|
-
message_filter.empty? ? "" : " --grep \"#{message_filter}\""
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Show
|
27
|
-
attr_reader :commit_hash
|
28
|
-
|
29
|
-
def initialize(options)
|
30
|
-
@commit_hash = options[:commit_hash]
|
31
|
-
end
|
32
|
-
|
33
|
-
def build
|
34
|
-
"git show --oneline --name-only #{commit_hash}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'hotspots/repository/command/git'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
class Hotspots
|
2
|
-
module Repository #:nodoc: all
|
3
|
-
module Driver
|
4
|
-
class Git
|
5
|
-
attr_reader :logger
|
6
|
-
|
7
|
-
def initialize(logger)
|
8
|
-
@logger = logger
|
9
|
-
end
|
10
|
-
|
11
|
-
def pretty_log(options)
|
12
|
-
command = log_with_tag("Input", :as => :green) { Command::Git::Log.new(:since_days => options[:since_days], :message_filter => options[:message_filter]).build }
|
13
|
-
log_with_tag("Output", :as => :red) { %x(#{command}) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def show_one_line_names(options)
|
17
|
-
command = log_with_tag("Input", :as => :green) { Command::Git::Show.new(:commit_hash => options[:commit_hash]).build }
|
18
|
-
log_with_tag("Output", :as => :red) { %x(#{command}) }
|
19
|
-
end
|
20
|
-
|
21
|
-
def log_with_tag(tag, options, &block)
|
22
|
-
yield.tap { |raw| logger.log("<#{tag}>\n#{raw}<#{tag}/>", :as => options[:as]) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'hotspots/repository/driver/git'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
class Hotspots
|
2
|
-
module Repository #:nodoc: all
|
3
|
-
module Parser
|
4
|
-
class Git
|
5
|
-
attr_reader :driver, :time, :message_filters
|
6
|
-
|
7
|
-
def initialize(driver, options)
|
8
|
-
@driver = driver
|
9
|
-
@time = options[:time]
|
10
|
-
@message_filters = options[:message_filters]
|
11
|
-
end
|
12
|
-
|
13
|
-
def files
|
14
|
-
filtered_commit_hashes.reduce([]) do |acc, commit_hash|
|
15
|
-
acc + driver.show_one_line_names(:commit_hash => commit_hash).lines.map(&:strip)[1..-1]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def filtered_commit_hashes
|
20
|
-
message_filters.reduce([]) do |acc, filter|
|
21
|
-
acc + driver.pretty_log(:since_days => time, :message_filter => filter).lines.map(&:strip)
|
22
|
-
end.uniq
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'hotspots/repository/parser/git'
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', '..', 'minitest_helper')
|
2
|
-
|
3
|
-
module Hotspots::Repository
|
4
|
-
describe "Command::Git" do
|
5
|
-
describe "Log" do
|
6
|
-
describe "#build" do
|
7
|
-
describe "when message filter exists" do
|
8
|
-
it "includes a grep clause" do
|
9
|
-
log_command = Command::Git::Log.new :since_days => 20, :message_filter => "Foo|Bar"
|
10
|
-
log_command.build.must_equal 'git log --pretty="%H" --since="20 days ago" --grep "Foo|Bar"'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "when message filter doesn't exist" do
|
15
|
-
it "doesn't have a grep clause" do
|
16
|
-
log_command = Command::Git::Log.new :since_days => 20
|
17
|
-
log_command.build.must_equal 'git log --pretty="%H" --since="20 days ago"'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "when message filter is set to an empty string" do
|
22
|
-
it "grep clause is ignored" do
|
23
|
-
log_command = Command::Git::Log.new :since_days => 20, :message_filter => ""
|
24
|
-
log_command.build.must_equal 'git log --pretty="%H" --since="20 days ago"'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "Show" do
|
31
|
-
describe "#build" do
|
32
|
-
it "constructs a git show with one-line format" do
|
33
|
-
show_command = Command::Git::Show.new :commit_hash => "abc123"
|
34
|
-
show_command.build.must_equal 'git show --oneline --name-only abc123'
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', '..', 'minitest_helper')
|
2
|
-
|
3
|
-
module Hotspots::Repository
|
4
|
-
describe "Parser::Git" do
|
5
|
-
it "fetches a commit hash based on filter and time" do
|
6
|
-
mock_git_driver = MiniTest::Mock.new
|
7
|
-
options = {:time => 10, :message_filters => ["Foo"]}
|
8
|
-
git_parser = Parser::Git.new mock_git_driver, options
|
9
|
-
|
10
|
-
mock_git_driver.expect(:pretty_log, "SHA1\nSHA2", [:since_days => options[:time], :message_filter => "Foo"])
|
11
|
-
|
12
|
-
git_parser.filtered_commit_hashes.must_equal(["SHA1", "SHA2"])
|
13
|
-
|
14
|
-
assert mock_git_driver.verify
|
15
|
-
end
|
16
|
-
|
17
|
-
it "fetches multiple commit hashes" do
|
18
|
-
options = {:time => 10, :message_filters => ["Foo", "Bar"]}
|
19
|
-
git_parser = Parser::Git.new StubGitDriver.new, options
|
20
|
-
|
21
|
-
git_parser.filtered_commit_hashes.must_equal(["SHA1", "SHA2", "SHA3"])
|
22
|
-
end
|
23
|
-
|
24
|
-
it "finds all affected files for a commit message" do
|
25
|
-
mock_git_driver = MiniTest::Mock.new
|
26
|
-
options = {:time => 10, :message_filters => ["Foo"]}
|
27
|
-
git_parser = Parser::Git.new mock_git_driver, options
|
28
|
-
|
29
|
-
mock_git_driver.expect(:pretty_log, "SHA1", [:since_days => options[:time], :message_filter => "Foo"])
|
30
|
-
mock_git_driver.expect(:show_one_line_names, "SHA1 CommitMessage\nfile1\nfile2", [:commit_hash => "SHA1"])
|
31
|
-
|
32
|
-
git_parser.files.must_equal(["file1", "file2"])
|
33
|
-
|
34
|
-
assert mock_git_driver.verify
|
35
|
-
end
|
36
|
-
|
37
|
-
it "finds all affected files for multiple commit messages" do
|
38
|
-
options = {:time => 10, :message_filters => ["Foo", "Bar"]}
|
39
|
-
git_parser = Parser::Git.new StubGitDriver.new, options
|
40
|
-
|
41
|
-
git_parser.files.must_equal(["file1", "file2", "file2", "file3", "file5", "file4"])
|
42
|
-
end
|
43
|
-
|
44
|
-
it "handles line ending" do
|
45
|
-
options = {:time => 10, :message_filters => ["Foo", "Bar"]}
|
46
|
-
git_parser = Parser::Git.new StubGitDriver.new, options
|
47
|
-
|
48
|
-
git_parser.files.must_equal(["file1", "file2", "file2", "file3", "file5", "file4"])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "git driver stub" do
|
53
|
-
it "has a sane pretty log" do
|
54
|
-
driver = StubGitDriver.new
|
55
|
-
driver.pretty_log(:time => 10, :message_filter => "Foo").must_equal "SHA1\nSHA2"
|
56
|
-
driver.pretty_log(:time => 10, :message_filter => "Bar").must_equal "SHA2\nSHA3"
|
57
|
-
end
|
58
|
-
|
59
|
-
it "has a sane show one line names" do
|
60
|
-
StubGitDriver.new.show_one_line_names(:commit_hash => "SHA2").
|
61
|
-
must_equal "SHA1 commit message\nfile2\nfile3\nfile5"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class StubGitDriver
|
66
|
-
def initialize
|
67
|
-
line_ending = "\n"
|
68
|
-
@pretty_log_enum = ["SHA1#{line_ending}SHA2", "SHA2#{line_ending}SHA3"].cycle
|
69
|
-
@commits = {
|
70
|
-
"SHA1" => "SHA1 commit message#{line_ending}file1#{line_ending}file2",
|
71
|
-
"SHA2" => "SHA1 commit message#{line_ending}file2#{line_ending}file3#{line_ending}file5",
|
72
|
-
"SHA3" => "SHA1 commit message#{line_ending}file4",
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
def pretty_log(options)
|
77
|
-
@pretty_log_enum.next
|
78
|
-
end
|
79
|
-
|
80
|
-
def show_one_line_names(options)
|
81
|
-
@commits[options[:commit_hash]]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|