zubat 0.0.1 → 0.0.2
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/exe/zubat +2 -2
- data/lib/zubat/analizer.rb +4 -2
- data/lib/zubat/cli/app.rb +98 -0
- data/lib/zubat/generator.rb +6 -3
- data/lib/zubat/git_command_wrapper.rb +8 -0
- data/lib/zubat/version.rb +1 -1
- data/templates/chart.html.erb +31 -7
- metadata +3 -3
- data/lib/zubat/cli.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9c150c481f0b0f1bc38b7cf18e533355f558952b9e9bf3ba0023fae00358468
|
4
|
+
data.tar.gz: afd7fb850269de77370ae157b3d2826989382a4bc0f6d620f1179d892832953c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f46258854224c3b0ef37cb94d4d7aaefffc1121d4614508db3957bc20ad01615f0625372a55d6e55144719f685df85b975d322e706f379aaab0d67642cbfe879
|
7
|
+
data.tar.gz: b5c489850eb1fc83ab6bcfd7795a26a234f0bb4cefa09f662e3d3232c55e7b726002b4d176ac39d72076499cf11552cb05f90cf4b23d8c2738784fc2dfc60492
|
data/exe/zubat
CHANGED
data/lib/zubat/analizer.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Zubat
|
4
4
|
class Analizer
|
5
|
-
AnalizedResult = Data.define(:label, :stat)
|
5
|
+
AnalizedResult = Data.define(:label, :commit, :stat)
|
6
6
|
|
7
7
|
# @param stat [Hash<String, Hash<String, Integer>>]
|
8
8
|
Stat = Data.define(:stat) do
|
@@ -50,7 +50,9 @@ module Zubat
|
|
50
50
|
|
51
51
|
stat = Stat.new(stat:)
|
52
52
|
|
53
|
-
AnalizedResult.new(label: "#{commit.time.iso8601} (#{commit.sha})",
|
53
|
+
AnalizedResult.new(label: "#{commit.time.iso8601} (#{commit.sha})",
|
54
|
+
commit:,
|
55
|
+
stat:)
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zubat'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
module Zubat
|
7
|
+
module CLI
|
8
|
+
class App
|
9
|
+
Argv = Data.define(:files, :silent, :root) do
|
10
|
+
def self.parse!(argv)
|
11
|
+
opt = OptionParser.new
|
12
|
+
|
13
|
+
root = nil
|
14
|
+
silent = false
|
15
|
+
|
16
|
+
opt.on('--silent', '-s') { silent = true }
|
17
|
+
opt.on('--root=ROOT') { |v| root = v }
|
18
|
+
|
19
|
+
files = opt.parse!(argv).uniq
|
20
|
+
|
21
|
+
abort 'no files to process, aborting.' if argv.empty?
|
22
|
+
|
23
|
+
new(files:, silent:, root:)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class GitRepo
|
28
|
+
URL_FORMATS = [
|
29
|
+
%r[https://(.+)/(.+)/(.+).git],
|
30
|
+
%r[git@(.+):(.+)/(.+).git],
|
31
|
+
]
|
32
|
+
|
33
|
+
def self.guess
|
34
|
+
url = GitCommandWrapper.new.remote_origin_url
|
35
|
+
|
36
|
+
matched = URL_FORMATS
|
37
|
+
.find { |format| format.match?(url) }
|
38
|
+
&.match(url)
|
39
|
+
|
40
|
+
return unless matched
|
41
|
+
|
42
|
+
new(hostname: matched[1], org: matched[2], repo: matched[3])
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(hostname:, org:, repo:)
|
46
|
+
@hostname = hostname
|
47
|
+
@org = org
|
48
|
+
@repo = repo
|
49
|
+
end
|
50
|
+
|
51
|
+
def site_url
|
52
|
+
"https://#{@hostname}/#{@org}/#{@repo}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Progress
|
57
|
+
include Enumerable
|
58
|
+
|
59
|
+
def initialize(enum, silent:)
|
60
|
+
@enum = enum
|
61
|
+
@silent = silent
|
62
|
+
end
|
63
|
+
|
64
|
+
def each(&block)
|
65
|
+
@enum.each_with_index do |elem, i|
|
66
|
+
$stderr.print "\r#{%w[| / - \\][i % 4]} Analyzing... #{100 * i / @enum.size}%" unless @silent
|
67
|
+
|
68
|
+
block.call(elem)
|
69
|
+
end
|
70
|
+
|
71
|
+
warn "\r✨ Analized \n\n" unless @silent
|
72
|
+
|
73
|
+
@enum
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def start(argv)
|
78
|
+
argv = Argv.parse!(argv)
|
79
|
+
|
80
|
+
files = argv.files
|
81
|
+
|
82
|
+
repo = GitRepo.guess
|
83
|
+
|
84
|
+
results = Dir.chdir(argv.root || Dir.pwd) do
|
85
|
+
commits = Zubat::Commit.find(files:)
|
86
|
+
|
87
|
+
Progress
|
88
|
+
.new(commits, silent: argv.silent)
|
89
|
+
.map { |commit| Zubat::Analizer.new.analize(files:, commit:) }
|
90
|
+
end
|
91
|
+
|
92
|
+
file = Generator.new.generate(results:, site_url: repo&.site_url)
|
93
|
+
|
94
|
+
puts "Generated - #{file}\n"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/zubat/generator.rb
CHANGED
@@ -4,8 +4,10 @@ module Zubat
|
|
4
4
|
class Generator
|
5
5
|
FILE = 'tmp/zubat/index.html'
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
TEMPLATE = 'templates/chart.html.erb'
|
8
|
+
|
9
|
+
def generate(results:, site_url:)
|
10
|
+
erb = Zubat.root.join(TEMPLATE).read
|
9
11
|
|
10
12
|
ylabels = []
|
11
13
|
|
@@ -33,6 +35,7 @@ module Zubat
|
|
33
35
|
|
34
36
|
dataset[:data] << {
|
35
37
|
label: xlabel,
|
38
|
+
commit_sha: result.commit.sha,
|
36
39
|
complexity_total: result.stat.complexity_total(ylabel),
|
37
40
|
complexity_average: result.stat.complexity_average(ylabel),
|
38
41
|
smells_scores: result.stat.smell_scores(ylabel).map { |type, value| { type:, value: } }
|
@@ -40,7 +43,7 @@ module Zubat
|
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
|
-
html = ERB.new(erb).result_with_hash(datasets:)
|
46
|
+
html = ERB.new(erb).result_with_hash(datasets:, site_url:)
|
44
47
|
|
45
48
|
file = File.expand_path(FILE)
|
46
49
|
|
@@ -7,6 +7,10 @@ require 'securerandom'
|
|
7
7
|
module Zubat
|
8
8
|
class GitCommandWrapper
|
9
9
|
module Stub
|
10
|
+
def remote_origin_url
|
11
|
+
"https://github.com/mizoR/zubat.git"
|
12
|
+
end
|
13
|
+
|
10
14
|
def log(files:)
|
11
15
|
logs = files.map do
|
12
16
|
Log.new(sha: SecureRandom.hex(3), time: Time.at(rand(1_900_000_000..1_900_999_999)))
|
@@ -42,6 +46,10 @@ module Zubat
|
|
42
46
|
instance
|
43
47
|
end
|
44
48
|
|
49
|
+
def remote_origin_url
|
50
|
+
`git config --get remote.origin.url`.chomp
|
51
|
+
end
|
52
|
+
|
45
53
|
def log(files:)
|
46
54
|
logs = `git log --oneline --pretty=format:'{ "sha": "%h", "time": "%ad" }' -- #{files.join(' ')}`.split("\n")
|
47
55
|
|
data/lib/zubat/version.rb
CHANGED
data/templates/chart.html.erb
CHANGED
@@ -308,11 +308,31 @@
|
|
308
308
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
309
309
|
|
310
310
|
<script>
|
311
|
+
var siteUrl = <%= site_url.to_json %>;
|
312
|
+
|
311
313
|
var datasets = <%= datasets.to_json %>;
|
312
314
|
|
315
|
+
var onClickWith = function (chart) {
|
316
|
+
return function (e) {
|
317
|
+
const points = chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, true);
|
318
|
+
|
319
|
+
if (points.length === 0) return;
|
320
|
+
|
321
|
+
const point = points[0];
|
322
|
+
const label = chart.data.labels[point.index];
|
323
|
+
const value = chart.data.datasets[point.datasetIndex].data[point.index];
|
324
|
+
|
325
|
+
if (siteUrl) {
|
326
|
+
const url = siteUrl + '/commit/' + value.commit_sha;
|
327
|
+
|
328
|
+
open(url, '_blank');
|
329
|
+
}
|
330
|
+
};
|
331
|
+
};
|
332
|
+
|
313
333
|
var ctx0 = document.getElementById("chart_of_code_complexity_total_trend");
|
314
334
|
|
315
|
-
new Chart(ctx0, {
|
335
|
+
var chart0 = new Chart(ctx0, {
|
316
336
|
type: 'line',
|
317
337
|
data: {
|
318
338
|
datasets: datasets
|
@@ -333,9 +353,11 @@
|
|
333
353
|
}
|
334
354
|
});
|
335
355
|
|
356
|
+
ctx0.addEventListener('click', onClickWith(chart0));
|
357
|
+
|
336
358
|
var ctx1 = document.getElementById("chart_of_code_complexity_average_trend");
|
337
359
|
|
338
|
-
new Chart(ctx1, {
|
360
|
+
var chart1 = new Chart(ctx1, {
|
339
361
|
type: 'line',
|
340
362
|
data: {
|
341
363
|
datasets: datasets
|
@@ -356,6 +378,8 @@
|
|
356
378
|
}
|
357
379
|
});
|
358
380
|
|
381
|
+
ctx1.addEventListener('click', onClickWith(chart1));
|
382
|
+
|
359
383
|
var ctx2 = document.getElementById("chart_of_code_smell_scores_trend");
|
360
384
|
|
361
385
|
var select = document.createElement('select');
|
@@ -369,8 +393,6 @@
|
|
369
393
|
select.add(option);
|
370
394
|
});
|
371
395
|
|
372
|
-
|
373
|
-
|
374
396
|
select.addEventListener('change', function () {
|
375
397
|
var file = select.value;
|
376
398
|
|
@@ -379,7 +401,7 @@
|
|
379
401
|
|
380
402
|
document.getElementById("select_of_code_smell_scores_trend").appendChild(select);
|
381
403
|
|
382
|
-
var
|
404
|
+
var chart2 = null;
|
383
405
|
|
384
406
|
var showCodeSmellChartFor = function (file) {
|
385
407
|
var data = datasets.find(item => item.label === file).data;
|
@@ -400,9 +422,9 @@
|
|
400
422
|
};
|
401
423
|
});
|
402
424
|
|
403
|
-
if (
|
425
|
+
if (chart2) chart2.destroy();
|
404
426
|
|
405
|
-
|
427
|
+
chart2 = new Chart(ctx2, {
|
406
428
|
type: 'line',
|
407
429
|
data: {
|
408
430
|
datasets: smellsets
|
@@ -422,6 +444,8 @@
|
|
422
444
|
}
|
423
445
|
}
|
424
446
|
});
|
447
|
+
|
448
|
+
ctx2.addEventListener('click', onClickWith(chart2));
|
425
449
|
};
|
426
450
|
|
427
451
|
showCodeSmellChartFor(datasets[0].label);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zubat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mizokami
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: flog
|
@@ -54,7 +54,7 @@ files:
|
|
54
54
|
- exe/zubat
|
55
55
|
- lib/zubat.rb
|
56
56
|
- lib/zubat/analizer.rb
|
57
|
-
- lib/zubat/cli.rb
|
57
|
+
- lib/zubat/cli/app.rb
|
58
58
|
- lib/zubat/commit.rb
|
59
59
|
- lib/zubat/flog_wrapper.rb
|
60
60
|
- lib/zubat/generator.rb
|
data/lib/zubat/cli.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'zubat'
|
4
|
-
require 'optparse'
|
5
|
-
|
6
|
-
module Zubat
|
7
|
-
class CLI
|
8
|
-
Argv = Data.define(:files, :silent, :root) do
|
9
|
-
def self.parse!(argv)
|
10
|
-
opt = OptionParser.new
|
11
|
-
|
12
|
-
root = nil
|
13
|
-
silent = false
|
14
|
-
|
15
|
-
opt.on('--silent', '-s') { silent = true }
|
16
|
-
opt.on('--root=ROOT') { |v| root = v }
|
17
|
-
|
18
|
-
files = opt.parse!(argv)
|
19
|
-
|
20
|
-
abort 'no files to process, aborting.' if files.empty? && argv.empty?
|
21
|
-
|
22
|
-
Dir.chdir(root || Dir.pwd) do
|
23
|
-
files = files.uniq
|
24
|
-
end
|
25
|
-
|
26
|
-
new(files:, silent:, root:)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class Progress
|
31
|
-
include Enumerable
|
32
|
-
|
33
|
-
def initialize(enum, silent:)
|
34
|
-
@enum = enum
|
35
|
-
@silent = silent
|
36
|
-
end
|
37
|
-
|
38
|
-
def each(&block)
|
39
|
-
@enum.each_with_index do |elem, i|
|
40
|
-
$stderr.print "\r#{%w[| / - \\][i % 4]} Analyzing... #{100 * i / @enum.size}%" unless @silent
|
41
|
-
|
42
|
-
block.call(elem)
|
43
|
-
end
|
44
|
-
|
45
|
-
warn "\r✨ Analized \n\n" unless @silent
|
46
|
-
|
47
|
-
@enum
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def start(argv)
|
52
|
-
argv = Argv.parse!(argv)
|
53
|
-
|
54
|
-
generator = Generator.new
|
55
|
-
|
56
|
-
results = Dir.chdir(argv.root || Dir.pwd) do
|
57
|
-
files = argv.files
|
58
|
-
|
59
|
-
analizer = Zubat::Analizer.new
|
60
|
-
|
61
|
-
commits = Zubat::Commit.find(files:)
|
62
|
-
|
63
|
-
progress = Progress.new(commits, silent: argv.silent)
|
64
|
-
|
65
|
-
progress.map { |commit| analizer.analize(files:, commit:) }
|
66
|
-
end
|
67
|
-
|
68
|
-
file = generator.generate(results:)
|
69
|
-
|
70
|
-
puts "Generated - #{file}\n"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|