arca 2.2.0 → 2.3.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
- SHA1:
3
- metadata.gz: b0591095b4b348fcbd76cf72ef3cea8aeecb8016
4
- data.tar.gz: bd32d70f3788e5238761d3368b6944b923860c54
2
+ SHA256:
3
+ metadata.gz: 326dbd7961f9ccfe0b39d77572d3fcc6599179feaf88a81f3fdfdc64ce0bb8e2
4
+ data.tar.gz: e0298827379b3759f81eaac23fb9d626b8ce20ae4150a4c44b01379157c6263a
5
5
  SHA512:
6
- metadata.gz: 9ea28b0b452751d96980314871b79df23b5ea261e9defbc9e3f331690d1c5ca4f4fee7b8c6c65461298faab770034c1c58e752b89cd9f5aa833b032b784a5c5b
7
- data.tar.gz: 5477fd14ed651d2681b8167db4ef3ee5ea60ae7246f73cb9e9e36c025df1f2747678d1db410b47113d8f78985bde696cf25b2cfee7e4b69bd90e92f35f001250
6
+ metadata.gz: 421d318fdbabf614179e883b5b009d3f7f8a560dbaed1c885ddcc09d14f656f774b162f3d111c576cf0b2fc5f63bfe913e7be09cb043c1c84a8fc18961a9a1c4
7
+ data.tar.gz: 6d9f740fb81d86ef2b2ede9b803ac04e77a3327b2053f48e4cbcbf551217293939cacba68b0c5ef87e47e8c90972eb7afe96ead015364011b7d34a21c0f6dae1
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ActiveRecord Callback Analyzer
2
2
 
