tingyun_rpm 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +14 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +3 -0
  7. data/Guardfile +25 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +41 -0
  10. data/cert/cacert.pem +0 -0
  11. data/lib/ting_yun/agent/agent.rb +128 -0
  12. data/lib/ting_yun/agent/class_methods.rb +21 -0
  13. data/lib/ting_yun/agent/collector/base_sampler.rb +2 -0
  14. data/lib/ting_yun/agent/collector/error_collector/error_trace_array.rb +88 -0
  15. data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +129 -0
  16. data/lib/ting_yun/agent/collector/error_collector.rb +165 -0
  17. data/lib/ting_yun/agent/collector/middle_ware_collector/cpu_sampler.rb +68 -0
  18. data/lib/ting_yun/agent/collector/middle_ware_collector/memory_sampler.rb +139 -0
  19. data/lib/ting_yun/agent/collector/middle_ware_collector/middle_ware.rb +13 -0
  20. data/lib/ting_yun/agent/collector/middle_ware_collector/sampler.rb +59 -0
  21. data/lib/ting_yun/agent/collector/middle_ware_collector.rb +80 -0
  22. data/lib/ting_yun/agent/collector/sql_sampler.rb +299 -0
  23. data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +170 -0
  24. data/lib/ting_yun/agent/collector/stats_engine/stats_hash.rb +172 -0
  25. data/lib/ting_yun/agent/collector/stats_engine.rb +28 -0
  26. data/lib/ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer.rb +25 -0
  27. data/lib/ting_yun/agent/collector/transaction_sampler/transaction_sample_buffer_base.rb +96 -0
  28. data/lib/ting_yun/agent/collector/transaction_sampler.rb +226 -0
  29. data/lib/ting_yun/agent/container_data_manager.rb +94 -0
  30. data/lib/ting_yun/agent/cross_app/cross_app_monitor.rb +131 -0
  31. data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +202 -0
  32. data/lib/ting_yun/agent/cross_app/inbound_request_monitor.rb +22 -0
  33. data/lib/ting_yun/agent/database.rb +410 -0
  34. data/lib/ting_yun/agent/datastore/metric_helper.rb +82 -0
  35. data/lib/ting_yun/agent/datastore/mongo.rb +44 -0
  36. data/lib/ting_yun/agent/datastore.rb +33 -0
  37. data/lib/ting_yun/agent/dispatcher.rb +39 -0
  38. data/lib/ting_yun/agent/event/event_listener.rb +47 -0
  39. data/lib/ting_yun/agent/event/event_loop.rb +194 -0
  40. data/lib/ting_yun/agent/instance_methods/connect.rb +164 -0
  41. data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +137 -0
  42. data/lib/ting_yun/agent/instance_methods/handle_errors.rb +71 -0
  43. data/lib/ting_yun/agent/instance_methods/start.rb +219 -0
  44. data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +51 -0
  45. data/lib/ting_yun/agent/instance_methods.rb +39 -0
  46. data/lib/ting_yun/agent/method_tracer.rb +256 -0
  47. data/lib/ting_yun/agent/method_tracer_helpers.rb +85 -0
  48. data/lib/ting_yun/agent/threading/agent_thread.rb +49 -0
  49. data/lib/ting_yun/agent/transaction/attributes.rb +22 -0
  50. data/lib/ting_yun/agent/transaction/request_attributes.rb +126 -0
  51. data/lib/ting_yun/agent/transaction/trace.rb +125 -0
  52. data/lib/ting_yun/agent/transaction/trace_node.rb +110 -0
  53. data/lib/ting_yun/agent/transaction/traced_method_stack.rb +80 -0
  54. data/lib/ting_yun/agent/transaction/transaction_metrics.rb +51 -0
  55. data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +63 -0
  56. data/lib/ting_yun/agent/transaction/transaction_state.rb +112 -0
  57. data/lib/ting_yun/agent/transaction.rb +522 -0
  58. data/lib/ting_yun/agent.rb +207 -0
  59. data/lib/ting_yun/configuration/default_source.rb +638 -0
  60. data/lib/ting_yun/configuration/dotted_hash.rb +46 -0
  61. data/lib/ting_yun/configuration/environment_source.rb +116 -0
  62. data/lib/ting_yun/configuration/manager.rb +232 -0
  63. data/lib/ting_yun/configuration/manual_source.rb +14 -0
  64. data/lib/ting_yun/configuration/server_source.rb +88 -0
  65. data/lib/ting_yun/configuration/yaml_source.rb +136 -0
  66. data/lib/ting_yun/configuration.rb +9 -0
  67. data/lib/ting_yun/environment_report.rb +123 -0
  68. data/lib/ting_yun/frameworks/class_methods.rb +47 -0
  69. data/lib/ting_yun/frameworks/external.rb +15 -0
  70. data/lib/ting_yun/frameworks/instance_methods.rb +120 -0
  71. data/lib/ting_yun/frameworks/instrumentation.rb +67 -0
  72. data/lib/ting_yun/frameworks/rails.rb +63 -0
  73. data/lib/ting_yun/frameworks/rails3.rb +26 -0
  74. data/lib/ting_yun/frameworks/rails4.rb +14 -0
  75. data/lib/ting_yun/frameworks/ruby.rb +17 -0
  76. data/lib/ting_yun/frameworks/sinatra.rb +10 -0
  77. data/lib/ting_yun/frameworks.rb +34 -0
  78. data/lib/ting_yun/http/generic_request.rb +8 -0
  79. data/lib/ting_yun/http/net_http_request.rb +46 -0
  80. data/lib/ting_yun/instrumentation/active_record.rb +103 -0
  81. data/lib/ting_yun/instrumentation/middleware_proxy.rb +77 -0
  82. data/lib/ting_yun/instrumentation/middleware_tracing.rb +84 -0
  83. data/lib/ting_yun/instrumentation/mongo.rb +103 -0
  84. data/lib/ting_yun/instrumentation/mongo2.rb +37 -0
  85. data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +97 -0
  86. data/lib/ting_yun/instrumentation/moped.rb +95 -0
  87. data/lib/ting_yun/instrumentation/net.rb +59 -0
  88. data/lib/ting_yun/instrumentation/rack.rb +109 -0
  89. data/lib/ting_yun/instrumentation/rails3/action_controller.rb +63 -0
  90. data/lib/ting_yun/instrumentation/rails3/action_view.rb +115 -0
  91. data/lib/ting_yun/instrumentation/rails4/action_controller_subscriber.rb +124 -0
  92. data/lib/ting_yun/instrumentation/rails4/action_view_subscriber.rb +118 -0
  93. data/lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb +124 -0
  94. data/lib/ting_yun/instrumentation/rails_middleware.rb +38 -0
  95. data/lib/ting_yun/instrumentation/redis.rb +70 -0
  96. data/lib/ting_yun/instrumentation/support/active_record_helper.rb +178 -0
  97. data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +54 -0
  98. data/lib/ting_yun/instrumentation/support/database.rb +38 -0
  99. data/lib/ting_yun/instrumentation/support/event_formatter.rb +19 -0
  100. data/lib/ting_yun/instrumentation/support/evented_subscriber.rb +97 -0
  101. data/lib/ting_yun/instrumentation/support/external_error.rb +52 -0
  102. data/lib/ting_yun/instrumentation/support/metric_translator.rb +84 -0
  103. data/lib/ting_yun/instrumentation/support/mongo_formatter.rb +49 -0
  104. data/lib/ting_yun/instrumentation/support/parameter_filtering.rb +21 -0
  105. data/lib/ting_yun/instrumentation/support/queue_time.rb +76 -0
  106. data/lib/ting_yun/instrumentation/support/transaction_namer.rb +68 -0
  107. data/lib/ting_yun/instrumentation/thrift.rb +329 -0
  108. data/lib/ting_yun/logger/agent_logger.rb +196 -0
  109. data/lib/ting_yun/logger/log_once.rb +38 -0
  110. data/lib/ting_yun/logger/memory_logger.rb +56 -0
  111. data/lib/ting_yun/logger/null_logger.rb +31 -0
  112. data/lib/ting_yun/logger/startup_logger.rb +13 -0
  113. data/lib/ting_yun/logger.rb +8 -0
  114. data/lib/ting_yun/metrics/metric_data.rb +86 -0
  115. data/lib/ting_yun/metrics/metric_spec.rb +89 -0
  116. data/lib/ting_yun/metrics/stats.rb +158 -0
  117. data/lib/ting_yun/metrics.rb +12 -0
  118. data/lib/ting_yun/support/coerce.rb +86 -0
  119. data/lib/ting_yun/support/collector.rb +29 -0
  120. data/lib/ting_yun/support/exception.rb +79 -0
  121. data/lib/ting_yun/support/hash_extensions.rb +25 -0
  122. data/lib/ting_yun/support/helper.rb +54 -0
  123. data/lib/ting_yun/support/hostname.rb +13 -0
  124. data/lib/ting_yun/support/http_clients/uri_util.rb +49 -0
  125. data/lib/ting_yun/support/language_support.rb +155 -0
  126. data/lib/ting_yun/support/library_detection.rb +129 -0
  127. data/lib/ting_yun/support/local_environment.rb +185 -0
  128. data/lib/ting_yun/support/path.rb +13 -0
  129. data/lib/ting_yun/support/serialize/encodes.rb +61 -0
  130. data/lib/ting_yun/support/serialize/encoding_normalizer.rb +84 -0
  131. data/lib/ting_yun/support/serialize/json_marshaller.rb +73 -0
  132. data/lib/ting_yun/support/serialize/json_wrapper.rb +78 -0
  133. data/lib/ting_yun/support/serialize/marshaller.rb +69 -0
  134. data/lib/ting_yun/support/serialize/ok_json.rb +651 -0
  135. data/lib/ting_yun/support/system_info.rb +206 -0
  136. data/lib/ting_yun/support/timer_lib.rb +29 -0
  137. data/lib/ting_yun/support/version_number.rb +70 -0
  138. data/lib/ting_yun/ting_yun_service/connection.rb +118 -0
  139. data/lib/ting_yun/ting_yun_service/http.rb +41 -0
  140. data/lib/ting_yun/ting_yun_service/request.rb +90 -0
  141. data/lib/ting_yun/ting_yun_service/ssl.rb +45 -0
  142. data/lib/ting_yun/ting_yun_service/upload_service.rb +149 -0
  143. data/lib/ting_yun/ting_yun_service.rb +124 -0
  144. data/lib/ting_yun/version.rb +17 -0
  145. data/lib/tingyun_rpm.rb +47 -0
  146. data/tingyun_rpm.gemspec +60 -0
  147. metadata +415 -0
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+ require 'ting_yun/metrics/metric_spec'
3
+ require 'ting_yun/metrics/metric_data'
4
+ require 'ting_yun/support/serialize/encodes'
5
+
6
+ module TingYun
7
+ class TingYunService
8
+ module UploadService
9
+
10
+ def compressed_json
11
+ TingYun::Support::Serialize::Encoders::CompressedJSON
12
+ end
13
+
14
+ def base64_compressed_json
15
+ TingYun::Support::Serialize::Encoders::Base64CompressedJSON
16
+ end
17
+
18
+ def json
19
+ TingYun::Support::Serialize::Encoders::Json
20
+ end
21
+
22
+ def metric_data(stats_hash)
23
+
24
+ timeslice_start = stats_hash.started_at
25
+ timeslice_end = stats_hash.harvested_at || Time.now
26
+
27
+ action_array, adpex_array, general_array, components_array, errors_array = build_metric_data_array(stats_hash)
28
+
29
+ upload_data = {
30
+ :type => 'perfMetrics',
31
+ :timeFrom => timeslice_start.to_i,
32
+ :timeTo => timeslice_end.to_i,
33
+ :interval => 60,
34
+ :actions => action_array,
35
+ :apdex => adpex_array,
36
+ :components => components_array,
37
+ :general => general_array,
38
+ :errors => errors_array
39
+ }
40
+ result = invoke_remote(:upload, [upload_data])
41
+ fill_metric_id_cache(result)
42
+ result
43
+ end
44
+
45
+ # The collector wants to recieve metric data in a format that's different
46
+ # from how we store it inte -nally, so this method handles the translation.
47
+ # It also handles translating metric names to IDs using our metric ID cache.
48
+ def build_metric_data_array(stats_hash)
49
+ action_array = []
50
+ adpex_array = []
51
+ general_array = []
52
+ components_array = []
53
+ errors_array = []
54
+ stats_hash.each do |metric_spec, stats|
55
+
56
+ # Omit empty stats as an optimization
57
+ unless stats.is_reset?
58
+ metric_id = metric_id_cache[metric_spec.name]
59
+
60
+ if metric_spec.name.start_with?('WebAction')
61
+ action_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
62
+ elsif metric_spec.name.start_with?('Apdex')
63
+ adpex_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
64
+ elsif metric_spec.name.start_with?('Errors') && metric_spec.scope.empty?
65
+ errors_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
66
+ elsif metric_spec.name.start_with?('Database','View','MongoDB','Redis','Memcached','External','Nested', 'CPU', 'Memory', 'WebFrontend')
67
+ if metric_spec.scope.empty?
68
+ general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
69
+ else
70
+ components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
71
+ end
72
+ elsif metric_spec.name.start_with?('cross_app')
73
+ external = metric_spec.name.split(';')
74
+ if metric_spec.scope.empty?
75
+ metric_spec.name = "ExternalTransaction/NULL/#{external[1]}"
76
+ general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
77
+ else
78
+ metric_spec.name = "External/#{external[3]}"
79
+ metric_spec.calleeId = external[1]
80
+ metric_spec.calleeName = external[2]
81
+ components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+ [action_array, adpex_array, general_array, components_array, errors_array]
89
+ end
90
+
91
+
92
+ # takes an array of arrays of spec and id, adds it into the
93
+ # metric cache so we can save the collector some work by
94
+ # sending integers instead of strings the next time around
95
+ def fill_metric_id_cache(pairs_of_specs_and_ids)
96
+ pairs_of_specs_and_ids.each do |_, value|
97
+ if value.is_a? Array
98
+ value.each do |array|
99
+ if array.is_a? Array
100
+ metric_id_cache[array[0]["name"]] = array[1]
101
+ end
102
+ end
103
+ end
104
+ end
105
+ rescue => e
106
+ # If we've gotten this far, we don't want this error to propagate and
107
+ # make this post appear to have been non-successful, which would trigger
108
+ # re-aggregation of the same metric data into the next post, so just log
109
+ TingYun::Agent.logger.error("Failed to fill metric ID cache from response, error details follow ", e)
110
+ end
111
+ end
112
+
113
+ def error_data(unsent_errors)
114
+ upload_data = {
115
+ :type => 'errorTraceData',
116
+ :errors => unsent_errors
117
+ }
118
+ invoke_remote(:upload, [upload_data], :encoder=> json)
119
+ end
120
+
121
+
122
+ def action_trace_data(traces)
123
+ upload_data = {
124
+ :type => 'actionTraceData',
125
+ :actionTraces => traces
126
+ }
127
+ invoke_remote(:upload, [upload_data], :encoder=> json)
128
+ end
129
+
130
+
131
+ def sql_trace(sql_trace)
132
+ upload_data = {
133
+ :type => 'sqlTraceData',
134
+ :sqlTraces => sql_trace
135
+ }
136
+
137
+ invoke_remote(:upload, [upload_data], :encoder=> json)
138
+
139
+ end
140
+
141
+ def external_error_data(traces)
142
+ upload_data = {
143
+ :type => 'externalErrorTraceData',
144
+ :errors => traces
145
+ }
146
+ invoke_remote(:upload, [upload_data], :encoder=> json)
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,124 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under Ting Yun's license terms.
3
+
4
+
5
+ require 'ting_yun/agent'
6
+ require 'zlib'
7
+ require 'ting_yun/ting_yun_service/http'
8
+ require 'ting_yun/support/collector'
9
+ require 'ting_yun/support/serialize/encodes'
10
+ require 'ting_yun/support/timer_lib'
11
+ require 'ting_yun/support/exception'
12
+ require 'ting_yun/support/serialize/json_marshaller'
13
+ require 'ting_yun/ting_yun_service/upload_service'
14
+ require 'ting_yun/version'
15
+
16
+ module TingYun
17
+ class TingYunService
18
+ include Http
19
+ include UploadService
20
+
21
+ CONNECTION_ERRORS = [Timeout::Error, EOFError, SystemCallError, SocketError].freeze
22
+
23
+ PROTOCOL_VERSION = 1
24
+
25
+
26
+ attr_accessor :request_timeout,
27
+ :appSessionKey,
28
+ :data_version,
29
+ :metric_id_cache,
30
+ :applicationId,
31
+ :ssl_cert_store,
32
+ :shared_tcp_connection
33
+
34
+ def initialize(license_key=nil,collector=TingYun::Support.collector)
35
+
36
+ @license_key = license_key || TingYun::Agent.config[:'license_key']
37
+ @request_timeout = TingYun::Agent.config[:timeout]
38
+ @collector = collector
39
+ @data_version = TingYun::VERSION::STRING
40
+ @marshaller =TingYun::Support::Serialize::JsonMarshaller.new
41
+ @metric_id_cache = {}
42
+ end
43
+
44
+ def connect(settings={})
45
+ if host = get_redirect_host
46
+ @collector = TingYun::Support.collector_from_host(host)
47
+ end
48
+ response = invoke_remote(:initAgentApp, [settings])
49
+ TingYun::Agent.logger.info("initAgentApp response: #{response}") if TingYun::Agent.config[:'nbs.audit_mode']
50
+ @applicationId = response['applicationId']
51
+ @appSessionKey = response['appSessionKey']
52
+ response
53
+ end
54
+
55
+ def get_redirect_host
56
+ invoke_remote(:getRedirectHost)
57
+ end
58
+
59
+ def force_restart
60
+ @applicationId = nil
61
+ @appSessionKey = nil
62
+ @metric_id_cache = {}
63
+ close_shared_connection
64
+ end
65
+
66
+
67
+ # send a message via post to the actual server. This attempts
68
+ # to automatically compress the data via zlib if it is large
69
+ # enough to be worth compressing, and handles any errors the
70
+ # server may return
71
+
72
+ # private
73
+
74
+ def invoke_remote(method, payload=[], options = {})
75
+
76
+ data = nil
77
+ payload = payload[0] if method == :initAgentApp
78
+ begin
79
+ data = @marshaller.dump(payload, options)
80
+ rescue StandardError, SystemStackError => e
81
+ handle_serialization_error(method, e)
82
+ end
83
+ # serialize_finish_time = Time.now
84
+
85
+ if TingYun::Agent.config[:'nbs.audit_mode']
86
+ TingYun::Agent.logger.info("the prepare data: #{data}")
87
+ else
88
+ TingYun::Agent.logger.info("prepare to send data")
89
+ end
90
+
91
+ data, encoding = compress_request_if_needed(data)
92
+ # size = data.size
93
+
94
+ uri = remote_method_uri(method)
95
+ full_uri = "#{@collector}#{uri}"
96
+ TingYun::Agent.logger.info("url: #{full_uri}") if TingYun::Agent.config[:'nbs.audit_mode']
97
+ response = send_request(:data => data,
98
+ :uri => uri,
99
+ :encoding => encoding,
100
+ :collector => @collector)
101
+
102
+ if TingYun::Agent.config[:'nbs.audit_mode']
103
+ TingYun::Agent.logger.info("the return data: #{response.body}")
104
+ else
105
+ TingYun::Agent.logger.info("the send-process end")
106
+ end
107
+ @marshaller.load(decompress_response(response))
108
+ end
109
+
110
+ def handle_serialization_error(method, e)
111
+ msg = "Failed to serialize #{method} data using #{@marshaller.class.to_s}: #{e.inspect}"
112
+ error = TingYun::Support::Exception::SerializationError.new(msg)
113
+ error.set_backtrace(e.backtrace)
114
+ raise error
115
+ end
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ end
124
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under Ting Yun's license terms.
3
+
4
+ module TingYun
5
+ module VERSION
6
+
7
+ MAJOR = 1
8
+
9
+ MINOR = 0
10
+ TINY = 6
11
+
12
+
13
+
14
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
15
+
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under Ting Yun's license terms.
3
+
4
+ # == TingYun Initialization
5
+ #
6
+ # When installed as a gem, you can activate the Ting Yun agent one of the following ways:
7
+ #
8
+ # For Rails, add:
9
+ # config.gem 'tingyun_rpm'
10
+ # to your initialization sequence.
11
+ #
12
+ # For merb, do
13
+ # dependency 'tingyun_rpm'
14
+ # in the Merb config/init.rb
15
+ #
16
+ # For Sinatra, do
17
+ # require 'tingyun_rpm'
18
+ # after requiring 'sinatra'.
19
+ #
20
+ # For other frameworks, or to manage the agent manually, invoke TingYun::Agent#manual_start
21
+ # directly.
22
+ #
23
+
24
+ require 'ting_yun/frameworks'
25
+
26
+
27
+ if defined?(Rails::VERSION)
28
+ if Rails::VERSION::MAJOR.to_i >= 3
29
+ module TingYun
30
+ class Railtie < Rails::Railtie
31
+
32
+ initializer "tingyun_rpm.start_plugin" do |app|
33
+ TingYun::Agent.logger.info('initialize tingyun_rpm start_plugin')
34
+ TingYun::Frameworks.init_start(:config => app.config)
35
+ end
36
+ end
37
+ end
38
+ else
39
+ # After version 2.0 of Rails we can access the configuration directly.
40
+ # We need it to add dev mode routes after initialization finished.
41
+ config = nil
42
+ config = Rails.configuration if Rails.respond_to?(:configuration)
43
+ TingYun::Frameworks.init_start(:config => config)
44
+ end
45
+ else
46
+ TingYun::Frameworks.init_start
47
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'ting_yun/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'tingyun_rpm'
9
+ s.version = TingYun::VERSION::STRING
10
+ s.author = 'tingyun'
11
+ # s.email = 'support@tingyun.com'
12
+ # s.homepage = 'http://tingyun.com/features/ruby.html'
13
+
14
+ s.licenses = ['Tingyun', 'MIT', 'Ruby']
15
+ s.summary = 'TingYun Ruby Agent'
16
+ # s.description = 'TingYun Ruby Agent. (http://tingyun.com/features/ruby.html)'
17
+
18
+ s.required_ruby_version = '>= 1.8.7'
19
+ s.required_rubygems_version = '>= 1.3.5'
20
+
21
+ file_list = `git ls-files`.split
22
+ file_list.delete_if { |item| item =~ /(test\/|bin\/|Rakefile)/ }
23
+ s.files = file_list
24
+
25
+ s.require_paths = ['lib']
26
+ s.rubygems_version = Gem::VERSION
27
+
28
+ s.add_development_dependency 'rake', '10.1.0'
29
+ s.add_development_dependency 'minitest', '~> 4.7'
30
+ s.add_development_dependency 'minitest-ci', '= 2.4.0'
31
+ s.add_development_dependency 'minitest-focus', '~> 1.1'
32
+ s.add_development_dependency 'minitest-reporters', '0.14.24'
33
+ s.add_development_dependency 'simplecov', '= 0.10.0'
34
+ s.add_development_dependency 'mocha', '~> 0.13.0'
35
+ s.add_development_dependency 'rails', '~> 3.2'
36
+ s.add_development_dependency 'pry', '~> 0.9.12'
37
+ s.add_development_dependency 'hometown', '~> 0.2.5'
38
+ s.add_development_dependency 'yard'
39
+
40
+ if RUBY_VERSION >= '1.9.3'
41
+ s.add_development_dependency 'guard', '= 2.12.5'
42
+ s.add_development_dependency 'guard-minitest', '= 2.4.4'
43
+ s.add_development_dependency 'rb-fsevent', '= 0.9.4'
44
+ end
45
+
46
+ # compatible with Ruby 1.8.7
47
+ s.add_development_dependency 'i18n', '0.6.11'
48
+
49
+ if RUBY_PLATFORM == 'java'
50
+ s.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
51
+ s.add_development_dependency 'jruby-openssl'
52
+ else
53
+ s.add_development_dependency 'sqlite3', '= 1.3.10'
54
+ end
55
+
56
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
57
+ s.add_development_dependency 'rubysl'
58
+ s.add_development_dependency 'racc'
59
+ end
60
+ end