speed_gun 1.0.0.rc1 → 2.0.0.pre.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -18
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +61 -1
  5. data/.travis.yml +3 -4
  6. data/LICENSE.txt +17 -18
  7. data/README.md +19 -137
  8. data/Rakefile +9 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/example/rails/.gitignore +18 -0
  12. data/example/rails/Gemfile +20 -0
  13. data/example/rails/Gemfile.lock +184 -0
  14. data/example/rails/README.rdoc +28 -0
  15. data/example/rails/Rakefile +6 -0
  16. data/example/rails/app/assets/images/.keep +0 -0
  17. data/example/rails/app/assets/javascripts/application.js +15 -0
  18. data/example/rails/app/assets/javascripts/posts.coffee +3 -0
  19. data/example/rails/app/assets/stylesheets/application.css +15 -0
  20. data/example/rails/app/assets/stylesheets/posts.scss +3 -0
  21. data/example/rails/app/assets/stylesheets/scaffolds.scss +73 -0
  22. data/example/rails/app/controllers/application_controller.rb +5 -0
  23. data/example/rails/app/controllers/concerns/.keep +0 -0
  24. data/example/rails/app/controllers/posts_controller.rb +74 -0
  25. data/example/rails/app/helpers/application_helper.rb +2 -0
  26. data/example/rails/app/helpers/posts_helper.rb +2 -0
  27. data/example/rails/app/mailers/.keep +0 -0
  28. data/example/rails/app/models/.keep +0 -0
  29. data/example/rails/app/models/concerns/.keep +0 -0
  30. data/example/rails/app/models/post.rb +2 -0
  31. data/example/rails/app/views/layouts/application.html.erb +14 -0
  32. data/example/rails/app/views/posts/_form.html.erb +25 -0
  33. data/example/rails/app/views/posts/edit.html.erb +6 -0
  34. data/example/rails/app/views/posts/index.html.erb +29 -0
  35. data/example/rails/app/views/posts/index.json.jbuilder +4 -0
  36. data/example/rails/app/views/posts/new.html.erb +5 -0
  37. data/example/rails/app/views/posts/show.html.erb +14 -0
  38. data/example/rails/app/views/posts/show.json.jbuilder +1 -0
  39. data/example/rails/bin/bundle +3 -0
  40. data/example/rails/bin/rails +9 -0
  41. data/example/rails/bin/rake +9 -0
  42. data/example/rails/bin/setup +29 -0
  43. data/example/rails/bin/spring +15 -0
  44. data/example/rails/config/application.rb +26 -0
  45. data/example/rails/config/boot.rb +3 -0
  46. data/example/rails/config/database.yml +25 -0
  47. data/example/rails/config/environment.rb +5 -0
  48. data/example/rails/config/environments/development.rb +41 -0
  49. data/example/rails/config/environments/production.rb +79 -0
  50. data/example/rails/config/environments/test.rb +42 -0
  51. data/example/rails/config/initializers/assets.rb +11 -0
  52. data/example/rails/config/initializers/backtrace_silencers.rb +7 -0
  53. data/example/rails/config/initializers/cookies_serializer.rb +3 -0
  54. data/example/rails/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/example/rails/config/initializers/inflections.rb +16 -0
  56. data/example/rails/config/initializers/mime_types.rb +4 -0
  57. data/example/rails/config/initializers/session_store.rb +3 -0
  58. data/example/rails/config/initializers/wrap_parameters.rb +14 -0
  59. data/example/rails/config/locales/en.yml +23 -0
  60. data/example/rails/config/routes.rb +57 -0
  61. data/example/rails/config/secrets.yml +22 -0
  62. data/example/rails/config.ru +4 -0
  63. data/example/rails/db/migrate/20160619175824_create_posts.rb +10 -0
  64. data/example/rails/db/schema.rb +23 -0
  65. data/example/rails/db/seeds.rb +7 -0
  66. data/example/rails/lib/assets/.keep +0 -0
  67. data/example/rails/lib/tasks/.keep +0 -0
  68. data/example/rails/log/.keep +0 -0
  69. data/example/rails/public/404.html +67 -0
  70. data/example/rails/public/422.html +67 -0
  71. data/example/rails/public/500.html +66 -0
  72. data/example/rails/public/favicon.ico +0 -0
  73. data/example/rails/public/robots.txt +5 -0
  74. data/example/rails/test/controllers/.keep +0 -0
  75. data/example/rails/test/controllers/posts_controller_test.rb +49 -0
  76. data/example/rails/test/fixtures/.keep +0 -0
  77. data/example/rails/test/fixtures/posts.yml +9 -0
  78. data/example/rails/test/helpers/.keep +0 -0
  79. data/example/rails/test/integration/.keep +0 -0
  80. data/example/rails/test/mailers/.keep +0 -0
  81. data/example/rails/test/models/.keep +0 -0
  82. data/example/rails/test/models/post_test.rb +7 -0
  83. data/example/rails/test/test_helper.rb +10 -0
  84. data/example/rails/vendor/assets/javascripts/.keep +0 -0
  85. data/example/rails/vendor/assets/stylesheets/.keep +0 -0
  86. data/lib/rack/speed_gun.rb +100 -0
  87. data/lib/speed_gun/app/public/report.js +58 -0
  88. data/lib/speed_gun/app/views/events.slim +11 -0
  89. data/lib/speed_gun/app/views/payload.slim +20 -0
  90. data/lib/speed_gun/app/views/report.scss +322 -0
  91. data/lib/speed_gun/app/views/report.slim +57 -0
  92. data/lib/speed_gun/app.rb +53 -0
  93. data/lib/speed_gun/config.rb +25 -32
  94. data/lib/speed_gun/event.rb +29 -39
  95. data/lib/speed_gun/profiler/action_controller_profiler.rb +3 -8
  96. data/lib/speed_gun/profiler/action_mailer_profiler.rb +7 -0
  97. data/lib/speed_gun/profiler/action_view_profiler.rb +3 -8
  98. data/lib/speed_gun/profiler/active_job_profiler.rb +6 -0
  99. data/lib/speed_gun/profiler/active_record_profiler.rb +3 -8
  100. data/lib/speed_gun/profiler/active_support_notifications_profiler.rb +9 -6
  101. data/lib/speed_gun/profiler/active_support_profiler.rb +8 -0
  102. data/lib/speed_gun/profiler/line_profiler.rb +32 -0
  103. data/lib/speed_gun/profiler/rack_profiler.rb +2 -4
  104. data/lib/speed_gun/profiler.rb +15 -9
  105. data/lib/speed_gun/railtie.rb +21 -5
  106. data/lib/speed_gun/report.rb +65 -0
  107. data/lib/speed_gun/source.rb +90 -0
  108. data/lib/speed_gun/store/file_store.rb +35 -0
  109. data/lib/speed_gun/store/memory_store.rb +7 -14
  110. data/lib/speed_gun/store.rb +10 -3
  111. data/lib/speed_gun/version.rb +9 -1
  112. data/lib/speed_gun.rb +21 -26
  113. data/speed_gun.gemspec +21 -16
  114. metadata +168 -58
  115. data/.coveralls.yml +0 -1
  116. data/lib/speed_gun/app/views/meter.html.slim +0 -4
  117. data/lib/speed_gun/middleware.rb +0 -91
  118. data/lib/speed_gun/profile.rb +0 -102
  119. data/lib/speed_gun/store/elastic_search_store.rb +0 -64
  120. data/lib/speed_gun/store/fluent_logger_store.rb +0 -29
  121. data/lib/speed_gun/store/memcache_store.rb +0 -40
  122. data/lib/speed_gun/store/multiple_store.rb +0 -23
  123. data/lib/speed_gun/store/redis_store.rb +0 -41
  124. data/lib/speed_gun/template.rb +0 -15
  125. data/spec/lib/speed_gun/config_spec.rb +0 -37
  126. data/spec/lib/speed_gun/event_spec.rb +0 -70
  127. data/spec/lib/speed_gun/middleware_spec.rb +0 -65
  128. data/spec/lib/speed_gun/profile_spec.rb +0 -41
  129. data/spec/lib/speed_gun_spec.rb +0 -52
  130. data/spec/spec_helper.rb +0 -9
  131. data/spec/support/simplecov.rb +0 -12
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'speed_gun/profiler/active_support_notifications_profiler'
3
+
4
+ class SpeedGun::Profiler::ActiveSupportProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+ subscribe %r{\.active_support$}
6
+ end
7
+
8
+
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require 'rblineprof'
3
+ require 'speed_gun/source'
4
+ require 'speed_gun/profiler'
5
+
6
+ class SpeedGun::Profiler::LineProfiler < SpeedGun::Profiler
7
+ def self.regexp
8
+ if SpeedGun.config.lineprof_paths.empty?
9
+ %r{.}
10
+ else
11
+ Regexp.union(*SpeedGun.config.lineprof_paths)
12
+ end
13
+ end
14
+
15
+ def profile(*_args)
16
+ return yield if self.class.ignore?
17
+
18
+ result = nil
19
+ lineprofiled = lineprof(self.class.regexp) do
20
+ result = yield
21
+ end
22
+ store(lineprofiled) if SpeedGun.current_report
23
+ result
24
+ end
25
+
26
+ def store(lineprofiled)
27
+ lineprofiled.each_pair do |file, linesamples|
28
+ source = SpeedGun::Source.new(file, linesamples)
29
+ SpeedGun.current_report.source(source) unless source.lines.empty?
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun/profiler'
2
3
 
3
- class SpeedGun::Profiler::RackProfier < SpeedGun::Profiler
4
- def self.name
5
- 'rack.total'
6
- end
4
+ class SpeedGun::Profiler::RackProfiler < SpeedGun::Profiler
7
5
  end
@@ -1,21 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun'
3
+ require 'speed_gun/event'
2
4
 
3
- # @abstract
4
5
  class SpeedGun::Profiler
5
6
  def self.profile(*args, &block)
6
7
  new.profile(*args, &block)
7
8
  end
8
9
 
9
- def profile(name = self.class.name, payload = {}, &block)
10
- starts_at = Time.now
10
+ def self.ignore?
11
+ SpeedGun.config.ignored_profilers.any? do |ignore|
12
+ name.include?(ignore)
13
+ end
14
+ end
15
+
16
+ def profile(name = self.class.name, payload = {})
17
+ started_at = Time.now
11
18
 
12
- ret = yield
19
+ event = SpeedGun::Event.new(name, payload, started_at)
20
+ result = yield(event)
21
+ event.finish!
13
22
 
14
- event = SpeedGun::Event.new(
15
- name, payload, starts_at, Time.now
16
- )
17
- SpeedGun.current_profile.record!(event)
23
+ SpeedGun.record(event) unless self.class.ignore?
18
24
 
19
- return ret
25
+ result
20
26
  end
21
27
  end
@@ -1,13 +1,21 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun'
3
+ require 'speed_gun/store/file_store'
4
+ require 'rack/speed_gun'
5
+ require 'rails/railtie'
2
6
 
3
7
  class SpeedGun::Railtie < ::Rails::Railtie
4
8
  initializer 'speed_gun' do |app|
5
- app.middleware.insert(0, SpeedGun::Middleware)
9
+ app.middleware.insert(0, Rack::SpeedGun)
6
10
 
7
- SpeedGun.config.logger = Rails.logger
8
- SpeedGun.config.skip_paths.push(
9
- /^#{Regexp.escape(app.config.assets.prefix)}/
10
- )
11
+ SpeedGun.configure do |config|
12
+ config.logger = Rails.logger
13
+ config.store = SpeedGun::Store::FileStore.new(Rails.root.join('tmp/speed_gun').to_s)
14
+ config.lineprof_paths.push(Rails.root.to_s)
15
+ config.skip_paths.push(app.config.assets.prefix)
16
+ end
17
+
18
+ require 'speed_gun/profiler/active_support_profiler'
11
19
 
12
20
  ActiveSupport.on_load(:action_controller) do
13
21
  require 'speed_gun/profiler/action_controller_profiler'
@@ -20,5 +28,13 @@ class SpeedGun::Railtie < ::Rails::Railtie
20
28
  ActiveSupport.on_load(:active_record) do
21
29
  require 'speed_gun/profiler/active_record_profiler'
22
30
  end
31
+
32
+ ActiveSupport.on_load(:action_mailer) do
33
+ require 'speed_gun/profiler/action_mailer_profiler'
34
+ end
35
+
36
+ ActiveSupport.on_load(:active_job) do
37
+ require 'speed_gun/profiler/active_job_profiler'
38
+ end
23
39
  end