3
- Arca is a callback analyzer for ActiveRecord models ideally suited for digging yourself out of callback hell. At best it will help you move towards a [more maintainable design](http://adequate.io/culling-the-activerecord-lifecycle) and at worst it can be used in your test suite to give you feedback when callbacks change.
3
+ Arca is a callback analyzer for ActiveRecord models ideally suited for digging yourself out of callback hell. At best it will help you move towards a [more maintainable design](https://web.archive.org/web/20161016162603/http://adequate.io/culling-the-activerecord-lifecycle) and at worst it can be used in your test suite to give you feedback when callbacks change.
4
4
 
5
5
  Arca helps you answer questions like:
6
6
 
@@ -10,6 +10,8 @@ Arca helps you answer questions like:
10
10
 
11
11
  The Arca library has two main components, the collector and the reporter. Include the collector module in ActiveRecord::Base before your models are loaded.
12
12
 
13
+ At GitHub, we test callbacks by whitelisting existing callbacks, and adding a lint test to ensure new callbacks are not added without review. The [examples](examples) folder is a good starting point.
14
+
13
15
  ## Requirements
14
16
 
15
17
  ![travis-ci build status](https://travis-ci.org/jonmagic/arca.svg)
@@ -34,7 +36,9 @@ class ActiveRecord::Base
34
36
  include Arca::Collector
35
37
  end
36
38
 
37
- # load your app
39
+ # load your app. It's important to setup before loading your models because Arca
40
+ # works by wrapping itself around the callback method definitions (before_save,
41
+ # after_save, etc) and then records how and where those methods are used.
38
42
  ```
39
43
 
40
44
  In this example the `Annoucements` module is included in `Ticket` and defines it's own callback.
@@ -212,6 +216,12 @@ have to update this test to make it pass.
212
216
  ---------------------------------------------
213
217
  ```
214
218
 
219
+ ## Contributors
220
+
221
+ - [@jonmagic](https://github.com/jonmagic)
222
+ - [@jch](https://github.com/jch)
223
+ - [@bensheldon](https://github.com/bensheldon)
224
+
215
225
  ## License
216
226
 
217
227
  The MIT License (MIT)
data/arca.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "arca"
3
- spec.version = "2.2.0"
3
+ spec.version = "2.3.0"
4
4
  spec.date = "2015-08-07"
5
5
  spec.summary = "ActiveRecord callback analyzer"
6
6
  spec.description = "Arca is a callback analyzer for ActiveRecord ideally suited for digging yourself out of callback hell"
@@ -0,0 +1,42 @@
1
+ require "minitest"
2
+
3
+ class ActiveRecordLintTest < Minitest::Test
4
+ def test_callbacks_must_be_defined_in_the_base_model_file
5
+ whitelist_path = File.expand_path("../active_record_callback_whitelist.txt", __FILE__)
6
+ whitelisted_callbacks = if File.exists?(whitelist_path)
7
+ File.read(whitelist_path).split("\n")
8
+ else
9
+ ""
10
+ end
11
+
12
+ # git grep... list classes with a parent. Does not handle classes nested within a module
13
+ # xargs... arca analyze. We skip line numbers so we can diff the results
14
+ # grep... filter for callbacks defined in external files or callbacks without names
15
+ #
16
+ # To update the whitelist, save the output up to script/audit-callbacks.
17
+ callback_output = IO.popen(<<-CMD).read
18
+ git grep -h '^class.*< ' -- '*.rb' | cut -d' ' -f 2 | sort -u | \
19
+ xargs bundle exec audit-callbaks.rb --skip-line-num | \
20
+ grep -E 'external:true|block$'
21
+ CMD
22
+
23
+ actual_callbacks = callback_output.split("\n")
24
+
25
+ new_bad_callbacks = actual_callbacks - whitelisted_callbacks
26
+ unnecessary_whitelist_entries = whitelisted_callbacks - actual_callbacks
27
+
28
+ message = ""
29
+ if new_bad_callbacks.any?
30
+ message << "The following ActiveRecord callbacks must be defined in the base model file with a named method:\n\n"
31
+ message << new_bad_callbacks.join("\n")
32
+ end
33
+
34
+ if unnecessary_whitelist_entries.any?
35
+ message << "\n\n" unless message.empty?
36
+ message << "Hooray! You removed a bad ActiveRecord callback. Please update #{whitelist_path} and remove the following\n\n"
37
+ message << unnecessary_whitelist_entries.join("\n")
38
+ end
39
+
40
+ assert message.empty?, message
41
+ end
42
+ end
@@ -0,0 +1,75 @@
1
+ # Prints a list of Active Record callbacks for the given models
2
+ #
3
+ # Usage:
4
+ # bundle exec audit-callbacks.rb [--skip-line-num] [Model1 Model2...]
5
+ #
6
+ skip_line_num = false
7
+ if ARGV.first == "--skip-line-num"
8
+ ARGV.shift
9
+ skip_line_num = true
10
+ end
11
+
12
+ unless ARGV.size > 0
13
+ $stderr.puts "No models specified. Try script/audit-callbacks User Issue."
14
+ exit 1
15
+ end
16
+
17
+ # Arca must be required after ActiveRecord, but before the environment loads so
18
+ # we can install Arca::Collector.
19
+ require "active_record"
20
+ require "arca"
21
+ class ActiveRecord::Base
22
+ include Arca::Collector
23
+ end
24
+
25
+ require "config/environment"
26
+
27
+ # Returns a formatted string of a callback analysis.
28
+ #
29
+ # Examples:
30
+ #
31
+ # An unnamed (block) before_destroy callback defined in the same file as the model
32
+ # Ability before_destroy app/models/ability.rb external:false block
33
+ #
34
+ # A after_destroy callback named `dereference_asset` defined in a file outside of the model (external:true)
35
+ # Avatar after_destroy app/models/asset_uploadable.rb external:true dereference_asset
36
+ #
37
+ # A before_save callback defined by a callback class
38
+ # IssueComment before_save app/models/referrer.rb external:true Referrer::ReferenceMentionsCallback
39
+ #
40
+ def format_callback(callback, skip_line_num:)
41
+ path = Arca.relative_path(callback.callback_file_path)
42
+ path << ":#{callback.callback_line_number}" unless skip_line_num
43
+
44
+ # Arca outputs object ids which triggers a diff
45
+ # e.g. #<Referrer::ReferenceMentionsCallback:0x007f8bca3a1b48>
46
+ target = if match = /#<(.+):.+>/.match(callback.target_symbol.to_s)
47
+ match[1]
48
+ else
49
+ callback.target_symbol
50
+ end
51
+
52
+ [
53
+ callback.model.name,
54
+ callback.callback_symbol,
55
+ path,
56
+ "external:#{callback.external_callback?}",
57
+ target
58
+ ].map(&:to_s).join(" ")
59
+ end
60
+
61
+ ARGV.each do |model_name|
62
+ begin
63
+ model_class = model_name.constantize
64
+ rescue NameError # test classes
65
+ next
66
+ end
67
+
68
+ next unless model_class.ancestors.include?(ActiveRecord::Base)
69
+
70
+ Arca[model_class].analyzed_callbacks.each do |callback_symbol, callbacks|
71
+ callbacks.each do |callback|
72
+ puts format_callback(callback, skip_line_num: skip_line_num)
73
+ end
74
+ end
75
+ end
@@ -33,8 +33,8 @@ module Arca
33
33
  # Duplicate args before modifying.
34
34
  args_copy = args.dup
35
35
 
36
- # Add target_symbol :inline to args_copy if a block, Proc, or Class
37
- # was given.
36
+ # Add target_symbol :inline to args_copy if given a block or Proc and
37
+ # class name if a class or instance was given.
38
38
  if block
39
39
  args_copy.unshift(:inline)
40
40
  elsif args_copy.first.kind_of?(Proc)
data/lib/arca/model.rb CHANGED
@@ -15,9 +15,11 @@ module Arca
15
15
  # they are used in the life cycle of an ActiveRecord model.
16
16
  CALLBACKS = [
17
17
  :after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
18
- :before_save, :around_save, :after_save, :before_create, :around_create,
19
- :after_create, :before_update, :around_update, :after_update,
20
- :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
18
+ :before_save, :around_save, :after_save, :after_save_commit,
19
+ :before_create, :around_create, :after_create, :after_create_commit,
20
+ :before_update, :around_update, :after_update, :after_update_commit,
21
+ :before_destroy, :around_destroy, :after_destroy, :after_destroy_commit,
22
+ :after_commit, :after_rollback
21
23
  ]
22
24
 
23
25
  # Public: ActiveRecord model class.
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arca
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Hoyt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2015-08-07 00:00:00.000000000 Z
@@ -79,6 +79,8 @@ files:
79
79
  - README.md
80
80
  - Rakefile
81
81
  - arca.gemspec
82
+ - examples/active_record_lint_test.rb
83
+ - examples/audit-callbacks.rb
82
84
  - gemfiles/Gemfile_activerecord-3.2
83
85
  - gemfiles/Gemfile_activerecord-4.2
84
86
  - lib/arca.rb
@@ -99,7 +101,7 @@ homepage: https://github.com/jonmagic/arca
99
101
  licenses:
100
102
  - MIT
101
103
  metadata: {}
102
- post_install_message:
104
+ post_install_message:
103
105
  rdoc_options: []
104
106
  require_paths:
105
107
  - lib
@@ -114,9 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
116
  - !ruby/object:Gem::Version
115
117
  version: '0'
116
118
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.2.2
119
- signing_key:
119
+ rubygems_version: 3.5.5
120
+ signing_key:
120
121
  specification_version: 4
121
122
  summary: ActiveRecord callback analyzer
122
123
  test_files: