dead_gems 0.0.2

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +102 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +42 -0
  7. data/Rakefile +2 -0
  8. data/dead_gems.gemspec +29 -0
  9. data/dummy/.gitignore +16 -0
  10. data/dummy/Gemfile +45 -0
  11. data/dummy/Gemfile.lock +130 -0
  12. data/dummy/README.rdoc +28 -0
  13. data/dummy/Rakefile +6 -0
  14. data/dummy/app/assets/images/.keep +0 -0
  15. data/dummy/app/assets/javascripts/application.js +16 -0
  16. data/dummy/app/assets/stylesheets/application.css +15 -0
  17. data/dummy/app/controllers/application_controller.rb +5 -0
  18. data/dummy/app/controllers/concerns/.keep +0 -0
  19. data/dummy/app/helpers/application_helper.rb +2 -0
  20. data/dummy/app/mailers/.keep +0 -0
  21. data/dummy/app/models/.keep +0 -0
  22. data/dummy/app/models/concerns/.keep +0 -0
  23. data/dummy/app/models/user.rb +8 -0
  24. data/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/dummy/bin/bundle +3 -0
  26. data/dummy/bin/rails +8 -0
  27. data/dummy/bin/rake +8 -0
  28. data/dummy/bin/spring +15 -0
  29. data/dummy/config/application.rb +23 -0
  30. data/dummy/config/boot.rb +4 -0
  31. data/dummy/config/database.yml +25 -0
  32. data/dummy/config/environment.rb +5 -0
  33. data/dummy/config/environments/development.rb +37 -0
  34. data/dummy/config/environments/production.rb +82 -0
  35. data/dummy/config/environments/test.rb +39 -0
  36. data/dummy/config/initializers/assets.rb +8 -0
  37. data/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/dummy/config/initializers/cookies_serializer.rb +3 -0
  39. data/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  40. data/dummy/config/initializers/inflections.rb +16 -0
  41. data/dummy/config/initializers/mime_types.rb +4 -0
  42. data/dummy/config/initializers/session_store.rb +3 -0
  43. data/dummy/config/initializers/wrap_parameters.rb +14 -0
  44. data/dummy/config/locales/en.yml +23 -0
  45. data/dummy/config/routes.rb +56 -0
  46. data/dummy/config/secrets.yml +22 -0
  47. data/dummy/config.ru +4 -0
  48. data/dummy/db/seeds.rb +7 -0
  49. data/dummy/lib/assets/.keep +0 -0
  50. data/dummy/lib/tasks/.keep +0 -0
  51. data/dummy/log/.keep +0 -0
  52. data/dummy/public/404.html +67 -0
  53. data/dummy/public/422.html +67 -0
  54. data/dummy/public/500.html +66 -0
  55. data/dummy/public/favicon.ico +0 -0
  56. data/dummy/public/robots.txt +5 -0
  57. data/dummy/test/controllers/.keep +0 -0
  58. data/dummy/test/fixtures/.keep +0 -0
  59. data/dummy/test/helpers/.keep +0 -0
  60. data/dummy/test/integration/.keep +0 -0
  61. data/dummy/test/mailers/.keep +0 -0
  62. data/dummy/test/models/.keep +0 -0
  63. data/dummy/test/models/user_test.rb +7 -0
  64. data/dummy/test/test_helper.rb +34 -0
  65. data/dummy/vendor/assets/javascripts/.keep +0 -0
  66. data/dummy/vendor/assets/stylesheets/.keep +0 -0
  67. data/lib/dead_gems/version.rb +3 -0
  68. data/lib/dead_gems.rb +81 -0
  69. data/spec/dead_gems_spec.rb +38 -0
  70. data/spec/spec_helper.rb +6 -0
  71. metadata +215 -0
data/lib/dead_gems.rb ADDED
@@ -0,0 +1,81 @@
1
+ require "dead_gems/version"
2
+ require "logger"
3
+ require "bundler"
4
+
5
+ module DeadGems
6
+ GemInstance = Struct.new(:name, :path)
7
+
8
+ class << self
9
+ def find(project_root, exerciser)
10
+ begin_dir = Dir.pwd
11
+ logger = Logger.new($stdout)
12
+ change_directory_to project_root
13
+ gems = find_all_gems.map do |name|
14
+ path = find_gem_path(name)
15
+ GemInstance.new(name, path)
16
+ end
17
+ apply_environment_patch(gems) do
18
+ run(exerciser, gems)
19
+ end
20
+ ensure
21
+ change_directory_to begin_dir
22
+ end
23
+
24
+ private
25
+
26
+ def change_directory_to(dir)
27
+ Dir.chdir(dir)
28
+ end
29
+
30
+ def find_all_gems
31
+ Bundler.with_clean_env do
32
+ gem_lines = File.read('Gemfile.lock').split("DEPENDENCIES\n").last
33
+ arr = []
34
+ gem_lines.each_line { |line| arr << line.match(/\s*([^\s!]+)/).captures.first }
35
+ arr
36
+ end
37
+ end
38
+
39
+ def find_gem_path(gem)
40
+ Bundler.with_clean_env do
41
+ `bundle list #{gem}`.chomp
42
+ end
43
+ end
44
+
45
+ def apply_environment_patch(gems)
46
+ file = 'test/test_helper.rb'
47
+ prepatch = File.read(file)
48
+ patch = <<-END
49
+ gem_paths = #{gems.map(&:path)}
50
+ trace = TracePoint.new(:call) do |tp|
51
+ # Gem is used
52
+ # Print to file
53
+ if path = gem_paths.detect {|p| tp.path.include?(p)}
54
+ puts "Gem used: \#{tp.defined_class} called with \#{tp.method_id} in \#{tp.path}"
55
+ File.open('dead_gems.out', 'a') {|f| f.puts path}
56
+ gem_paths.delete(path)
57
+ end
58
+ end
59
+ trace.enable
60
+ END
61
+ File.open(file, 'w') { |f| f.write([prepatch, patch].join("\n")) }
62
+ yield
63
+ ensure
64
+ File.open(file, 'w') { |f| f.write(prepatch) }
65
+ File.delete('dead_gems.out') if File.exists?('dead_gems.out')
66
+ end
67
+
68
+ def run(exerciser, gems)
69
+ Bundler.with_clean_env do
70
+ # If all tests pass then the gem is unused.
71
+ # Otherwise it would've have exited on-call.
72
+ system exerciser
73
+ File.read('dead_gems.out').each_line do |line|
74
+ path = line.chomp
75
+ gems.delete_if {|g| g.path == path}
76
+ end
77
+ gems.map(&:name)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ class DeadGemsSpec < Minitest::Spec
4
+ describe '.find' do
5
+ describe 'given the dummy app and the test shell command' do
6
+ before do
7
+ @project_path = File.expand_path('../../dummy', __FILE__)
8
+ @exerciser_command = 'bundle exec rake &> /dev/null'
9
+ end
10
+
11
+ it 'outputs factory_girl in the list of unused gems' do
12
+ assert DeadGems.find(@project_path, @exerciser_command).include?('factory_girl')
13
+ end
14
+
15
+ it 'doesnt output timecop in the list of unused gems' do
16
+ r = DeadGems.find(@project_path, @exerciser_command)
17
+ assert !r.include?('timecop')
18
+ end
19
+ end
20
+ end
21
+
22
+ describe '.find_all_gems' do
23
+ it 'correctly parses outs bangs' do
24
+ begin
25
+ str = <<-FILE
26
+ DEPENDENCIES
27
+ test!
28
+ FILE
29
+
30
+ original = File.method(:read)
31
+ File.define_singleton_method(:read, -> (f) { str })
32
+ assert DeadGems.send(:find_all_gems).any? {|g| g == 'test'}
33
+ ensure
34
+ File.define_singleton_method(:read, original)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,6 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'dead_gems'
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+ require 'minitest/spec'
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dead_gems
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Josh Bodah
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: spy_rb
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: dead_gems works by analyzing your gem dependencies and running an exerciser
112
+ script to see if any of them were used
113
+ email:
114
+ - jb3689@yahoo.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - Guardfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - dead_gems.gemspec
126
+ - dummy/.gitignore
127
+ - dummy/Gemfile
128
+ - dummy/Gemfile.lock
129
+ - dummy/README.rdoc
130
+ - dummy/Rakefile
131
+ - dummy/app/assets/images/.keep
132
+ - dummy/app/assets/javascripts/application.js
133
+ - dummy/app/assets/stylesheets/application.css
134
+ - dummy/app/controllers/application_controller.rb
135
+ - dummy/app/controllers/concerns/.keep
136
+ - dummy/app/helpers/application_helper.rb
137
+ - dummy/app/mailers/.keep
138
+ - dummy/app/models/.keep
139
+ - dummy/app/models/concerns/.keep
140
+ - dummy/app/models/user.rb
141
+ - dummy/app/views/layouts/application.html.erb
142
+ - dummy/bin/bundle
143
+ - dummy/bin/rails
144
+ - dummy/bin/rake
145
+ - dummy/bin/spring
146
+ - dummy/config.ru
147
+ - dummy/config/application.rb
148
+ - dummy/config/boot.rb
149
+ - dummy/config/database.yml
150
+ - dummy/config/environment.rb
151
+ - dummy/config/environments/development.rb
152
+ - dummy/config/environments/production.rb
153
+ - dummy/config/environments/test.rb
154
+ - dummy/config/initializers/assets.rb
155
+ - dummy/config/initializers/backtrace_silencers.rb
156
+ - dummy/config/initializers/cookies_serializer.rb
157
+ - dummy/config/initializers/filter_parameter_logging.rb
158
+ - dummy/config/initializers/inflections.rb
159
+ - dummy/config/initializers/mime_types.rb
160
+ - dummy/config/initializers/session_store.rb
161
+ - dummy/config/initializers/wrap_parameters.rb
162
+ - dummy/config/locales/en.yml
163
+ - dummy/config/routes.rb
164
+ - dummy/config/secrets.yml
165
+ - dummy/db/seeds.rb
166
+ - dummy/lib/assets/.keep
167
+ - dummy/lib/tasks/.keep
168
+ - dummy/log/.keep
169
+ - dummy/public/404.html
170
+ - dummy/public/422.html
171
+ - dummy/public/500.html
172
+ - dummy/public/favicon.ico
173
+ - dummy/public/robots.txt
174
+ - dummy/test/controllers/.keep
175
+ - dummy/test/fixtures/.keep
176
+ - dummy/test/helpers/.keep
177
+ - dummy/test/integration/.keep
178
+ - dummy/test/mailers/.keep
179
+ - dummy/test/models/.keep
180
+ - dummy/test/models/user_test.rb
181
+ - dummy/test/test_helper.rb
182
+ - dummy/vendor/assets/javascripts/.keep
183
+ - dummy/vendor/assets/stylesheets/.keep
184
+ - lib/dead_gems.rb
185
+ - lib/dead_gems/version.rb
186
+ - spec/dead_gems_spec.rb
187
+ - spec/spec_helper.rb
188
+ homepage: ''
189
+ licenses:
190
+ - MIT
191
+ metadata: {}
192
+ post_install_message:
193
+ rdoc_options: []
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ requirements: []
207
+ rubyforge_project:
208
+ rubygems_version: 2.2.2
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: a gem for finding unused gems in your project
212
+ test_files:
213
+ - spec/dead_gems_spec.rb
214
+ - spec/spec_helper.rb
215
+ has_rdoc: