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