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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f4eb5790313a7a672cad41fcf05c8c5515659f265a60952efbf3bb28fad7fb1
4
- data.tar.gz: 0b94a1a09d207f79c9a32414655c4ec9706f47323659fc64d7f433f60ded012b
3
+ metadata.gz: d9c150c481f0b0f1bc38b7cf18e533355f558952b9e9bf3ba0023fae00358468
4
+ data.tar.gz: afd7fb850269de77370ae157b3d2826989382a4bc0f6d620f1179d892832953c
5
5
  SHA512:
6
- metadata.gz: 52c4ba88c4e15d3e947c0022b15f3da7477f7e8d5d7fbda9a0b43d7e8e61e13da446c59b7b6e54f425e32c31bf008bdbe1e3f19021f25c3c9ce728630e4eb586
7
- data.tar.gz: 34b2ad121d67f463e93f1cb19153dba16764e33b59e73aef0a7e7704610b695d6a5320fd8a19bb4108787973aa19cc4ad1a3a2b56aa6e4e76835df034de8138c
6
+ metadata.gz: f46258854224c3b0ef37cb94d4d7aaefffc1121d4614508db3957bc20ad01615f0625372a55d6e55144719f685df85b975d322e706f379aaab0d67642cbfe879
7
+ data.tar.gz: b5c489850eb1fc83ab6bcfd7795a26a234f0bb4cefa09f662e3d3232c55e7b726002b4d176ac39d72076499cf11552cb05f90cf4b23d8c2738784fc2dfc60492
data/exe/zubat CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'zubat/cli'
4
+ require 'zubat/cli/app'
5
5
 
6
- Zubat::CLI.new.start(ARGV)
6
+ Zubat::CLI::App.new.start(ARGV)
@@ -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})", stat:)
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
@@ -4,8 +4,10 @@ module Zubat
4
4
  class Generator
5
5
  FILE = 'tmp/zubat/index.html'
6
6
 
7
- def generate(results:)
8
- erb = Zubat.root.join('templates/chart.html.erb').read
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zubat
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
@@ -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 chart3 = null;
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 (chart3) chart3.destroy();
425
+ if (chart2) chart2.destroy();
404
426
 
405
- chart3 = new Chart(ctx2, {
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.1
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-08 00:00:00.000000000 Z
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