runtime_profiler 0.3.0 → 0.3.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7839cd9d608c73c35a269e4bf7f2f52ae482e714dd99a108e9078e6628f9a86b
4
- data.tar.gz: 9eecf865436dcd07b575d96c1bfb21d1ba1c9344c9100aa955ed00a84d2e8011
3
+ metadata.gz: 4c567a2661f9eec0b394b9751be7e66994e12eea070333f1123ca7c8178e3897
4
+ data.tar.gz: 6eaf3618331b9f5a2c9ea5c657cb61aeb67b391456c4a82f74937a800b78afe7
5
5
  SHA512:
6
- metadata.gz: eaeedf57a5c02b27e1f75778290f821a4b0ed3901220c7dce8529df44d4bf49fe8d0846a4bb3e7e73b485c96196f85d7d57a6cc3e8df93bfda8b05676526ddc1
7
- data.tar.gz: 196e71a0244d7d47c8af6585213c45373dcc8d694bac70daa86e9688877d4b02fc029bc50df87baf3ce288e64c8c7850ea717603975eb38a9da367e34998d9a5
6
+ metadata.gz: 1f5466a9848de8f4e8dbf80e57d48c1dd146f4867ad7b31f8bae7a88a441b562d75c8efbd54c33ced2efc125b1057bdafa571ff94d3c7c5015ce7ae2e73c5847
7
+ data.tar.gz: f53a00037808f40793cc28d523577f405581ed5588b29146c49daabe02151a7ad34b5c205aede70c7c93bc98e8858de08c740a9b675bac3ef22e9c67475dc438
data/README.md CHANGED
@@ -1,16 +1,35 @@
1
- # runtime_profiler - Runtime Profiler for Rails Applications [![Build Status](https://wnuqui.semaphoreci.com/badges/runtime_profiler/branches/master.svg?style=shields)](https://wnuqui.semaphoreci.com/projects/runtime_profiler)
1
+ # runtime_profiler
2
2
 
3
- `runtime_profiler` instruments API endpoints or methods in your Rails application using Rails' `ActiveSupport::Notifications`. Currently, it is intended to be used during development or test.
3
+ *A runtime profiler for Rails applications.*
4
4
 
5
- It then aggregates and generates report to give you insights about specific calls in your Rails application.
5
+ Check which part of your Rails application is causing slow response time. **runtime_profiler** gives you an easy way to find performance problems by profiling an endpoint or a method in your Rails application.
6
6
 
7
- ## Installation
7
+ [![Build Status](https://wnuqui.semaphoreci.com/badges/runtime_profiler/branches/master.svg?style=shields)](https://wnuqui.semaphoreci.com/projects/runtime_profiler)
8
+
9
+ ## Table of contents
10
+
11
+ - [Getting Started](#getting-started)
12
+ - [Installing](#installing)
13
+ - [Profiling](#profiling)
14
+ - [Structure](#structure)
15
+ - [Examples](#examples)
16
+ - [Viewing Profiling Result](#viewing-profiling-result)
17
+ - [view Options](#view-options)
18
+ - [Configurations](#configurations)
19
+ - [Development](#development)
20
+ - [Contributing](#contributing)
21
+ - [Acknowledgement](#acknowledgement)
22
+ - [License](#license)
23
+
24
+ ## Getting Started
25
+
26
+ ### Installing
8
27
 
9
28
  Add this line to your application's Gemfile:
10
29
 
11
30
  ```ruby
31
+ # In your Gemfile
12
32
  group :development, :test do
13
- ... ...
14
33
  gem 'runtime_profiler'
15
34
  end
16
35
  ```
@@ -19,13 +38,33 @@ And then execute:
19
38
 
20
39
  $ bundle
21
40
 
22
- ## Profiling/Instrumenting
41
+ Or install it yourself as:
42
+
43
+ $ gem install runtime_profiler
44
+
45
+ ### Profiling
46
+
47
+ #### Structure
48
+
49
+ To profile a specific class (model, controller, etc), all you need to do is to wrap a line where the target class (or instance) is calling a method (entry point of profiling).
50
+
51
+ ```ruby
52
+ # Profiles runtime of `ClassToProfile` class.
53
+ RuntimeProfiler.profile!('description', [ClassToProfile]) {
54
+ # one line where `ClassToProfile` (or its instance) is calling a method
55
+ }
56
+ ```
57
+
58
+ Since the second argument of `.profile!` accepts array of classes, then you can provide all target classes that you want to profile.
59
+
60
+ #### Examples
23
61
 
24
- To start profiling, you can make a test that targets a particular endpoint and use `RuntimeProfiler.profile!` method in the test. The output of instrumentation will be generated under the `tmp` folder of your application.
62
+ You can make a test that targets a particular endpoint (or even just a method) and use `RuntimeProfiler.profile!` method in the test.
25
63
 
26
- Example of a test code wrap by `RuntimeProfiler.profile!` method:
27
64
  ```ruby
28
65
  it 'updates user' do
66
+ # Profiles runtime of PUT /users/:id endpoint and
67
+ # specifically interested with the methods of `User` model.
29
68
  RuntimeProfiler.profile!('updates user', [User]) {
30
69
  patch :update, { id: user.id, name: 'Joe' }
31
70
  }
@@ -36,25 +75,26 @@ end
36
75
 
37
76
  Run the test as usual and follow printed instructions after running.
38
77
 
39
- If you prefer writing just code snippet, then just wrap the snippet with `RuntimeProfiler.profile!` method:
78
+ Or if you prefer writing just code snippet, then just wrap the snippet with `RuntimeProfiler.profile!` method:
40
79
  ```ruby
80
+ # Profiles runtime of `UserMailer` mailer.
41
81
  RuntimeProfiler.profile!('UserMailer', [UserMailer]) {
42
82
  user = User.last
43
83
  UserMailer.with(user: user).weekly_summary.deliver_now
44
84
  }
45
85
  ```
46
86
 
47
- **Note:** The code (tests or not) where `RuntimeProfiler.profile!` is used must be **free from any mocking** since your goal is to check bottlenecks.
87
+ **Note:** The code (test or not) where `RuntimeProfiler.profile!` is used must be **free from any mocking/stubbing** since the goal is to check performance bottlenecks.
48
88
 
49
- ## Viewing Profiling Result
89
+ ### Viewing Profiling Result
50
90
 
51
- To see profiling/instrumenting report, you can open the report in browser with JSON viewer report. Or you can run the following command:
91
+ To see profiling report, you can open the report in browser with JSON viewer report. Or you can run the following command:
52
92
 
53
93
  ```bash
54
- bundle exec runtime_profiler view ~/the-rails-app/tmp/runtime-profiling-51079-1521371428.json
94
+ bundle exec runtime_profiler view tmp/rp-124094-1608308786.json
55
95
  ```
56
96
 
57
- ### view options
97
+ #### view options
58
98
 
59
99
  Here are the command line options for `runtime_profiler view` command.
60
100
 
@@ -97,9 +137,9 @@ $ bundle exec runtime_profiler view --help
97
137
  ROUNDING is integer value. Used in rounding runtimes. Default is 4.
98
138
  ```
99
139
 
100
- ## Configurations
140
+ ### Configurations
101
141
 
102
- All the configurable variables and their defaults are listed below. These configurations can be put in the `config/initializers` folder of your Rails application.
142
+ All the configurable variables and their defaults are listed below. There is no one correct place where to put these configurations. It can be inside `config/initializers` folder of your Rails application. Or if you are using test to profile, it can be in the last part of `spec/spec_helper.rb`.
103
143
  ```ruby
104
144
  RuntimeProfiler.output_path = File.join(Rails.root.to_s, 'tmp')
105
145
  RuntimeProfiler.instrumented_constants = [User]
@@ -11,15 +11,15 @@ module RuntimeProfiler
11
11
  end
12
12
 
13
13
  config_accessor :instrumented_paths do
14
- %w(app lib)
14
+ %w[app lib]
15
15
  end
16
16
 
17
17
  config_accessor :instrumented_sql_commands do
18
- %w(SELECT INSERT UPDATE DELETE)
18
+ %w[SELECT INSERT UPDATE DELETE]
19
19
  end
20
20
 
21
21
  config_accessor :output_path do
22
- if defined?(Rails) && Rails.respond_to?(:root)
22
+ if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
23
23
  File.join(Rails.root.to_s, 'tmp')
24
24
  else
25
25
  'tmp'
@@ -28,7 +28,11 @@ module RuntimeProfiler
28
28
 
29
29
  class << self
30
30
  def configure
31
- Rails.application.eager_load! rescue nil
31
+ begin
32
+ Rails.application.eager_load!
33
+ rescue StandardError
34
+ nil
35
+ end
32
36
  yield self if block_given?
33
37
  end
34
38
 
@@ -42,4 +46,4 @@ module RuntimeProfiler
42
46
  profiler.save_instrumentation_data
43
47
  end
44
48
  end
45
- end
49
+ end
@@ -12,6 +12,7 @@ module RuntimeProfiler
12
12
  def call(*args)
13
13
  event = RuntimeProfiler::ProcessActionEvent.new(args: args)
14
14
  return unless event.recordable?
15
+
15
16
  add event
16
17
  end
17
18
 
@@ -26,12 +26,12 @@ module RuntimeProfiler
26
26
 
27
27
  @data[key][:sql] = event.sanitized_sql
28
28
  @data[key][:runtimes] = [
29
- [ event.total_runtime, event.trace.first ]
29
+ [event.total_runtime, event.trace.first]
30
30
  ]
31
31
  end
32
32
 
33
33
  def update(event)
34
- @data[event.key][:runtimes] << [ event.total_runtime, event.trace.first ]
34
+ @data[event.key][:runtimes] << [event.total_runtime, event.trace.first]
35
35
  end
36
36
  end
37
37
  end
@@ -49,4 +49,4 @@ module RuntimeProfiler
49
49
  run!
50
50
  end
51
51
  end
52
- end
52
+ end
@@ -30,4 +30,4 @@ module RuntimeProfiler
30
30
  @key ||= Digest::MD5.hexdigest(path.downcase)
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -8,12 +8,34 @@ module RuntimeProfiler
8
8
  end
9
9
 
10
10
  def persist!
11
- instrumented_api = [
11
+ File.open(output_file, 'w') do |f|
12
+ f.write JSON.dump(instrumentation_data)
13
+ end
14
+
15
+ puts "\n"
16
+ puts 'Profiling data written at ' + output_file.to_s
17
+ puts 'You can view profiling data via: bundle exec runtime_profiler view ' + output_file.to_s
18
+ puts "\n"
19
+ end
20
+
21
+ private
22
+
23
+ def output_file
24
+ FileUtils.mkdir_p(RuntimeProfiler.output_path)
25
+ filename = ['rp', Process.pid, Time.now.to_i].join('-') + '.json'
26
+ File.join(RuntimeProfiler.output_path, filename)
27
+ end
28
+
29
+ def instrumented_api
30
+ return unless controller_data[:payload]
31
+ @instrumented_api ||= [
12
32
  controller_data[:payload][:controller],
13
33
  controller_data[:payload][:action]
14
- ].join('#') if controller_data[:payload]
34
+ ].join('#')
35
+ end
15
36
 
16
- instrumentation_data = {
37
+ def instrumentation_data
38
+ @instrumentation_data ||= {
17
39
  instrumentation: {
18
40
  instrumented_api: instrumented_api,
19
41
  summary: {
@@ -32,31 +54,8 @@ module RuntimeProfiler
32
54
  instrumented_at: Time.now
33
55
  }
34
56
  }
35
-
36
- FileUtils.mkdir_p(RuntimeProfiler.output_path)
37
- filename = ['runtime-profiling', Process.pid, Time.now.to_i].join('-') << '.json'
38
- output_file = File.join(RuntimeProfiler.output_path, filename)
39
-
40
- File.open(output_file, 'w') do |f|
41
- f.write JSON.dump(instrumentation_data)
42
- end
43
-
44
- puts "\n"
45
- puts '~~~~> [ Profiling RUNTIME ] Profiling now COMPLETE and JSON report is written at ' + output_file.to_s
46
- puts '~~~~> [ Profiling RUNTIME ]'
47
- puts '~~~~> [ Profiling RUNTIME ] You can do the following to view the JSON report in console:'
48
- puts '~~~~> [ Profiling RUNTIME ]'
49
- puts '~~~~> [ Profiling RUNTIME ] bundle exec runtime_profiler view ' + output_file.to_s
50
- puts '~~~~> [ Profiling RUNTIME ]'
51
- puts '~~~~> [ Profiling RUNTIME ] Or'
52
- puts '~~~~> [ Profiling RUNTIME ]'
53
- puts '~~~~> [ Profiling RUNTIME ] bundle exec runtime_profiler view --help'
54
- puts '~~~~> [ Profiling RUNTIME ]'
55
- puts '~~~~> [ Profiling RUNTIME ] for more details.'
56
57
  end
57
58
 
58
- private
59
-
60
59
  def method_calls_data
61
60
  @method_calls_data ||= begin
62
61
  instrumented_methods = {}
@@ -23,12 +23,12 @@ module RuntimeProfiler
23
23
  @active_record_callback = Callback::ActiveRecord.new
24
24
 
25
25
  @subscribers << ActiveSupport::Notifications
26
- .subscribe('sql.active_record', @active_record_callback)
26
+ .subscribe('sql.active_record', @active_record_callback)
27
27
 
28
28
  @action_controller_callback = Callback::ActionController.new
29
29
 
30
30
  @subscribers << ActiveSupport::Notifications
31
- .subscribe('process_action.action_controller', @action_controller_callback)
31
+ .subscribe('process_action.action_controller', @action_controller_callback)
32
32
  end
33
33
 
34
34
  def unsubscribe_to_event_notifications
@@ -38,18 +38,18 @@ module RuntimeProfiler
38
38
  end
39
39
 
40
40
  def prepare_methods_to_instrument
41
- self.instrumented_constants.flatten
42
- .each { |constant| MethodMeter.observe(constant) }
41
+ instrumented_constants.flatten
42
+ .each { |constant| MethodMeter.observe(constant) }
43
43
  end
44
44
 
45
45
  def save_instrumentation_data
46
46
  unsubscribe_to_event_notifications
47
47
 
48
48
  instrumentation_data = RuntimeProfiler::InstrumentationData.new \
49
- controller_data: @action_controller_callback.controller_data,
50
- sql_data: @active_record_callback.data
49
+ controller_data: @action_controller_callback.controller_data,
50
+ sql_data: @active_record_callback.data
51
51
 
52
52
  instrumentation_data.persist!
53
53
  end
54
54
  end
55
- end
55
+ end
@@ -26,12 +26,12 @@ module RuntimeProfiler
26
26
  \e[1mSQL CALLS\e[22m
27
27
  Total : %s
28
28
  Total Unique : %s
29
-
29
+
30
30
  \e[1mSLOWEST\e[22m
31
31
  Total Runtime : %s ms
32
32
  SQL : %s
33
33
  Source : %s
34
-
34
+
35
35
  \e[1mMOSTLY CALLED\e[22m
36
36
  Total Calls : %s
37
37
  Total Runtime : %s ms
@@ -86,7 +86,7 @@ module RuntimeProfiler
86
86
  attr_accessor :data, :options
87
87
 
88
88
  def initialize(json_file, options)
89
- self.data = JSON.parse( File.read(json_file) )
89
+ self.data = JSON.parse(File.read(json_file))
90
90
  self.options = options
91
91
  end
92
92
 
@@ -121,12 +121,12 @@ module RuntimeProfiler
121
121
 
122
122
  def print_summary
123
123
  summary = if only_methods?
124
- METHODS_DETAILS_TEMPLATE % details_template_data
125
- elsif only_sqls?
126
- SQLS_DETAILS_TEMPLATE % details_template_data
127
- else
128
- FULL_DETAILS_TEMPLATE % details_template_data
129
- end
124
+ METHODS_DETAILS_TEMPLATE % details_template_data
125
+ elsif only_sqls?
126
+ SQLS_DETAILS_TEMPLATE % details_template_data
127
+ else
128
+ FULL_DETAILS_TEMPLATE % details_template_data
129
+ end
130
130
  puts summary
131
131
  end
132
132
 
@@ -158,7 +158,6 @@ module RuntimeProfiler
158
158
  ]
159
159
  t.add_separator if index < instrumented_methods.size - 1
160
160
  end
161
-
162
161
  end
163
162
 
164
163
  puts
@@ -176,7 +175,7 @@ module RuntimeProfiler
176
175
  instrumented_sql_calls = sort(instrumented_sql_calls, false)
177
176
 
178
177
  table = Terminal::Table.new do |t|
179
- t.headings = ['Count', 'Total Runtime (ms)', 'Average Runtime (ms)', 'SQL Query', 'Source']
178
+ t.headings = ['SQL Query', 'Count', 'Total Runtime (ms)', 'Average Runtime (ms)', 'Source']
180
179
 
181
180
  instrumented_sql_calls.each_with_index do |row, index|
182
181
  chopped_sql = wrap_text(row['sql'], sql_width)
@@ -192,18 +191,17 @@ module RuntimeProfiler
192
191
  (0...total_lines).each do |line|
193
192
  count = line == 0 ? row['total_calls'] : ''
194
193
  average = line == 0 ? average_runtime : ''
195
- total_runtime = line == 0 ? total_runtime : ''
194
+ total_runtime = line == 0 ? total_runtime : ''
196
195
  source = source_list.length > line ? source_list[line] : ''
197
196
  query = row['sql'].length > line ? chopped_sql[line] : ''
198
197
 
199
198
  t.add_row []
200
- t.add_row [count, total_runtime, average, query, source]
199
+ t.add_row [query, count, total_runtime, average, source]
201
200
  end
202
201
 
203
202
  t.add_row []
204
203
  t.add_separator if index < instrumented_sql_calls.size - 1
205
204
  end
206
-
207
205
  end
208
206
 
209
207
  puts
@@ -215,6 +213,7 @@ module RuntimeProfiler
215
213
 
216
214
  def wrap_text(text, width)
217
215
  return [text] if text.length <= width
216
+
218
217
  text.scan(/.{1,#{width}}/)
219
218
  end
220
219
 
@@ -231,7 +230,7 @@ module RuntimeProfiler
231
230
  end
232
231
  end
233
232
 
234
- def sort(data, methods=true)
233
+ def sort(data, methods = true)
235
234
  if methods
236
235
  data.sort_by do |d|
237
236
  if options.sort_by == 'max_runtime'
@@ -243,8 +242,8 @@ module RuntimeProfiler
243
242
  end
244
243
  end
245
244
  else
246
- options.sort_by = 'total_runtime' if options.sort_by == 'max_runtime'
247
- data.sort_by { |d| options.sort_by == 'total_runtime' ? -d['total_runtime'] : -d['total_calls'] }
245
+ options.sort_by = 'total_runtime' if options.sort_by == 'max_runtime'
246
+ data.sort_by { |d| options.sort_by == 'total_runtime' ? -d['total_runtime'] : -d['total_calls'] }
248
247
  end
249
248
  end
250
249
 
@@ -1,3 +1,3 @@
1
1
  module RuntimeProfiler
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.3.4'.freeze
3
3
  end
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'runtime_profiler/version'
5
4
 
@@ -19,15 +18,16 @@ Gem::Specification.new do |spec|
19
18
  spec.executables = ['runtime_profiler']
20
19
  spec.require_paths = ['lib']
21
20
 
21
+ spec.add_development_dependency 'activesupport', '>= 3.0.0'
22
22
  spec.add_development_dependency 'bundler'
23
- spec.add_development_dependency 'rake', '>= 12.3.3'
24
23
  spec.add_development_dependency 'minitest', '~> 5.0'
25
- spec.add_development_dependency 'activesupport', '>= 3.0.0'
26
- spec.add_development_dependency 'pry'
27
24
  spec.add_development_dependency 'minitest-line'
28
- spec.add_runtime_dependency 'terminal-table'
25
+ spec.add_development_dependency 'pry'
26
+ spec.add_development_dependency 'rake', '>= 12.3.3'
27
+ spec.add_development_dependency 'rubocop'
29
28
  spec.add_runtime_dependency 'commander'
29
+ spec.add_runtime_dependency 'defined_methods'
30
30
  spec.add_runtime_dependency 'hirb'
31
31
  spec.add_runtime_dependency 'method_meter'
32
- spec.add_runtime_dependency 'defined_methods'
32
+ spec.add_runtime_dependency 'terminal-table'
33
33
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runtime_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wilfrido T. Nuqui Jr.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-04 00:00:00.000000000 Z
11
+ date: 2020-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 3.0.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 3.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 12.3.3
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 12.3.3
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activesupport
56
+ name: minitest-line
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 3.0.0
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 3.0.0
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +81,21 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: minitest-line
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 12.3.3
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 12.3.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -95,7 +109,7 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: terminal-table
112
+ name: commander
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: commander
126
+ name: defined_methods
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -151,7 +165,7 @@ dependencies:
151
165
  - !ruby/object:Gem::Version
152
166
  version: '0'
153
167
  - !ruby/object:Gem::Dependency
154
- name: defined_methods
168
+ name: terminal-table
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - ">="