rubycritic 0.0.5 → 0.0.16

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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -0
  3. data/README.md +72 -11
  4. data/bin/rubycritic +2 -0
  5. data/lib/rubycritic/adapters/complexity/flog.rb +22 -0
  6. data/lib/rubycritic/adapters/smell/flay.rb +68 -0
  7. data/lib/rubycritic/adapters/smell/flog.rb +62 -0
  8. data/lib/rubycritic/adapters/smell/reek.rb +44 -0
  9. data/lib/rubycritic/analysers/churn.rb +19 -0
  10. data/lib/rubycritic/analysers/config.reek +8 -0
  11. data/lib/rubycritic/analysers/flay.rb +15 -0
  12. data/lib/rubycritic/analysers/flog.rb +1 -2
  13. data/lib/rubycritic/analysers/stats.rb +31 -0
  14. data/lib/rubycritic/analysers_runner.rb +15 -14
  15. data/lib/rubycritic/cli.rb +35 -14
  16. data/lib/rubycritic/configuration.rb +24 -0
  17. data/lib/rubycritic/core/analysed_file.rb +50 -0
  18. data/lib/rubycritic/{location.rb → core/location.rb} +6 -2
  19. data/lib/rubycritic/core/rating.rb +22 -0
  20. data/lib/rubycritic/{smell.rb → core/smell.rb} +5 -12
  21. data/lib/rubycritic/files_initializer.rb +15 -0
  22. data/lib/rubycritic/orchestrator.rb +23 -0
  23. data/lib/rubycritic/report_generators/assets/javascripts/application.js +87 -8
  24. data/lib/rubycritic/report_generators/assets/javascripts/highcharts.src-4.0.1.js +17672 -0
  25. data/lib/rubycritic/report_generators/assets/javascripts/jquery.floatThead-v1.2.7.js +754 -0
  26. data/lib/rubycritic/report_generators/assets/javascripts/jquery.scrollTo-1.4.11.js +186 -0
  27. data/lib/rubycritic/report_generators/assets/javascripts/jquery.tablesorter-2.0.js +1031 -0
  28. data/lib/rubycritic/report_generators/assets/javascripts/jquery.timeago-v1.4.1.js +214 -0
  29. data/lib/rubycritic/report_generators/assets/stylesheets/application.css +204 -1
  30. data/lib/rubycritic/report_generators/assets/stylesheets/prettify.custom_theme.css +1 -4
  31. data/lib/rubycritic/report_generators/base.rb +49 -0
  32. data/lib/rubycritic/report_generators/code_file.rb +38 -0
  33. data/lib/rubycritic/report_generators/code_index.rb +24 -0
  34. data/lib/rubycritic/report_generators/current_code_file.rb +17 -0
  35. data/lib/rubycritic/report_generators/line.rb +31 -0
  36. data/lib/rubycritic/report_generators/overview.rb +25 -0
  37. data/lib/rubycritic/report_generators/smells_index.rb +24 -0
  38. data/lib/rubycritic/report_generators/templates/code_file.html.erb +36 -0
  39. data/lib/rubycritic/report_generators/templates/code_index.html.erb +26 -0
  40. data/lib/rubycritic/report_generators/templates/layouts/application.html.erb +27 -16
  41. data/lib/rubycritic/report_generators/templates/overview.html.erb +5 -0
  42. data/lib/rubycritic/report_generators/templates/smells_index.html.erb +20 -0
  43. data/lib/rubycritic/report_generators/view_helpers.rb +28 -9
  44. data/lib/rubycritic/reporters/base.rb +24 -0
  45. data/lib/rubycritic/reporters/main.rb +52 -0
  46. data/lib/rubycritic/reporters/mini.rb +30 -0
  47. data/lib/rubycritic/revision_comparator.rb +21 -28
  48. data/lib/rubycritic/serializer.rb +32 -0
  49. data/lib/rubycritic/smells_status_setter.rb +7 -16
  50. data/lib/rubycritic/source_control_systems/base.rb +60 -0
  51. data/lib/rubycritic/source_control_systems/double.rb +19 -0
  52. data/lib/rubycritic/source_control_systems/git.rb +47 -37
  53. data/lib/rubycritic/source_locator.rb +8 -12
  54. data/lib/rubycritic/turbulence.rb +17 -0
  55. data/lib/rubycritic/version.rb +1 -1
  56. data/lib/rubycritic.rb +2 -27
  57. data/rubycritic.gemspec +3 -0
  58. data/test/lib/rubycritic/adapters/complexity/flog_test.rb +18 -0
  59. data/test/lib/rubycritic/adapters/smell/flay_test.rb +34 -0
  60. data/test/lib/rubycritic/adapters/smell/flog_test.rb +26 -0
  61. data/test/lib/rubycritic/adapters/smell/reek_test.rb +35 -0
  62. data/test/lib/rubycritic/analysers/churn_test.rb +38 -0
  63. data/test/lib/rubycritic/configuration_test.rb +17 -0
  64. data/test/lib/rubycritic/core/analysed_file_test.rb +71 -0
  65. data/test/lib/rubycritic/{location_test.rb → core/location_test.rb} +8 -4
  66. data/test/lib/rubycritic/core/smell_test.rb +73 -0
  67. data/test/lib/rubycritic/{smells_array_test.rb → core/smells_array_test.rb} +1 -1
  68. data/test/lib/rubycritic/smells_status_setter_test.rb +5 -5
  69. data/test/lib/rubycritic/source_control_systems/source_control_system_test.rb +5 -11
  70. data/test/lib/rubycritic/source_locator_test.rb +26 -17
  71. data/test/lib/rubycritic/turbulence_test.rb +17 -0
  72. data/test/lib/rubycritic/version_test.rb +1 -0
  73. data/test/samples/flay/smelly.rb +17 -0
  74. data/test/samples/flog/complex.rb +11 -0
  75. data/test/samples/flog/smelly.rb +7 -2
  76. data/test/samples/reek/not_smelly.rb +31 -3
  77. data/test/test_helper.rb +1 -0
  78. metadata +97 -32
  79. data/SPEC.md +0 -58
  80. data/lib/rubycritic/report_generators/base_generator.rb +0 -42
  81. data/lib/rubycritic/report_generators/file_generator.rb +0 -42
  82. data/lib/rubycritic/report_generators/index_generator.rb +0 -28
  83. data/lib/rubycritic/report_generators/line_generator.rb +0 -27
  84. data/lib/rubycritic/report_generators/reporter.rb +0 -45
  85. data/lib/rubycritic/report_generators/templates/file.html.erb +0 -3
  86. data/lib/rubycritic/report_generators/templates/index.html.erb +0 -14
  87. data/lib/rubycritic/smell_adapters/flog.rb +0 -41
  88. data/lib/rubycritic/smell_adapters/reek.rb +0 -35
  89. data/lib/rubycritic/smells_aggregator.rb +0 -29
  90. data/lib/rubycritic/smelly_pathnames_serializer.rb +0 -34
  91. data/lib/rubycritic/source_control_systems/source_control_system.rb +0 -42
  92. data/test/lib/rubycritic/metric_adapters/flog_adapter_test.rb +0 -25
  93. data/test/lib/rubycritic/metric_adapters/reek_adapter_test.rb +0 -34
  94. data/test/lib/rubycritic/smell_test.rb +0 -71
  95. data/test/lib/rubycritic/smells_aggregator_test.rb +0 -47
  96. /data/lib/rubycritic/report_generators/assets/javascripts/{prettify.js → prettify-4-Mar-2013.js} +0 -0
@@ -0,0 +1,26 @@
1
+ <table id="js-index-table" class="index-table sortable-table">
2
+ <thead>
3
+ <tr>
4
+ <th class="first-cell">Name</th>
5
+ <th class="numeric-cell" title="Number of times a file has changed">Churn</th>
6
+ <th class="numeric-cell" title="Overall amount of code in a file">Complexity</th>
7
+ <th class="numeric-cell" title="Amount of code that is similar to other code">Duplication</th>
8
+ <th class="numeric-cell">Smells</th>
9
+ <th class="centered-cell last-cell">Rating</th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% @analysed_files.each do |analysed_file| %>
14
+ <tr>
15
+ <td class="first-cell">
16
+ <a href="<%= file_path(analysed_file.pathname.sub_ext('.html')) %>"><%= analysed_file.name %></a>
17
+ </td>
18
+ <td class="numeric-cell"><%= analysed_file.churn %></td>
19
+ <td class="numeric-cell"><%= analysed_file.complexity %></td>
20
+ <td class="numeric-cell"><%= analysed_file.duplication %></td>
21
+ <td class="numeric-cell"><%= analysed_file.smells.length %></td>
22
+ <td class="centered-cell last-cell"><span class="rating-<%= analysed_file.rating.to_s.downcase %> circled-rating circle"><%= analysed_file.rating %></td>
23
+ </tr>
24
+ <% end %>
25
+ </tbody>
26
+ </table>
@@ -1,19 +1,30 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <title>RubyCritic</title>
7
- <link href="<%= stylesheet_path(:application) %>" media="screen, projection, print" rel="stylesheet" type="text/css">
8
- <link href="<%= stylesheet_path(:'prettify.custom_theme') %>" media="screen, projection, print" rel="stylesheet" type="text/css">
9
- <meta name="description" content="">
10
- <meta name="viewport" content="width=device-width, initial-scale=1">
11
- </head>
12
- <body>
13
- <h1><a href="<%= index_path %>">RubyCritic</a></h1>
14
- <%= yield %>
15
- <script src="<%= javascript_path(:'jquery-2.1.0') %>"></script>
16
- <script src="<%= javascript_path(:prettify) %>"></script>
17
- <script src="<%= javascript_path(:application) %>"></script>
18
- </body>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <title>RubyCritic</title>
7
+ <link href="<%= stylesheet_path(:application) %>" media="screen, projection, print" rel="stylesheet" type="text/css">
8
+ <link href="<%= stylesheet_path(:'prettify.custom_theme') %>" media="screen, projection, print" rel="stylesheet" type="text/css">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ </head>
11
+ <body>
12
+ <header class="project-header group">
13
+ <h1 class="logo"><a href="<%= file_path('overview.html') %>" class="logo-link">RubyCritic</a></h1>
14
+ <nav class="project-nav">
15
+ <a href="<%= file_path('overview.html') %>" class="project-nav-item">Overview</a>
16
+ <a href="<%= file_path('code_index.html') %>" class="project-nav-item">Code</a>
17
+ <a href="<%= file_path('smells_index.html') %>" class="project-nav-item">Smells</a>
18
+ </nav>
19
+ </header>
20
+ <%= yield %>
21
+ <%= javascript_tag(:'jquery-2.1.0') %>
22
+ <%= javascript_tag(:'jquery.tablesorter-2.0') %>
23
+ <%= javascript_tag(:'jquery.floatThead-v1.2.7') %>
24
+ <%= javascript_tag(:'jquery.timeago-v1.4.1') %>
25
+ <%= javascript_tag(:'highcharts.src-4.0.1') %>
26
+ <%= javascript_tag(:'jquery.scrollTo-1.4.11') %>
27
+ <%= javascript_tag(:'prettify-4-Mar-2013') %>
28
+ <%= javascript_tag(:application) %>
29
+ </body>
19
30
  </html>
