attractor 2.0.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32f34f95771347469f06cb38654a9cbdfd90addb8cbf70e718689352256cc15c
4
- data.tar.gz: f8024a093f262346b4705dfcdcfd8cc96b44fab40562c9d81eb46b44c5a663f1
3
+ metadata.gz: a044632a13376f395112a65b938be9c3173a16499f4eab725e97afffc1e83925
4
+ data.tar.gz: 20aafed307f3cf4f047130aa6aafc2395838ba50ecf48dedc0bd205fe5e6c391
5
5
  SHA512:
6
- metadata.gz: 952196da679b26b588c622d4204a148cf32105975dc7918bca71102e9abb0f4753206ac6cc68509b93b492aeb690b7b6d0d258ecf3dc42de5d11a6490e9bd6bd
7
- data.tar.gz: a6bf90fef7df1ea26f3e45cec87360d3befed11107faa2b6554f3ac5df8bdf5985342346845e44e8ef2085a3e8678d7f5976c35fc4fd82fbf04fc48cb98d12b1
6
+ metadata.gz: 12a4dd82ff8d50a7d5e7c3663b6b013e93d6575a706581c7b64a5bbb75714d9d8126c3f24344f57e2c5c79905ea549e82370def04fb6643ff25fbc38f365c846
7
+ data.tar.gz: f27f15c33b573ab2cccb9be34d59f89c12575e19fe18454d5380c4fd500f98e63e2b0e8be2bd4e7a86c18512124fb6792e5f625101ef4e8333b54bf59a03a165
data/README.md CHANGED
@@ -195,6 +195,7 @@ attractor calc
195
195
  --watch|-w
196
196
  --start_ago|-s (e.g. 5y, 3m, 7w)
197
197
  --minimum_churn|-c (minimum times a file must have changed to be processed)
198
+ --ignore|-i 'spec/*_spec.rb,db/schema.rb,tmp'
198
199
  ```
199
200
 
200
201
  Generate a full report
@@ -207,6 +208,7 @@ attractor report
207
208
  --no-open-browser|--ci
208
209
  --start_ago|-s (e.g. 5y, 3m, 7w)
209
210
  --minimum_churn|-c (minimum times a file must have changed to be processed)
211
+ --ignore|-i 'spec/*_spec.rb,db/schema.rb,tmp'
210
212
  ```
211
213
 
212
214
  Serve the output on `http://localhost:7890`
@@ -218,6 +220,7 @@ attractor serve
218
220
  --no-open-browser|--ci
219
221
  --start_ago|-s (e.g. 5y, 3m, 7w)
220
222
  --minimum_churn|-c (minimum times a file must have changed to be processed)
223
+ --ignore|-i 'spec/*_spec.rb,db/schema.rb,tmp'
221
224
  ```
222
225
 
223
226
  ## Development
data/Rakefile CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'autoprefixer-rails'
4
- require 'bootstrap'
5
- require 'bundler/gem_tasks'
6
- require 'fileutils'
7
- require 'rspec/core/rake_task'
8
- require 'sassc'
9
- require 'structured_changelog/tasks'
3
+ require "autoprefixer-rails"
4
+ require "bootstrap"
5
+ require "bundler/gem_tasks"
6
+ require "fileutils"
7
+ require "rspec/core/rake_task"
8
+ require "sassc"
9
+ require "structured_changelog/tasks"
10
10
 
11
11
  RSpec::Core::RakeTask.new(:spec)
12
12
 
@@ -14,18 +14,18 @@ task default: :spec
14
14
 
15
15
  task build: :assets
16
16
 
17
- desc 'Preprocess assets'
17
+ desc "Preprocess assets"
18
18
  task :assets do
19
- puts 'Preprocessing SCSS and JS files'
19
+ puts "Preprocessing SCSS and JS files"
20
20
 
21
- puts 'Copying over bootstrap'
21
+ puts "Copying over bootstrap"
22
22
 
23
- FileUtils.cp_r Gem::Specification.find_by_name('bootstrap').gem_dir, 'tmp'
23
+ FileUtils.cp_r Gem::Specification.find_by_name("bootstrap").gem_dir, "tmp"
24
24
 
25
- sass = File.read(File.expand_path('./src/stylesheets/main.scss'))
25
+ sass = File.read(File.expand_path("./src/stylesheets/main.scss"))
26
26
  css = SassC::Engine.new(sass, style: :compressed).render
27
27
  prefixed = AutoprefixerRails.process(css)
28
- File.open(File.expand_path('./app/assets/stylesheets/main.css'), 'w') { |file| file.write(prefixed) }
28
+ File.open(File.expand_path("./app/assets/stylesheets/main.css"), "w") { |file| file.write(prefixed) }
29
29
 
30
30
  npm_output = `npm run build`
31
31
  puts npm_output
data/exe/attractor CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- require 'attractor/cli'
2
+ require "attractor/cli"
3
3
  Attractor::CLI.start
data/lib/attractor.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'attractor/version'
4
- require 'attractor/gem_names'
5
- require 'attractor/duration_parser'
6
- require 'attractor/calculators/base_calculator'
7
- require 'attractor/detectors/base_detector'
8
- require 'attractor/reporters/base_reporter'
9
- require 'attractor/suggester'
10
- require 'attractor/watcher'
11
-
12
- Dir[File.join(__dir__, 'attractor', 'reporters', '*.rb')].each do |file|
13
- next if file.start_with?('base')
3
+ require "attractor/version"
4
+ require "attractor/gem_names"
5
+ require "attractor/duration_parser"
6
+ require "attractor/calculators/base_calculator"
7
+ require "attractor/detectors/base_detector"
8
+ require "attractor/reporters/base_reporter"
9
+ require "attractor/suggester"
10
+ require "attractor/watcher"
11
+
12
+ Dir[File.join(__dir__, "attractor", "reporters", "*.rb")].sort.each do |file|
13
+ next if file.start_with?("base")
14
14
 
15
15
  require file
16
16
  end
@@ -27,9 +27,8 @@ module Attractor
27
27
  def calculators_for_type(type, **options)
28
28
  registry_entry_for_type = @registry_entries[type]
29
29
 
30
- return { type => registry_entry_for_type.calculator_class.new(**options) } if type
30
+ return {type => registry_entry_for_type.calculator_class.new(**options)} if type
31
31
 
32
-
33
32
  Hash[@registry_entries.map do |type, entry|
34
33
  [type, entry.calculator_class.new(**options)] if entry.detector_class.new.detect
35
34
  end.compact]
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'churn/calculator'
3
+ require "churn/calculator"
4
4
 
5
- require 'attractor/value'
5
+ require "attractor/value"
6
6
 
7
7
  module Attractor
8
8
  # calculates churn and complexity
9
9
  class BaseCalculator
10
10
  attr_reader :type
11
11
 
12
- def initialize(file_prefix: '', file_extension: 'rb', minimum_churn_count: 3, start_ago: '5y')
12
+ def initialize(file_prefix: "", ignores: "", file_extension: "rb", minimum_churn_count: 3, start_ago: "5y")
13
13
  @file_prefix = file_prefix
14
14
  @file_extension = file_extension
15
15
  @minimum_churn_count = minimum_churn_count
16
16
  @start_date = Date.today - Attractor::DurationParser.new(start_ago).duration
17
+ @ignores = ignores
17
18
  end
18
19
 
19
20
  def calculate
@@ -21,7 +22,8 @@ module Attractor
21
22
  file_extension: @file_extension,
22
23
  file_prefix: @file_prefix,
23
24
  minimum_churn_count: @minimum_churn_count,
24
- start_date: @start_date
25
+ start_date: @start_date,
26
+ ignores: @ignores
25
27
  ).report(false)
26
28
 
27
29
  churn[:churn][:changes].map do |change|
@@ -39,10 +41,10 @@ module Attractor
39
41
  def git_history_for_file(file_path:, limit: 10)
40
42
  history = `git log --oneline -n #{limit} -- #{file_path}`
41
43
  history.split("\n")
42
- .map do |log_entry|
44
+ .map do |log_entry|
43
45
  log_entry.partition(/\A(\S+)\s/)
44
- .map(&:strip)
45
- .reject(&:empty?)
46
+ .map(&:strip)
47
+ .reject(&:empty?)
46
48
  end
47
49
  end
48
50
  end
data/lib/attractor/cli.rb CHANGED
@@ -1,95 +1,84 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
3
+ require "thor"
4
4
 
5
- require 'attractor'
5
+ require "attractor"
6
6
 
7
7
  module Attractor
8
8
  # contains methods implementing the CLI
9
9
  class CLI < Thor
10
10
  shared_options = [[:file_prefix, aliases: :p],
11
- [:watch, aliases: :w, type: :boolean],
12
- [:minimum_churn, aliases: :c, type: :numeric, default: 3],
13
- [:start_ago, aliases: :s, type: :string, default: '5y'],
14
- [:type, aliases: :t]]
11
+ [:ignore, aliases: :i, default: ""],
12
+ [:watch, aliases: :w, type: :boolean],
13
+ [:minimum_churn, aliases: :c, type: :numeric, default: 3],
14
+ [:start_ago, aliases: :s, type: :string, default: "5y"],
15
+ [:type, aliases: :t]]
15
16
 
16
- advanced_options = [[:format, aliases: :f, default: 'html'],
17
- [:no_open_browser, type: :boolean],
18
- [:ci, type: :boolean]]
17
+ advanced_options = [[:format, aliases: :f, default: "html"],
18
+ [:no_open_browser, type: :boolean],
19
+ [:ci, type: :boolean]]
19
20
 
20
21
  desc "version", "Prints Attractor's version information"
21
- map %w(-v --version) => :version
22
+ map %w[-v --version] => :version
22
23
  def version
23
24
  puts "Attractor version #{Attractor::VERSION}"
24
25
  rescue RuntimeError => e
25
26
  puts "Runtime error: #{e.message}"
26
27
  end
27
28
 
28
- desc 'calc', 'Calculates churn and complexity for all ruby files in current directory'
29
+ desc "calc", "Calculates churn and complexity for all ruby files in current directory"
29
30
  shared_options.each do |shared_option|
30
31
  option(*shared_option)
31
32
  end
32
33
  def calc
33
34
  file_prefix = options[:file_prefix]
34
- if options[:watch]
35
- puts 'Listening for file changes...'
36
- Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators(options)).watch
37
- else
38
- Attractor::ConsoleReporter.new(file_prefix: file_prefix, calculators: calculators(options)).report
39
- end
35
+
36
+ report! Attractor::ConsoleReporter.new(file_prefix: file_prefix, ignores: options[:ignore], calculators: calculators(options))
40
37
  rescue RuntimeError => e
41
38
  puts "Runtime error: #{e.message}"
42
39
  end
43
40
 
44
- desc 'report', 'Generates an HTML report'
41
+ desc "report", "Generates an HTML report"
45
42
  (shared_options + advanced_options).each do |option|
46
43
  option(*option)
47
44
  end
48
45
  def report
49
46
  file_prefix = options[:file_prefix]
50
47
  open_browser = !(options[:no_open_browser] || options[:ci])
51
- if options[:watch]
52
- puts 'Listening for file changes...'
53
- Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).watch
54
- else
55
- case options[:format]
56
- when 'html'
57
- Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
58
- else
59
- Attractor::HtmlReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
60
- end
61
- end
48
+
49
+ report! Attractor::HtmlReporter.new(file_prefix: file_prefix, ignores: options[:ignore], calculators: calculators(options), open_browser: open_browser)
62
50
  rescue RuntimeError => e
63
51
  puts "Runtime error: #{e.message}"
64
52
  end
65
53
 
66
- desc 'serve', 'Serves the report on localhost'
54
+ desc "serve", "Serves the report on localhost"
67
55
  (shared_options + advanced_options).each do |option|
68
56
  option(*option)
69
57
  end
70
58
  def serve
71
59
  file_prefix = options[:file_prefix]
72
60
  open_browser = !(options[:no_open_browser] || options[:ci])
73
- if options[:watch]
74
- puts 'Listening for file changes...'
75
- Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).watch
76
- else
77
- case options[:format]
78
- when 'html'
79
- Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
80
- else
81
- Attractor::SinatraReporter.new(file_prefix: file_prefix, calculators: calculators(options), open_browser: open_browser).report
82
- end
83
- end
61
+
62
+ report! Attractor::SinatraReporter.new(file_prefix: file_prefix, ignores: options[:ignore], calculators: calculators(options), open_browser: open_browser)
84
63
  end
85
64
 
86
65
  private
87
66
 
88
67
  def calculators(options)
89
68
  Attractor.calculators_for_type(options[:type],
90
- file_prefix: options[:file_prefix],
91
- minimum_churn_count: options[:minimum_churn],
92
- start_ago: options[:start_ago])
69
+ file_prefix: options[:file_prefix],
70
+ minimum_churn_count: options[:minimum_churn],
71
+ ignores: options[:ignore],
72
+ start_ago: options[:start_ago])
73
+ end
74
+
75
+ def report!(reporter)
76
+ if options[:watch]
77
+ puts "Listening for file changes..."
78
+ reporter.watch
79
+ else
80
+ reporter.report
81
+ end
93
82
  end
94
83
  end
95
84
  end
@@ -4,10 +4,10 @@ module Attractor
4
4
  # converts a duration string into an amount of days
5
5
  class DurationParser
6
6
  TOKENS = {
7
- 'd' => 1,
8
- 'w' => 7,
9
- 'm' => 30,
10
- 'y' => 365
7
+ "d" => 1,
8
+ "w" => 7,
9
+ "m" => 30,
10
+ "y" => 365
11
11
  }.freeze
12
12
 
13
13
  attr_reader :duration
@@ -2,7 +2,7 @@ module Attractor
2
2
  # from https://github.com/prontolabs/pronto/blob/master/lib/pronto/gem_names.rb
3
3
  class GemNames
4
4
  def to_a
5
- gems.map { |gem| gem.name.sub(/^attractor-/, '') }.uniq.sort
5
+ gems.map { |gem| gem.name.sub(/^attractor-/, "") }.uniq.sort
6
6
  end
7
7
 
8
8
  private
@@ -9,4 +9,3 @@ module Attractor
9
9
  end
10
10
  end
11
11
  end
12
-
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'descriptive_statistics/safe'
4
- require 'fileutils'
5
- require 'forwardable'
6
- require 'launchy'
7
- require 'tilt'
3
+ require "descriptive_statistics/safe"
4
+ require "fileutils"
5
+ require "forwardable"
6
+ require "launchy"
7
+ require "tilt"
8
8
 
9
9
  module Attractor
10
10
  # base reporter
@@ -15,21 +15,21 @@ module Attractor
15
15
  attr_writer :values
16
16
  def_delegator :@watcher, :watch
17
17
 
18
- def initialize(file_prefix:, calculators:, open_browser: true)
18
+ def initialize(calculators:, file_prefix: "", ignores: "", open_browser: true)
19
19
  @file_prefix = file_prefix || ""
20
20
  @calculators = calculators
21
21
  @open_browser = open_browser
22
22
  @values = @calculators.first.last.calculate
23
23
  @suggester = Suggester.new(values)
24
24
 
25
- @watcher = Watcher.new(@file_prefix, lambda do
25
+ @watcher = Watcher.new(@file_prefix, ignores, lambda do
26
26
  report
27
27
  end)
28
- rescue NoMethodError => e
29
- raise 'There was a problem gathering churn changes'
28
+ rescue NoMethodError => _e
29
+ raise "There was a problem gathering churn changes"
30
30
  end
31
31
 
32
- def suggestions(quantile:, type: 'rb')
32
+ def suggestions(quantile:, type: "rb")
33
33
  @suggester.values = values(type: type)
34
34
  @suggestions = @suggester.suggest(quantile)
35
35
  @suggestions
@@ -41,13 +41,13 @@ module Attractor
41
41
  end
42
42
 
43
43
  def render
44
- 'Attractor'
44
+ "Attractor"
45
45
  end
46
46
 
47
- def values(type: 'rb')
47
+ def values(type: "rb")
48
48
  @values = @calculators[type].calculate
49
49
  @values
50
- rescue NoMethodError => e
50
+ rescue NoMethodError => _e
51
51
  puts "No calculator for type #{type}"
52
52
  end
53
53
  end
@@ -5,10 +5,10 @@ module Attractor
5
5
  class ConsoleReporter < BaseReporter
6
6
  def report
7
7
  super
8
- puts 'Calculated churn and complexity'
8
+ puts "Calculated churn and complexity"
9
9
  puts
10
- puts "file_path#{' ' * 53}complexity churn"
11
- puts '-' * 80
10
+ puts "file_path#{" " * 53}complexity churn"
11
+ puts "-" * 80
12
12
 
13
13
  @calculators.each do |calc|
14
14
  # e.g. ['js', JsCalculator']
@@ -19,7 +19,7 @@ module Attractor
19
19
 
20
20
  puts values&.map(&:to_s)
21
21
  puts
22
- puts 'Suggestions for refactorings:'
22
+ puts "Suggestions for refactorings:"
23
23
  suggester.suggest&.each { |sug| puts sug.file_path }
24
24
  puts
25
25
  end
@@ -6,18 +6,18 @@ module Attractor
6
6
  def report
7
7
  super
8
8
 
9
- puts 'Generating an HTML report'
9
+ puts "Generating an HTML report"
10
10
  @serve_static = true
11
11
 
12
- FileUtils.mkdir_p './attractor_output'
13
- FileUtils.mkdir_p './attractor_output/stylesheets'
14
- FileUtils.mkdir_p './attractor_output/images'
15
- FileUtils.mkdir_p './attractor_output/javascripts'
12
+ FileUtils.mkdir_p "./attractor_output"
13
+ FileUtils.mkdir_p "./attractor_output/stylesheets"
14
+ FileUtils.mkdir_p "./attractor_output/images"
15
+ FileUtils.mkdir_p "./attractor_output/javascripts"
16
16
 
17
- File.open('./attractor_output/images/attractor_logo.svg', 'w') { |file| file.write(logo) }
18
- File.open('./attractor_output/images/attractor_favicon.png', 'w') { |file| file.write(favicon) }
19
- File.open('./attractor_output/stylesheets/main.css', 'w') { |file| file.write(css) }
20
- File.open('./attractor_output/javascripts/index.pack.js', 'w') { |file| file.write(javascript_pack) }
17
+ File.open("./attractor_output/images/attractor_logo.svg", "w") { |file| file.write(logo) }
18
+ File.open("./attractor_output/images/attractor_favicon.png", "w") { |file| file.write(favicon) }
19
+ File.open("./attractor_output/stylesheets/main.css", "w") { |file| file.write(css) }
20
+ File.open("./attractor_output/javascripts/index.pack.js", "w") { |file| file.write(javascript_pack) }
21
21
 
22
22
  if @calculators.size > 1
23
23
  @calculators.each do |calc|
@@ -25,9 +25,9 @@ module Attractor
25
25
  suggester = Suggester.new(values(type: @short_type))
26
26
  @suggestions = suggester.suggest
27
27
 
28
- File.open("./attractor_output/javascripts/index.#{@short_type}.js", 'w') { |file| file.write(javascript) }
29
- File.open("./attractor_output/index.#{@short_type}.html", 'w') { |file| file.write(render) }
30
- puts "Generated HTML report at #{File.expand_path './attractor_output/'}/index.#{@short_type}.html"
28
+ File.open("./attractor_output/javascripts/index.#{@short_type}.js", "w") { |file| file.write(javascript) }
29
+ File.open("./attractor_output/index.#{@short_type}.html", "w") { |file| file.write(render) }
30
+ puts "Generated HTML report at #{File.expand_path "./attractor_output/"}/index.#{@short_type}.html"
31
31
  end
32
32
 
33
33
  if @open_browser
@@ -35,41 +35,40 @@ module Attractor
35
35
  puts "Opening browser window..."
36
36
  end
37
37
  else
38
- File.open('./attractor_output/javascripts/index.js', 'w') { |file| file.write(javascript) }
39
- File.open('./attractor_output/index.html', 'w') { |file| file.write(render) }
40
- puts "Generated HTML report at #{File.expand_path './attractor_output/index.html'}"
38
+ File.open("./attractor_output/javascripts/index.js", "w") { |file| file.write(javascript) }
39
+ File.open("./attractor_output/index.html", "w") { |file| file.write(render) }
40
+ puts "Generated HTML report at #{File.expand_path "./attractor_output/index.html"}"
41
41
 
42
42
  if @open_browser
43
- Launchy.open(File.expand_path('./attractor_output/index.html'))
43
+ Launchy.open(File.expand_path("./attractor_output/index.html"))
44
44
  puts "Opening browser window..."
45
45
  end
46
46
  end
47
-
48
47
  end
49
48
 
50
49
  def logo
51
- File.read(File.expand_path('../../../app/assets/images/attractor_logo.svg', __dir__))
50
+ File.read(File.expand_path("../../../app/assets/images/attractor_logo.svg", __dir__))
52
51
  end
53
52
 
54
53
  def favicon
55
- File.read(File.expand_path('../../../app/assets/images/attractor_favicon.png', __dir__))
54
+ File.read(File.expand_path("../../../app/assets/images/attractor_favicon.png", __dir__))
56
55
  end
57
56
 
58
57
  def css
59
- File.read(File.expand_path('../../../app/assets/stylesheets/main.css', __dir__))
58
+ File.read(File.expand_path("../../../app/assets/stylesheets/main.css", __dir__))
60
59
  end
61
60
 
62
61
  def javascript_pack
63
- File.read(File.expand_path('../../../app/assets/javascripts/index.pack.js', __dir__))
62
+ File.read(File.expand_path("../../../app/assets/javascripts/index.pack.js", __dir__))
64
63
  end
65
64
 
66
65
  def javascript
67
- template = Tilt.new(File.expand_path('../../../app/assets/javascripts/index.js.erb', __dir__))
66
+ template = Tilt.new(File.expand_path("../../../app/assets/javascripts/index.js.erb", __dir__))
68
67
  template.render self
69
68
  end
70
69
 
71
70
  def render
72
- template = Tilt.new(File.expand_path('../../../app/views/index.html.erb', __dir__))
71
+ template = Tilt.new(File.expand_path("../../../app/views/index.html.erb", __dir__))
73
72
  template.render self
74
73
  end
75
74
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack/livereload'
4
- require 'rack'
5
- require 'sinatra/base'
3
+ require "rack/livereload"
4
+ require "rack"
5
+ require "sinatra/base"
6
6
 
7
7
  module Attractor
8
8
  # skeleton sinatra app
@@ -13,31 +13,31 @@ module Attractor
13
13
  end
14
14
 
15
15
  enable :static
16
- set :public_folder, File.expand_path('../../../app/assets', __dir__)
16
+ set :public_folder, File.expand_path("../../../app/assets", __dir__)
17
17
  set :show_exceptions, :after_handler
18
18
 
19
- get '/' do
19
+ get "/" do
20
20
  @types = @reporter.types
21
- erb File.read(File.expand_path('../../../app/views/index.html.erb', __dir__))
21
+ erb File.read(File.expand_path("../../../app/views/index.html.erb", __dir__))
22
22
  end
23
23
 
24
- get '/file_prefix' do
25
- { file_prefix: @reporter.file_prefix }.to_json
24
+ get "/file_prefix" do
25
+ {file_prefix: @reporter.file_prefix}.to_json
26
26
  end
27
27
 
28
- get '/values' do
29
- type = params[:type] || 'rb'
28
+ get "/values" do
29
+ type = params[:type] || "rb"
30
30
  @reporter.values(type: type).to_json
31
31
  end
32
32
 
33
- get '/suggestions' do
33
+ get "/suggestions" do
34
34
  threshold = params[:t] || 95
35
- type = params[:type] || 'rb'
35
+ type = params[:type] || "rb"
36
36
  @reporter.suggestions(quantile: threshold, type: type).to_json
37
37
  end
38
38
 
39
39
  error NoMethodError do
40
- { error: env['sinatra.error'].message }.to_json
40
+ {error: env["sinatra.error"].message}.to_json
41
41
  end
42
42
  end
43
43
 
@@ -48,10 +48,10 @@ module Attractor
48
48
 
49
49
  app = AttractorApp.new(self)
50
50
 
51
- puts 'Serving attractor at http://localhost:7890'
51
+ puts "Serving attractor at http://localhost:7890"
52
52
 
53
53
  if @open_browser
54
- Launchy.open('http://localhost:7890') if @open_browser
54
+ Launchy.open("http://localhost:7890") if @open_browser
55
55
  puts "Opening browser window..."
56
56
  end
57
57
 
@@ -63,9 +63,9 @@ module Attractor
63
63
 
64
64
  app = AttractorApp.new(self)
65
65
 
66
- puts 'Serving attractor at http://localhost:7890'
66
+ puts "Serving attractor at http://localhost:7890"
67
67
  if @open_browser
68
- Launchy.open('http://localhost:7890')
68
+ Launchy.open("http://localhost:7890")
69
69
  puts "Opening browser window..."
70
70
  end
71
71
 
@@ -4,7 +4,7 @@ module Attractor
4
4
  # makes suggestions for refactorings
5
5
  class Suggester
6
6
  attr_accessor :values
7
-
7
+
8
8
  def initialize(values)
9
9
  @values = values || []
10
10
  end
@@ -15,7 +15,7 @@ module Attractor
15
15
  quantile = products.percentile(threshold.to_i)
16
16
 
17
17
  @values.select { |val| val.churn * val.complexity > quantile }
18
- .sort_by { |val| val.churn * val.complexity }.reverse
18
+ .sort_by { |val| val.churn * val.complexity }.reverse
19
19
  end
20
20
  end
21
21
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
3
+ require "json"
4
4
 
5
5
  module Attractor
6
6
  # holds a churn/complexity value
7
7
  class Value
8
8
  attr_reader :file_path, :churn, :complexity, :details, :history
9
9
 
10
- def initialize(file_path: '', churn: 1, complexity: 0, details: [], history: [])
10
+ def initialize(file_path: "", churn: 1, complexity: 0, details: [], history: [])
11
11
  @file_path = file_path
12
12
  @churn = churn
13
13
  @complexity = complexity
@@ -16,11 +16,11 @@ module Attractor
16
16
  end
17
17
 
18
18
  def to_s
19
- format('%-64s%8.1f%8i', @file_path, @complexity, @churn)
19
+ format("%-64s%8.1f%8i", @file_path, @complexity, @churn)
20
20
  end
21
21
 
22
22
  def to_h
23
- { file_path: file_path, x: churn, y: complexity, details: details, history: history }
23
+ {file_path: file_path, x: churn, y: complexity, details: details, history: history}
24
24
  end
25
25
 
26
26
  def to_json(_opt)
@@ -1,3 +1,3 @@
1
1
  module Attractor
2
- VERSION = "2.0.5"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -5,17 +5,19 @@ require "listen"
5
5
  module Attractor
6
6
  # functionality for watching file system changes
7
7
  class Watcher
8
- def initialize(file_prefix, callback)
8
+ def initialize(file_prefix, ignores, callback)
9
9
  @file_prefix = file_prefix
10
10
  @callback = callback
11
+ @ignores = ignores.split(",").map(&:strip)
11
12
  end
12
13
 
13
14
  def watch
14
15
  @callback.call
16
+ ignore = @ignores + [/^attractor_output/]
15
17
 
16
- listener = Listen.to(File.absolute_path(@file_prefix), ignore: /^attractor_output/) do |modified, _added, _removed|
18
+ listener = Listen.to(File.absolute_path(@file_prefix), ignore: ignore) do |modified, _added, _removed|
17
19
  if modified
18
- puts "#{modified.map(&:to_s).join(', ')} modified, recalculating..."
20
+ puts "#{modified.map(&:to_s).join(", ")} modified, recalculating..."
19
21
  @callback.call
20
22
  end
21
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Rubisch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: churn
@@ -154,30 +154,30 @@ dependencies:
154
154
  name: attractor-javascript
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - ">="
157
+ - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '0'
159
+ version: 0.2.0
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - ">="
164
+ - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '0'
166
+ version: 0.2.0
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: attractor-ruby
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - ">="
171
+ - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '0'
173
+ version: 0.2.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ">="
178
+ - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '0'
180
+ version: 0.2.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: autoprefixer-rails
183
183
  requirement: !ruby/object:Gem::Requirement