pig-ci-rails 0.2.0 → 1.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.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require 'bundler/gem_tasks'
1
+ require "bundler/gem_tasks"
2
2
  begin
3
- require 'rspec/core/rake_task'
3
+ require "rspec/core/rake_task"
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
@@ -1,10 +1,5 @@
1
1
  en:
2
2
  pig_ci:
3
- api:
4
- reports:
5
- success: 'PigCI: Successfully submitted report to pigci.com'
6
- error: 'Unable to connect to PigCI API: %{error}'
7
- api_error: 'Unable to connect to PigCI API'
8
3
  summary:
9
4
  ci_start: 'PigCI Thresholds Summary:'
10
5
  ci_failure: 'PigCI: This commit has exceeded the thresholds defined in PigCI.thresholds'
@@ -13,7 +8,7 @@ en:
13
8
  view_historic_reports: 'Historic Reports'
14
9
  footer_html: |
15
10
  <p>Generated <time datetime="%{generated_at}">%{generated_at}</time> by PigCI.</p>
16
- <p>Support <a href="https://pigci.com/" target="_blank" rel="noopener">PigCI</a> by <a href="https://github.com/apps/pigci/installations/new" target="_blank" rel="noopener">adding us on GitHub</a>.</p>
11
+ <p>Support <a href="https://pigci.mikerogers.io/" target="_blank" rel="noopener">PigCI</a> by <a href="https://www.buymeacoffee.com/MikeRogers0" target="_blank" rel="noopener">buying me a coffee</a>.</p>
17
12
 
18
13
  report:
19
14
  memory:
data/lib/pig_ci.rb CHANGED
@@ -1,30 +1,42 @@
1
- require 'active_support'
2
- require 'active_support/core_ext/string/inflections'
3
- require 'rake'
4
-
5
- require 'pig_ci/version'
6
- require 'pig_ci/api'
7
- require 'pig_ci/configuration'
8
- require 'pig_ci/decorator'
9
- require 'pig_ci/summary'
10
- require 'pig_ci/profiler_engine'
11
- require 'pig_ci/profiler'
12
- require 'pig_ci/metric'
13
- require 'pig_ci/report'
1
+ require "active_support"
2
+ require "active_support/core_ext/string/inflections"
3
+ require "rake"
4
+
5
+ require "pig_ci/version"
6
+ require "pig_ci/configuration"
7
+ require "pig_ci/decorator"
8
+ require "pig_ci/summary"
9
+ require "pig_ci/profiler_engine"
10
+ require "pig_ci/profiler"
11
+ require "pig_ci/metric"
12
+ require "pig_ci/report"
13
+ require "pig_ci/test_frameworks"
14
14
 
15
15
  module PigCI
16
16
  extend self
17
17
 
18
18
  attr_accessor :pid
19
19
 
20
+ attr_writer :enabled
21
+ def enabled?
22
+ @enabled.nil? ? true : @enabled
23
+ end
24
+
25
+ # Rails caches repeated queries within the same request. You can not count
26
+ # any cached queries if you'd like.
27
+ attr_writer :ignore_cached_queries
28
+ def ignore_cached_queries?
29
+ @ignore_cached_queries.nil? ? false : @ignore_cached_queries
30
+ end
31
+
20
32
  attr_writer :tmp_directory
21
33
  def tmp_directory
22
- @tmp_directory || Pathname.new(Dir.getwd).join('tmp', 'pig-ci')
34
+ @tmp_directory || Pathname.new(Dir.getwd).join("tmp", "pig-ci")
23
35
  end
24
36
 
25
37
  attr_writer :output_directory
26
38
  def output_directory
27
- @output_directory || Pathname.new(Dir.getwd).join('pig-ci')
39
+ @output_directory || Pathname.new(Dir.getwd).join("pig-ci")
28
40
  end
29
41
 
30
42
  attr_accessor :generate_terminal_summary
@@ -88,29 +100,19 @@ module PigCI
88
100
  @profiler_engine ||= PigCI::ProfilerEngine::Rails.new
89
101
  end
90
102
 
91
- attr_writer :api_base_uri
92
- def api_base_uri
93
- @api_base_uri || 'https://api.pigci.com/api'
94
- end
95
-
96
- attr_accessor :api_verify_ssl
97
- def api_verify_ssl?
98
- !@api_verify_ssl.nil? ? @api_verify_ssl : true
99
- end
100
-
101
- attr_accessor :api_key
102
- def api_key?
103
- !@api_key.nil? && @api_key != ''
104
- end
105
-
106
103
  attr_writer :commit_sha1
107
104
  def commit_sha1
108
- @commit_sha1 || ENV['CI_COMMIT_ID'] || ENV['CIRCLE_SHA1'] || ENV['TRAVIS_COMMIT'] || `git rev-parse HEAD`.strip
105
+ @commit_sha1 || ENV["CI_COMMIT_ID"] || ENV["CIRCLE_SHA1"] || ENV["TRAVIS_COMMIT"] || `git rev-parse HEAD`.strip
109
106
  end
110
107
 
111
108
  attr_writer :head_branch
112
109
  def head_branch
113
- @head_branch || ENV['CI_BRANCH'] || ENV['CIRCLE_BRANCH'] || ENV['TRAVIS_BRANCH'] || `git rev-parse --abbrev-ref HEAD`.strip
110
+ @head_branch || ENV["CI_BRANCH"] || ENV["CIRCLE_BRANCH"] || ENV["TRAVIS_BRANCH"] || `git rev-parse --abbrev-ref HEAD`.strip
111
+ end
112
+
113
+ # Throw deprecation notice for setting API
114
+ def api_key=(value)
115
+ puts "DEPRECATED: PigCI.com API has been retired, you no longer need to set config.api_key in your spec/rails_helper.rb file."
114
116
  end
115
117
 
116
118
  attr_writer :locale
@@ -130,8 +132,9 @@ module PigCI
130
132
 
131
133
  def start(&block)
132
134
  self.pid = Process.pid
135
+ PigCI::TestFrameworks::Rspec.configure! if defined?(::RSpec)
133
136
 
134
- block.call(self) if block_given?
137
+ block&.call(self)
135
138
 
136
139
  # Add our translations
137
140
  load_i18ns!
@@ -146,7 +149,7 @@ module PigCI
146
149
 
147
150
  def load_i18ns!
148
151
  I18n.available_locales << PigCI.locale
149
- I18n.load_path += Dir["#{File.expand_path('../config/locales/pig_ci', __dir__)}/*.{rb,yml}"]
152
+ I18n.load_path += Dir["#{File.expand_path("../config/locales/pig_ci", __dir__)}/*.{rb,yml}"]
150
153
  end
151
154
 
152
155
  def run_exit_tasks!
@@ -161,9 +164,6 @@ module PigCI
161
164
  # Save the report summary to the project root.
162
165
  PigCI::Summary::HTML.new(reports: profiler_engine.reports).save! if PigCI.generate_html_summary?
163
166
 
164
- # If they have an API key, share it with PigCI.com
165
- PigCI::Api::Reports.new(reports: profiler_engine.reports).share! if PigCI.api_key?
166
-
167
167
  # Make sure CI fails when metrics are over thresholds.
168
168
  PigCI::Summary::CI.new(reports: profiler_engine.reports).call!
169
169
  end
@@ -1,7 +1,7 @@
1
1
  class PigCI::Configuration
2
- Thresholds = Struct.new(:memory, :request_time, :database_request) do
2
+ Thresholds = Struct.new(:memory, :request_time, :database_request) {
3
3
  def initialize(memory: 350, request_time: 250, database_request: 35)
4
4
  super(memory, request_time, database_request)
5
5
  end
6
- end
6
+ }
7
7
  end
@@ -6,4 +6,4 @@ class PigCI::Decorator
6
6
  end
7
7
  end
8
8
 
9
- require 'pig_ci/decorator/report_terminal_decorator'
9
+ require "pig_ci/decorator/report_terminal_decorator"
@@ -1,4 +1,4 @@
1
- require 'colorized_string'
1
+ require "colorized_string"
2
2
 
3
3
  class PigCI::Decorator::ReportTerminalDecorator < PigCI::Decorator
4
4
  %i[key max min mean number_of_requests].each do |field|
@@ -8,9 +8,9 @@ class PigCI::Decorator::ReportTerminalDecorator < PigCI::Decorator
8
8
  end
9
9
 
10
10
  def max_change_percentage
11
- if @object[:max_change_percentage].start_with?('-')
11
+ if @object[:max_change_percentage].start_with?("-")
12
12
  ColorizedString[@object[:max_change_percentage]].colorize(:green)
13
- elsif @object[:max_change_percentage].start_with?('0.0')
13
+ elsif @object[:max_change_percentage].start_with?("0.0")
14
14
  @object[:max_change_percentage]