24
40
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ require 'securerandom'
3
+ require 'speed_gun'
4
+
5
+ class SpeedGun::Report
6
+ # @return [String] Report ID
7
+ attr_reader :id
8
+
9
+ # @return [Array<SpeedGun::Source>] Profiled source codes
10
+ attr_reader :sources
11
+
12
+ # @return [Array<SpeedGun::Event>] Recorded events
13
+ attr_reader :events
14
+
15
+ def self.from_hash(hash)
16
+ report = new
17
+
18
+ hash['sources'].map! do |source_id, hash|
19
+ SpeedGun::Source.from_hash(hash, source_id)
20
+ end
21
+
22
+ hash['events'].map! do |event_id, hash|
23
+ SpeedGun::Event.from_hash(hash, event_id)
24
+ end
25
+
26
+ hash.each_pair do |key, val|
27
+ report.instance_variable_set(:"@#{key}", val)
28
+ end
29
+
30
+ report
31
+ end
32
+
33
+ def initialize
34
+ @id = SecureRandom.uuid
35
+ @sources = []
36
+ @events = []
37
+ end
38
+
39
+ def record(event)
40
+ @events.push(event)
41
+ end
42
+
43
+ def source(source)
44
+ @sources.push(source)
45
+ end
46
+
47
+ def nearlest_event_started_at
48
+ @events.sort_by(&:started_at).first.started_at
49
+ end
50
+
51
+ def latest_event_finished_at
52
+ @events.sort_by { |event| event.roughly_finished_at.to_f * -1 }.first.roughly_finished_at
53
+ end
54
+
55
+ def duration
56
+ latest_event_finished_at.to_f - nearlest_event_started_at.to_f
57
+ end
58
+
59
+ def to_hash
60
+ {
61
+ sources: sources.map { |source| [ source.id, source.to_hash ] },
62
+ events: events.map { |event| [event.id, event.to_hash] }
63
+ }
64
+ end
65
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+ require 'securerandom'
3
+ require 'speed_gun'
4
+
5
+ class SpeedGun::Source
6
+ KEEP_RANGE = 3
7
+
8
+ class Line
9
+ attr_reader :id, :line, :code, :wall, :cpu, :calls, :allocations
10
+
11
+ def self.from_hash(hash, id = nil)
12
+ keys = %w(line code wall cpu calls allocations)
13
+ vals = keys.map { |k| hash[k] }
14
+ new(*vals).tap do |line|
15
+ line.instance_variable_set(:@id, id) if id
16
+ end
17
+ end
18
+
19
+ def initialize(line, code, wall, cpu, calls, allocations)
20
+ @id = SecureRandom.uuid
21
+ @line, @code, @wall, @cpu, @calls, @allocations = line, code, wall, cpu, calls, allocations
22
+ end
23
+
24
+ def to_s
25
+ format('% 8.1fms + % 8.1fms (% 5d) % 5d allocs | %04d %s', cpu / 1000.0, (wall - cpu) / 1000.0, calls, allocations, line, code)
26
+ end
27
+
28
+ def to_hash
29
+ {
30
+ line: line,
31
+ code: code,
32
+ wall: wall,
33
+ cpu: cpu,
34
+ calls: calls,
35
+ allocations: allocations
36
+ }
37
+ end
38
+ end
39
+
40
+ attr_reader :id, :file, :lines
41
+
42
+ def self.from_hash(hash, id = nil)
43
+ source = new(hash['file'], nil)
44
+
45
+ lines = (hash['lines'] || []).map do |line_id, hash|
46
+ Line.from_hash(hash, line_id)
47
+ end
48
+
49
+ source.instance_variable_set(:@lines, lines)
50
+ source.instance_variable_set(:@id, id) if id
51
+
52
+ source
53
+ end
54
+
55
+ def initialize(file, linesamples)
56
+ @id = SecureRandom.uuid
57
+ @file = file
58
+ @lines = []
59
+ analyze(file, linesamples) if linesamples
60
+ end
61
+
62
+ def analyze(file, linesamples)
63
+ code_lines = File.exist?(file) ? File.readlines(file) : []
64
+
65
+ keep_lines = []
66
+ code_lines.each_with_index do |line, idx|
67
+ sample = linesamples[idx + 1] || [0, 0, 0, 0]
68
+ wall, cpu, calls, allocations = *sample
69
+
70
+ keep_lines.push(idx) if calls > 0
71
+ @lines.push(Line.new(idx + 1, line, wall, cpu, calls, allocations))
72
+ end
73
+
74
+ @lines.select! do |line|
75
+ idx = line.line - 1
76
+ ((KEEP_RANGE * -1)..KEEP_RANGE).any? { |n| keep_lines.include?(idx + n) }
77
+ end
78
+ end
79
+
80
+ def to_s
81
+ "#{file}====\n#{lines.map(&:to_s).join('')}"
82
+ end
83
+
84
+ def to_hash
85
+ {
86
+ file: file,
87
+ lines: lines.map { |line| [ line.id, line.to_hash ] }
88
+ }
89
+ end
90
+ end
@@ -0,0 +1,35 @@
1
+ require 'fileutils'
2
+ require 'speed_gun/store'
3
+
4
+ class SpeedGun::Store::FileStore < SpeedGun::Store
5
+ def initialize(basedir)
6
+ @basedir = basedir
7
+ end
8
+
9
+ def store(obj)
10
+ key, val = serialize(obj)
11
+
12
+ filepath = pathnize(key)
13
+ dirname = File.dirname(filepath)
14
+ FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
15
+ File.open(filepath, 'wb') do |fp|
16
+ fp.write(val)
17
+ end
18
+ end
19
+
20
+ def load(key)
21
+ filepath = pathnize(key)
22
+ return nil unless File.exist?(filepath)
23
+
24
+ msg = File.open(filepath, 'rb', &:read)
25
+ deserialize(key, msg)
26
+ end
27
+
28
+ private
29
+
30
+ def pathnize(key)
31
+ klass, id = *key.split('/', 2)
32
+
33
+ File.join(@basedir, *klass.split('::'), id)
34
+ end
35
+ end
@@ -1,23 +1,16 @@
1
1
  require 'speed_gun/store'