@@ -0,0 +1,5 @@
1
+ <div id="js-chart-container" class="chart-container"></div>
2
+
3
+ <script type="text/javascript">
4
+ var turbulenceData = <%= @turbulence_data %>;
5
+ </script>
@@ -0,0 +1,20 @@
1
+ <table id="js-index-table" class="index-table sortable-table">
2
+ <thead>
3
+ <tr>
4
+ <th class="first-cell">Smell</th>
5
+ <th class="last-cell">Locations</th>
6
+ </tr>
7
+ </thead>
8
+ <tbody>
9
+ <% @smells.each do |smell| %>
10
+ <tr>
11
+ <td class="first-cell"><%= smell.type %></td>
12
+ <td class="last-cell">
13
+ <% smell.locations.each do |location| %>
14
+ <a href="<%= smell_location_path(location) %>"><%= location.file_name %></a>
15
+ <% end %>
16
+ </td>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ </table>
@@ -1,25 +1,44 @@
1
+ require "pathname"
2
+
1
3
  module Rubycritic
2
4
 
3
5
  module ViewHelpers
4
- def javascript_path(file)
5
- asset_path(File.join("javascripts", "#{file}.js"))
6
+ def timeago_tag(time)
7
+ "<time class='js-timeago' datetime='#{time}'>#{time}</time>"
8
+ end
9
+
10
+ def javascript_tag(file)
11
+ "<script src='" + asset_path("javascripts", "#{file}.js").to_s + "'></script>"
6
12
  end
7
13
 
8
14
  def stylesheet_path(file)
9
- asset_path(File.join("stylesheets", "#{file}.css"))
15
+ asset_path("stylesheets", "#{file}.css")
16
+ end
17
+
18
+ def asset_path(*fragments)
19
+ relative_path(([root_directory, "assets"] + fragments).reduce(:+))
10
20
  end
11
21
 
12
- def asset_path(file)
13
- File.join(root_directory, "assets", file)
22
+ def file_path(file)
23
+ relative_path(root_directory + file)
14
24
  end
15
25
 
16
26
  def smell_location_path(location)
17
- pathname = location.pathname
18
- File.join(root_directory, File.dirname(pathname), "#{pathname.basename.sub_ext("")}.html#L#{location.line}")
27
+ relative_path(root_directory + "#{location.pathname.sub_ext('.html')}#L#{location.line}")
28
+ end
29
+
30
+ private
31
+
32
+ def relative_path(pathname)
33
+ pathname.relative_path_from(file_directory)
34
+ end
35
+
36
+ def file_directory
37
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
19
38
  end
20
39
 
21
- def index_path
22
- File.join(root_directory, "index.html")
40
+ def root_directory
41
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
23
42
  end
24
43
  end
25
44
 
@@ -0,0 +1,24 @@
1
+ require "fileutils"
2
+
3
+ module Rubycritic
4
+ module Reporter
5
+
6
+ class Base
7
+ ASSETS_DIR = File.expand_path("../../report_generators/assets", __FILE__)
8
+
9
+ def create_directories_and_files(generators)
10
+ Array(generators).each do |generator|
11
+ FileUtils.mkdir_p(generator.file_directory)
12
+ File.open(generator.file_pathname, "w+") do |file|
13
+ file.write(generator.render)
14
+ end
15
+ end
16
+ end
17
+
18
+ def copy_assets_to_report_directory
19
+ FileUtils.cp_r(ASSETS_DIR, ::Rubycritic.configuration.root)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ require "rubycritic/reporters/base"
2
+ require "rubycritic/report_generators/overview"
3
+ require "rubycritic/report_generators/smells_index"
4
+ require "rubycritic/report_generators/code_index"
5
+ require "rubycritic/report_generators/code_file"
6
+
7
+ module Rubycritic
8
+ module Reporter
9
+
10
+ class Main < Base
11
+ def initialize(analysed_files)
12
+ @analysed_files = analysed_files
13
+ @smells = analysed_files.flat_map(&:smells).uniq
14
+ end
15
+
16
+ def generate_report
17
+ create_directories_and_files(generators)
18
+ copy_assets_to_report_directory
19
+ report_location
20
+ end
21
+
22
+ private
23
+
24
+ def generators
25
+ [overview_generator, code_index_generator, smells_index_generator] + file_generators
26
+ end
27
+
28
+ def overview_generator
29
+ @overview_generator ||= Generator::Overview.new(@analysed_files)
30
+ end
31
+
32
+ def code_index_generator
33
+ Generator::CodeIndex.new(@analysed_files)
34
+ end
35
+
36
+ def smells_index_generator
37
+ Generator::SmellsIndex.new(@smells)
38
+ end
39
+
40
+ def file_generators
41
+ @analysed_files.map do |analysed_file|
42
+ Generator::CodeFile.new(analysed_file)
43
+ end
44
+ end
45
+
46
+ def report_location
47
+ overview_generator.file_href
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,30 @@
1
+ require "rubycritic/reporters/base"
2
+ require "rubycritic/report_generators/current_code_file"
3
+
4
+ module Rubycritic
5
+ module Reporter
6
+
7
+ class Mini < Base
8
+ def initialize(analysed_files)
9
+ @analysed_file = analysed_files.first
10
+ end
11
+
12
+ def generate_report
13
+ create_directories_and_files(file_generator)
14
+ copy_assets_to_report_directory
15
+ report_location
16
+ end
17
+
18
+ private
19
+
20
+ def file_generator
21
+ @file_generator ||= Generator::CurrentCodeFile.new(@analysed_file)
22
+ end
23
+
24
+ def report_location
25
+ file_generator.file_href
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -1,54 +1,47 @@
1
- require "rubycritic/smelly_pathnames_serializer"
2
- require "rubycritic/source_locator"
1
+ require "rubycritic/serializer"
2
+ require "rubycritic/files_initializer"
3
3
  require "rubycritic/analysers_runner"
