attractor 2.0.5 → 2.1.0

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: 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