2
2
 
3
3
  class SpeedGun::Store::MemoryStore < SpeedGun::Store
4
- DEFAULT_MAX_ENTRIES = 1000
5
-
6
- def initialize(options = {})
7
- @max_entries = options[:max_entries] || DEFAULT_MAX_ENTRIES
8
- @store = {}
9
- @stored_list = []
4
+ def initialize
5
+ @data = {}
10
6
  end
11
7
 
12
- def save(object)
13
- id = "#{object.class.name}-#{object.id}"
14
- @store[id] = object.to_hash
15
- @stored_list.push(id)
16
-
17
- @store.delete(@stored_list.shift) while @stored_list.length > @max_entries
8
+ def store(obj)
9
+ key, val = serialize(obj)
10
+ @data[key] = val
18
11
  end
19
12
 
20
- def load(klass, id)
21
- klass.from_hash(id, @store["#{klass.name}-#{id}"])
13
+ def load(key)
14
+ deserialize(key, @data[key])
22
15
  end
23
16
  end
@@ -1,10 +1,17 @@
1
+ require 'msgpack'
1
2
  require 'speed_gun'
2
3
 
3
- # @abstract
4
4
  class SpeedGun::Store
5
- def save(object)
5
+ def serialize(obj)
6
+ ["#{obj.class.name}/#{obj.id}", MessagePack.pack(obj.to_hash)]
6
7
  end
7
8
 
8
- def load(klass, id)
9
+ def deserialize(key, msg)
10
+ return nil if msg.nil? || msg.empty?
11
+ hash = MessagePack.unpack(msg)
12
+ klass, id = *key.split('/', 2)
13
+ obj = Object.const_get(klass).from_hash(hash)
14
+ obj.instance_variable_set(:@id, id)
15
+ obj
9
16
  end
10
17
  end
@@ -1,3 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require 'semantic'
3
+
1
4
  module SpeedGun
2
- VERSION = '1.0.0.rc1'.freeze
5
+ VERSION = '2.0.0-alpha.1'
6
+
7
+ # @return [Semantic::Version] Version
8
+ def self.version
9
+ @version ||= Semantic::Version.new(VERSION)
10
+ end
3
11
  end
data/lib/speed_gun.rb CHANGED
@@ -1,43 +1,38 @@
1
- require 'forwardable'
2
- require 'thread'
1
+ # frozen_string_literal: true
3
2
  require 'speed_gun/version'
4
3
  require 'speed_gun/config'
5
- require 'speed_gun/profile'
6
- require 'speed_gun/middleware'
4
+ require 'speed_gun/report'
5
+ require 'rack/speed_gun'
6
+ require 'speed_gun/railtie' if defined?(::Rails)
7
7
 
8
8
  module SpeedGun
9
9
  class << self
10
- # @return [SpeedGun::Config] the config of speed gun
10
+ # @return [SpeedGun::Config]
11
11
  def config
12
- @config ||= Config.new
12
+ @config ||= SpeedGun::Config.new
13
13
  end
14
14
 
15
- # @return [SpeedGun::Profile, nil] the profile of a current thread
16
- def current_profile
17
- Thread.current[:speed_gun_current_profile]
15
+ # @yield [config] Configure speed gun
16
+ # @yieldparam config [SpeedGun::Config]
17
+ def configure
18
+ yield config
18
19
  end
19
20
 
20
- # Set the profile of a current thread
21
- #
22
- # @param profile [SpeedGun::Profile] the profile
23
- # @return [SpeedGun::Profile] the profile of a current thread
24
- def current_profile=(profile)
25
- Thread.current[:speed_gun_current_profile] = profile
21
+ # @return [SpeedGun::Report, nil]
22
+ def current_report
23
+ Thread.current[:speed_gun_report]
26
24
  end
27
25
 
28
- # Discard the profile of a current thread
29
- #
30
- # @return [nil]
31
- def discard_profile!
32
- self.current_profile = nil
26
+ def current_report=(report)
27
+ Thread.current[:speed_gun_report] = report
33
28
  end
34
29
 
35
- # @see SpeedGun::Config#enabled?
36
- # @return [Boolean] true if enabled speed gun
37
- def enabled?
38
- config.enabled?
30
+ def record(event)
31
+ current_report && current_report.record(event)
32
+ end
33
+
34
+ def get_report(id)
35
+ config.store.load("SpeedGun::Report/#{id}")
39
36
  end
40
37
  end
41
38
  end
42
-
43
- require 'speed_gun/railtie' if defined?(Rails)
data/speed_gun.gemspec CHANGED
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'speed_gun/version'
@@ -7,26 +8,30 @@ Gem::Specification.new do |spec|
7
8
  spec.name = 'speed_gun'
8
9
  spec.version = SpeedGun::VERSION
9
10
  spec.authors = ['Sho Kusano']
10
- spec.email = ['rosylilly@aduca.org']
11
- spec.summary = %q{Better web app profiler for Rails apps}
12
- spec.description = %q{Better web app profiler for Rails apps}
13
- spec.homepage = 'https://github.com/rosylilly/speed_gun'
11
+ spec.email = ['sho-kusano@zeny.io']
12
+
13
+ spec.summary = 'Better web app profiler for Rails apps'
14
+ spec.description = spec.summary
15
+ spec.homepage = 'https://github.com/zeny-io/speed_gun'
14
16
  spec.license = 'MIT'
15
17
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
21
  spec.require_paths = ['lib']
20
22
 
21
- spec.add_development_dependency 'bundler'
22
- spec.add_development_dependency 'rake'
23
- spec.add_development_dependency 'rspec', '~> 2.14.1'
24
- spec.add_development_dependency 'simplecov', '~> 0.8.2'
25
- spec.add_development_dependency 'simplecov-console'
26
- spec.add_development_dependency 'rack-test'
27
- spec.add_development_dependency 'coveralls'
28
-
29
- spec.add_dependency 'hashie'
30
23
  spec.add_dependency 'msgpack'
24
+ spec.add_dependency 'rack'
25
+ spec.add_dependency 'rblineprof'
26
+ spec.add_dependency 'sass'
27
+ spec.add_dependency 'semantic'
28
+ spec.add_dependency 'sinatra'
29
+ spec.add_dependency 'sinatra-partial'
31
30
  spec.add_dependency 'slim'
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.12'
33
+ spec.add_development_dependency 'rake', '~> 11.0'
34
+ spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'rubocop'
36
+ spec.add_development_dependency 'yard'
32
37
  end