4
- require "rubycritic/smells_aggregator"
5
4
  require "rubycritic/smells_status_setter"
6
5
 
7
6
  module Rubycritic
8
7
 
9
8
  class RevisionComparator
10
- SNAPSHOTS_DIR = File.expand_path("tmp/rubycritic/snapshots", Dir.getwd)
9
+ SNAPSHOTS_DIR_NAME = "snapshots"
11
10
 
12
- def initialize(paths, source_control_system)
13
- @paths = paths
11
+ def initialize(analysed_files, source_control_system)
12
+ @analysed_files_now = analysed_files
14
13
  @source_control_system = source_control_system
15
14
  end
16
15
 
17
- def compare
18
- SmellsStatusSetter.new(smelly_pathnames_before, smelly_pathnames_now).smelly_pathnames
16
+ def set_statuses
17
+ SmellsStatusSetter.set(
18
+ analysed_files_before.flat_map(&:smells),
19
+ @analysed_files_now.flat_map(&:smells)
20
+ )
19
21
  end
20
22
 
21
23
  private
22
24
 
23
- def smelly_pathnames_before
24
- serializer = SmellyPathnamesSerializer.new(revision_file)
25
+ def analysed_files_before
26
+ serializer = Serializer.new(revision_file)
25
27
  if File.file?(revision_file)
26
28
  serializer.load
27
29
  else
28
- smelly_pathnames = nil
30
+ analysed_files = FilesInitializer.init(["."])
29
31
  @source_control_system.travel_to_head do
30
- smelly_pathnames = smelly_pathnames(paths_of_tracked_files)
32
+ AnalysersRunner.new(analysed_files, @source_control_system).run
31
33
  end
32
- serializer.dump(smelly_pathnames)
33
- smelly_pathnames
34
+ serializer.dump(analysed_files)
35
+ analysed_files
34
36
  end
35
37
  end
36
38
 
37
- def smelly_pathnames_now
38
- smelly_pathnames(@paths)
39
- end
40
-
41
- def smelly_pathnames(paths)
42
- smell_adapters = AnalysersRunner.new(paths).run
43
- SmellsAggregator.new(smell_adapters).smelly_pathnames
44
- end
45
-
46
39
  def revision_file
47
- @revision_file ||= File.join(SNAPSHOTS_DIR, @source_control_system.head_reference)
48
- end
49
-
50
- def paths_of_tracked_files
51
- SourceLocator.new(["."]).paths
40
+ @revision_file ||= File.join(
41
+ ::Rubycritic.configuration.root,
42
+ SNAPSHOTS_DIR_NAME,
43
+ @source_control_system.head_reference
44
+ )
52
45
  end
53
46
  end
54
47
 