15
15
  else
16
16
  ColorizedString[@object[:max_change_percentage]].colorize(:red)
data/lib/pig_ci/metric.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  class PigCI::Metric; end
2
2
 
3
- require 'pig_ci/metric/current'
4
- require 'pig_ci/metric/historical'
3
+ require "pig_ci/metric/current"
4
+ require "pig_ci/metric/historical"
@@ -7,7 +7,7 @@ class PigCI::Metric::Current
7
7
  @to_h = {}
8
8
 
9
9
  File.foreach(@log_file) do |f|
10
- key, value = f.strip.split('|')
10
+ key, value = f.strip.split("|")
11
11
  value = value.to_i
12
12
 
13
13
  @to_h[key] ||= {
@@ -11,7 +11,7 @@ class PigCI::Metric::Historical::ChangePercentage
11
11
  previous_run_data = previous_run_data_for_key(data[:key]) || data
12
12
 
13
13
  data[:max_change_percentage] = (((BigDecimal(data[:max]) - BigDecimal(previous_run_data[:max])) / BigDecimal(previous_run_data[:max])) * 100).round(PigCI.max_change_percentage_precision)
14
- data[:max_change_percentage] = BigDecimal('0') if data[:max_change_percentage].to_s == 'NaN' || data[:max_change_percentage] == BigDecimal('-0.0')
14
+ data[:max_change_percentage] = BigDecimal("0") if data[:max_change_percentage].to_s == "NaN" || data[:max_change_percentage] == BigDecimal("-0.0")
15
15
  data[:max_change_percentage] = data[:max_change_percentage].to_f
16
16
 
17
17
  data
@@ -29,15 +29,15 @@ class PigCI::Metric::Historical
29
29
 
30
30
  def remove_old_historical_data!
31
31
  new_historical_data = @to_h
32
- .sort_by { |timestamp, _data| timestamp.to_s.to_i * -1 }[0..(PigCI.historical_data_run_limit - 1)]
33
- .to_h
34
- .sort_by { |timestamp, _data| timestamp.to_s.to_i * -1 }.to_h
32
+ .sort_by { |timestamp, _data| timestamp.to_s.to_i * -1 }[0..(PigCI.historical_data_run_limit - 1)]
33
+ .to_h
34
+ .sort_by { |timestamp, _data| timestamp.to_s.to_i * -1 }.to_h
35
35
  @to_h = new_historical_data
36
36
  end
37
37
 
38
38
  def read_historical_log_file
39
39
  if File.exist?(@historical_log_file)
40
- JSON.parse(File.open(@historical_log_file, 'r').read, symbolize_names: true)
40
+ JSON.parse(File.open(@historical_log_file, "r").read, symbolize_names: true)
41
41
  else
42
42
  {}
43
43
  end
@@ -49,4 +49,4 @@ class PigCI::Metric::Historical
49
49
  end
50
50
  end
51
51
 
52
- require 'pig_ci/metric/historial/change_percentage'
52
+ require "pig_ci/metric/historial/change_percentage"
@@ -2,14 +2,14 @@ class PigCI::Profiler
2
2
  attr_accessor :log_value, :log_file, :historical_log_file, :i18n_key
3
3
 
4
4
  def initialize(i18n_key: nil, log_file: nil, historical_log_file: nil)
5
- @i18n_key = i18n_key || self.class.name.underscore.split('/').last
5
+ @i18n_key = i18n_key || self.class.name.underscore.split("/").last
6
6
  @log_file = log_file || PigCI.tmp_directory.join("#{@i18n_key}.txt")
7
7
  @historical_log_file = historical_log_file || PigCI.tmp_directory.join("#{@i18n_key}.json")
8
8
  @log_value = 0
9
9
  end
10
10
 
11
11
  def setup!
12
- File.open(log_file, 'w') { |file| file.truncate(0) }
12
+ File.open(log_file, "w") { |file| file.truncate(0) }
13
13
  end
14
14
 
15
15
  def reset!
@@ -17,8 +17,8 @@ class PigCI::Profiler
17
17
  end
18
18
 
19
19
  def log_request!(request_key)
20
- File.open(log_file, 'a+') do |f|
21
- f.puts([request_key, log_value].join('|'))
20
+ File.open(log_file, "a+") do |f|
21
+ f.puts([request_key, log_value].join("|"))
22
22
  end
23
23
  end
24
24
 
@@ -36,6 +36,6 @@ class PigCI::Profiler
36
36
  end
37
37
  end
38
38
 
39
- require 'pig_ci/profiler/memory'
40
- require 'pig_ci/profiler/request_time'
41
- require 'pig_ci/profiler/database_request'
39
+ require "pig_ci/profiler/memory"
40
+ require "pig_ci/profiler/request_time"
41
+ require "pig_ci/profiler/database_request"
@@ -1,4 +1,4 @@
1
- require 'get_process_mem'
1
+ require "get_process_mem"
2
2
 
3
3
  class PigCI::Profiler::Memory < PigCI::Profiler
4
4
  def reset!
@@ -8,7 +8,7 @@ class PigCI::ProfilerEngine
8
8
  end
9
9
 
10
10
  def request_key?
11
- !@request_key.nil? && @request_key != ''
11
+ !@request_key.nil? && @request_key != ""
12
12
  end
13
13
 
14
14
  def request_captured?
@@ -37,4 +37,4 @@ class PigCI::ProfilerEngine
37
37
  end
38
38
  end
39
39
 
40
- require 'pig_ci/profiler_engine/rails'
40
+ require "pig_ci/profiler_engine/rails"
@@ -31,10 +31,13 @@ class PigCI::ProfilerEngine::Rails < ::PigCI::ProfilerEngine
31
31
  def precompile_assets!
32
32
  # From: https://github.com/rails/sprockets-rails/blob/e9ca63edb6e658cdfcf8a35670c525b369c2ccca/test/test_railtie.rb#L7-L13
33
33
  ::Rails.application.load_tasks
34
- ::Rake.application['assets:precompile'].execute
34
+ ::Rake.application["assets:precompile"].execute
35
35
  end
36
36
 
37
37
  def eager_load_rails!
38
+ # None of these methods will work pre-rails 5.
39
+ return unless ::Rails.version.to_f >= 5.0
40
+
38
41
  # Eager load rails to give more accurate memory levels.
39
42
  ::Rails.application.eager_load!
40
43
  ::Rails.application.routes.eager_load!
@@ -45,30 +48,32 @@ class PigCI::ProfilerEngine::Rails < ::PigCI::ProfilerEngine
45
48
  def make_blank_application_request!
46
49
  # Make a call to the root path to load up as much of rails as possible
47
50
  # Done within a timezone block as it affects the timezone.
48
- Time.use_zone('UTC') do
49
- ::Rails.application.call(::Rack::MockRequest.env_for('/'))
51
+ Time.use_zone("UTC") do
52
+ ::Rails.application.call(::Rack::MockRequest.env_for("/"))
50
53
  end
51
54
  end
52
55
 
53
56
  def attach_listeners!
54
- ::ActiveSupport::Notifications.subscribe 'start_processing.action_controller' do |_name, _started, _finished, _unique_id, payload|
57
+ ::ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |_name, _started, _finished, _unique_id, payload|
55
58
  request_key_from_payload!(payload)
56
59
 
57
60
  profilers.each(&:reset!)
58
61
  end
59
62
 
60
- ::ActiveSupport::Notifications.subscribe 'sql.active_record' do |_name, _started, _finished, _unique_id, _payload|
61
- if request_key?
62
- profilers.select { |profiler| profiler.class == PigCI::Profiler::DatabaseRequest }.each(&:increment!)
63
+ ::ActiveSupport::Notifications.subscribe "sql.active_record" do |_name, _started, _finished, _unique_id, payload|
64
+ if request_key? && PigCI.enabled? && (!PigCI.ignore_cached_queries? || (PigCI.ignore_cached_queries? && !payload[:cached]))
65
+ profilers.select { |profiler| profiler.instance_of?(PigCI::Profiler::DatabaseRequest) }.each(&:increment!)
63
66
  end
64
67
  end
65
68
 
66
- ::ActiveSupport::Notifications.subscribe 'process_action.action_controller' do |_name, _started, _finished, _unique_id, _payload|
67
- profilers.each do |profiler|
68
- profiler.log_request!(request_key)
69
- end
69
+ ::ActiveSupport::Notifications.subscribe "process_action.action_controller" do |_name, _started, _finished, _unique_id, _payload|
70
+ if PigCI.enabled?
71
+ profilers.each do |profiler|
72
+ profiler.log_request!(request_key)
73
+ end
70
74
 
71
- request_captured!
75
+ request_captured!
76
+ end
72
77
  self.request_key = nil
73
78
  end
74
79
  end
data/lib/pig_ci/report.rb CHANGED
@@ -2,7 +2,7 @@ class PigCI::Report
2
2
  attr_accessor :historical_log_file, :i18n_key
3
3
 
4
4
  def initialize(historical_log_file: nil, i18n_key: nil, timestamp: nil)
5
- @i18n_key = i18n_key || self.class.name.underscore.split('/').last
5
+ @i18n_key = i18n_key || self.class.name.underscore.split("/").last
6
6
  @historical_log_file = historical_log_file || PigCI.tmp_directory.join("#{@i18n_key}.json")
7
7
  @timestamp = timestamp || PigCI.run_timestamp
8
8
  end
@@ -12,7 +12,7 @@ class PigCI::Report
12
12
  end
13
13
 
14
14
  def i18n_name
15
- I18n.t('.name', scope: i18n_scope, locale: PigCI.locale)
15
+ I18n.t(".name", scope: i18n_scope, locale: PigCI.locale)
16
16
  end
17
17
 
18
18
  def max_for(timestamp)
@@ -30,9 +30,9 @@ class PigCI::Report
30
30
  end
31
31
 
32
32
  def sorted_and_formatted_data_for(timestamp)
33
- data_for(timestamp)[@i18n_key.to_sym].sort_by do |data|
33
+ data_for(timestamp)[@i18n_key.to_sym].sort_by { |data|
34
34
  PigCI.report_row_sort_by(data)
35
- end.collect do |data|
35
+ }.collect do |data|
36
36
  self.class.format_row(data)
37
37
  end
38
38
  end
@@ -73,6 +73,6 @@ class PigCI::Report
73
73
  end
74
74
  end
75
75
 
76
- require 'pig_ci/report/memory'
77
- require 'pig_ci/report/request_time'
78
- require 'pig_ci/report/database_request'
76
+ require "pig_ci/report/memory"
77
+ require "pig_ci/report/request_time"
78
+ require "pig_ci/report/database_request"
@@ -10,6 +10,6 @@ class PigCI::Report::Memory < PigCI::Report
10
10
  end
11
11
 
12
12
  def self.bytes_in_a_megabyte
13
- @bytes_in_a_megabyte ||= BigDecimal(1_048_576)
13
+ @bytes_in_a_megabyte ||= BigDecimal("1_048_576")
14
14
  end
15
15
  end
@@ -1,5 +1,5 @@
1
1
  class PigCI::Summary; end
2
2
 
3
- require 'pig_ci/summary/ci'
4
- require 'pig_ci/summary/html'
5
- require 'pig_ci/summary/terminal'
3
+ require "pig_ci/summary/ci"
4
+ require "pig_ci/summary/html"
5
+ require "pig_ci/summary/terminal"
@@ -1,4 +1,4 @@
1
- require 'colorized_string'
1
+ require "colorized_string"
2
2
 
3
3
  class PigCI::Summary::CI < PigCI::Summary
4
4
  def initialize(reports:)
@@ -7,8 +7,8 @@ class PigCI::Summary::CI < PigCI::Summary
7
7
  end
8
8
 
9
9
  def call!
10
- puts ''
11
- puts I18n.t('pig_ci.summary.ci_start')
10
+ puts ""
11
+ puts I18n.t("pig_ci.summary.ci_start")
12
12
 
13
13
  over_threshold = false
14
14
  @reports.each do |report|
@@ -17,22 +17,22 @@ class PigCI::Summary::CI < PigCI::Summary
17
17
  end
18
18
 
19
19
  fail_with_error! if over_threshold
20
- puts ''
20
+ puts ""
21
21
  end
22
22
 
23
23
  private
24
24
 
25
25
  def fail_with_error!
26
- puts I18n.t('pig_ci.summary.ci_failure')
26
+ puts I18n.t("pig_ci.summary.ci_failure")
27
27
  Kernel.exit(2)
28
28
  end
29
29
 
30
30
  def print_report(report)
31
31
  max_and_threshold = [
32
32
  report.max_for(@timestamp).to_s,
33
- '/',
33
+ "/",
34
34
  report.threshold
35
- ].join(' ')
35
+ ].join(" ")
36
36
 
37
37
  if report.over_threshold_for?(@timestamp)
38
38
  puts "#{report.i18n_name}: #{ColorizedString[max_and_threshold].colorize(:red)}\n"