@@ -0,0 +1,32 @@
1
+ require "fileutils"
2
+
3
+ module Rubycritic
4
+
5
+ class Serializer
6
+ def initialize(file)
7
+ @file = file
8
+ end
9
+
10
+ def load
11
+ Marshal.load(File.binread(@file))
12
+ end
13
+
14
+ def dump(content)
15
+ create_file_directory
16
+ File.open(@file, "w+") do |file|
17
+ Marshal.dump(content, file)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def create_file_directory
24
+ FileUtils.mkdir_p(file_directory)
25
+ end
26
+
27
+ def file_directory
28
+ File.dirname(@file)
29
+ end
30
+ end
31
+
32
+ end
@@ -1,25 +1,16 @@
1
1
  module Rubycritic
2
2
 
3
- class SmellsStatusSetter
4
- def initialize(smelly_pathnames_before, smelly_pathnames_now)
5
- @smelly_pathnames_before = smelly_pathnames_before
6
- @smelly_pathnames_now = smelly_pathnames_now
7
- end
8
-
9
- def smelly_pathnames
10
- @smelly_pathnames_now.each do |pathname, smells_now|
11
- smells_before = @smelly_pathnames_before[pathname] || []
12
- old_smells = smells_now & smells_before
13
- set_status(old_smells, :old)
14
- new_smells = smells_now - smells_before
15
- set_status(new_smells, :new)
16
- end
17
- @smelly_pathnames_now
3
+ module SmellsStatusSetter
4
+ def self.set(smells_before, smells_now)
5
+ old_smells = smells_now & smells_before
6
+ set_status(old_smells, :old)
7
+ new_smells = smells_now - smells_before
8
+ set_status(new_smells, :new)
18
9
  end
19
10
 
20
11
  private
21
12
 
22
- def set_status(smells, status)
13
+ def self.set_status(smells, status)
23
14
  smells.each { |smell| smell.status = status }
24
15
  end
25
16
  end
@@ -0,0 +1,60 @@
1
+ require "shellwords"
2
+
3
+ module Rubycritic
4
+ module SourceControlSystem
5
+
6
+ class Base
7
+ @@systems = []
8
+
9
+ def self.register_system
10
+ @@systems << self
11
+ end
12
+
13
+ def self.create
14
+ supported_system = systems.detect(&:supported?)
15
+ if supported_system
16
+ supported_system.new
17
+ else
18
+ puts "Rubycritic requires a #{system_names} repository."
19
+ Double.new
20
+ end
21
+ end
22
+
23
+ def self.systems
24
+ @@systems
25
+ end
26
+
27
+ def self.system_names
28
+ systems.join(", ")
29
+ end
30
+
31
+ def self.supported?
32
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
33
+ end
34
+
35
+ def has_revision?
36
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
37
+ end
38
+
39
+ def head_reference
40
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
41
+ end
42
+
43
+ def travel_to_head
44
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
45
+ end
46
+
47
+ def revisions_count(path)
48
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
49
+ end
50
+
51
+ def date_of_last_commit(path)
52
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ require "rubycritic/source_control_systems/double"
60
+ require "rubycritic/source_control_systems/git"
@@ -0,0 +1,19 @@
1
+ module Rubycritic
2
+ module SourceControlSystem
3
+
4
+ class Double < Base
5
+ def has_revision?
6
+ false
7
+ end
8
+
9
+ def revisions_count(path)
10
+ "N/A"
11
+ end
12
+
13
+ def date_of_last_commit(path)
14
+ nil
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -1,53 +1,63 @@
1
1
  module Rubycritic
2
+ module SourceControlSystem
2
3
 
3
- class Git < SourceControlSystem
4
- register_system
4
+ class Git < Base
5
+ register_system
5
6
 
6
- def self.supported?
7
- `git branch 2>&1` && $?.success?
8
- end
7
+ def self.supported?
8
+ `git branch 2>&1` && $?.success?
9
+ end
9
10
 
10
- def self.to_s
11
- "Git"
12
- end
11
+ def self.to_s
12
+ "Git"
13
+ end
13
14
 
14
- def has_revision?
15
- head_reference && $?.success?
16
- end
15
+ def has_revision?
16
+ head_reference && $?.success?
17
+ end
17
18
 
18
- def head_reference
19
- `git rev-parse --verify HEAD`.chomp
20
- end
19
+ def head_reference
20
+ `git rev-parse --verify HEAD`.chomp!
21
+ end
21
22
 
22
- def travel_to_head
23
- stash_successful = stash_changes
24
- yield
25
- ensure
26
- travel_to_original_state if stash_successful
27
- end
23
+ def travel_to_head
24
+ stash_successful = stash_changes
25
+ yield
26
+ ensure
27
+ travel_to_original_state if stash_successful
28
+ end
28
29
 
29
- private
30
+ def revisions_count(path)
31
+ `git log --follow --format=oneline #{path.shellescape}`.count("\n")
32
+ end
30
33
 
31
- def stash_changes
32
- return false if everything_commmited?
34
+ def date_of_last_commit(path)
35
+ `git log -1 --date=iso --format=%ad #{path.shellescape}`.chomp!
36
+ end
33
37
 
34
- stashes_count_before = stashes_count
35
- `git stash`
36
- stashes_count_after = stashes_count
37
- stashes_count_after > stashes_count_before
38
- end
38
+ private
39
39
 
40
- def everything_commmited?
41
- `git status --porcelain`.empty?
42
- end
40
+ def stash_changes
41
+ return false if everything_commmited?
43
42
 
44
- def stashes_count
45
- `git stash list`.split("\n").length
46
- end
43
+ stashes_count_before = stashes_count
44
+ `git stash`
45
+ stashes_count_after = stashes_count
46
+ stashes_count_after > stashes_count_before
47
+ end
48
+
49
+ def everything_commmited?
50
+ `git status --porcelain`.empty?
51
+ end
47
52
 
48
- def travel_to_original_state
49
- `git stash pop`
53
+ def stashes_count
54
+ `git stash list`.count("\n")
55
+ end
56
+
57
+ def travel_to_original_state
58
+ `git stash pop`
59
+ end
50
60
  end
51
- end
52
61
 
62
+ end
53
63
  end
@@ -7,31 +7,27 @@ module Rubycritic
7
7
  RUBY_FILES = File.join("**", "*#{RUBY_EXTENSION}")
8
8
 
9
9
  def initialize(paths)
10
- @user_paths = paths
11
- end
12
-
13
- def pathnames
14
- @pathnames ||= expand_paths
10
+ @initial_paths = paths
15
11
  end
16
12
 
17
13
  def paths
18
14
  @paths ||= pathnames.map(&:to_s)
19
15
  end
20
16
 
17
+ def pathnames
18
+ @pathnames ||= expand_paths
19
+ end
20
+
21
21
  private
22
22
 
23
23
  def expand_paths
24
- @user_paths.map do |path|
24
+ @initial_paths.map do |path|
25
25
  if File.directory?(path)
26
- Pathname.glob(files_contained_in(path))
26
+ Pathname.glob(File.join(path, RUBY_FILES))
27
27
  elsif File.exists?(path) && File.extname(path) == RUBY_EXTENSION
28
28
  Pathname.new(path)
29
29
  end
30
- end.flatten.compact.sort
31
- end
32
-
33
- def files_contained_in(path)
34
- (path == ".") ? RUBY_FILES : File.join(path, RUBY_FILES)
30
+ end.flatten.compact.map(&:cleanpath).sort
35
31
  end
36
32
  end
37
33
 
@@ -0,0 +1,17 @@
1
+ require "json"
2
+
3
+ module Rubycritic
4
+
5
+ module Turbulence
6
+ def self.data(analysed_files)
7
+ analysed_files.map do |analysed_file|
8
+ {
9
+ :name => analysed_file.pathname,
10
+ :x => analysed_file.churn,
11
+ :y => analysed_file.complexity
12
+ }
13
+ end.to_json
14
+ end
15
+ end
16
+
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubycritic
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.16"
3
3
  end