etalon 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0fb791760ce141b660f228dde7b375ab1cc8da1517bfb73037a5f62fa131f688
4
+ data.tar.gz: 38d7da2d8215dc9e4dc4588247295a953c3130729a621e537b6dc607617a40f0
5
+ SHA512:
6
+ metadata.gz: e46a28737336f6c99d0e97c218a2c66913b9cee61e34fccaed6d531dcd6bd8ba1ca5141a567a189ae4637203705ac0091aebfb3fe31c1e89d67469dae0f0f64a
7
+ data.tar.gz: 55270db263194c75f3afcb0bb4ea7ab1e3fdedb67197a72234e80f7f401b53026496602468a075d303b7510c9b5cab37098cde48c0629f47d6b562c323b09bf1
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /tmp/
10
+ *.gem
11
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1 @@
1
+ 2.5.3
@@ -0,0 +1,6 @@
1
+ ignore:
2
+ - '**/*.rb':
3
+ - Layout/SpaceInsideHashLiteralBraces
4
+ - Layout/SpaceInsideArrayLiteralBrackets
5
+ - Layout/SpaceAroundOperators
6
+ - Standard/SemanticBlocks
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6.1
4
+ - 2.5.3
5
+ - 2.4.2
6
+ - 2.3.8
7
+ - 2.2.10
8
+ - jruby
9
+ - truffleruby
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## 0.1.0 - October 31, 2018
10
+ ### Added
11
+ - `Etalon.time` method which accepts a string title as its first argument
12
+ and a block argument which will store calls matching the same title and
13
+ compare their minimum, maximum, and average execution time but also the
14
+ standard deviation from that average, the 5 slowest timings, and the
15
+ iteration count.
16
+ - `Etalon.print_timings` method which returns a Hash of the above metrics
17
+ for all blocks of instrumented code and logs one line per unique `Etalon.time`
18
+ title in either the `Rails.logger` or a `Syslog::Logger` instance.
19
+ - `Etalon.active?` to check whether Etalon is... activated. Meaning whether it
20
+ is recording metrics or simply yielding to the block of code supplied to
21
+ `Etalon.time` without doing anything.
22
+ - `Etalon.activate` to make the `ETALON_ACTIVE` environment variable truthy,
23
+ which will cause `Etalon.active?` to return `true`.
24
+ - `Etalon.deactivate` to make the `ETALON_ACTIVE` environment variable falsey,
25
+ which will cause `Etalon.active?` to return `false`.
26
+
27
+
28
+ [Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.1.0...HEAD
@@ -0,0 +1,11 @@
1
+ # Contributing
2
+
3
+ After checking out the repo, run `bin/setup` to install dependencies.
4
+ You can also run `bin/console` for an interactive prompt that will allow
5
+ you to experiment.
6
+
7
+ To install this gem onto your local machine, run `bundle exec rake
8
+ install`. To release a new version, update the version number in
9
+ `version.rb`, and then run `bundle exec rake release`, which will create
10
+ a git tag for the version, push git commits and tags, and push the
11
+ `.gem` file to [rubygems.org](https://rubygems.org).
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in etalon.gemspec
6
+ gemspec
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ etalon (0.1.0)
5
+ activesupport (> 5.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (5.2.1)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ ast (2.4.0)
16
+ byebug (10.0.2)
17
+ concurrent-ruby (1.0.5)
18
+ diff-lcs (1.3)
19
+ i18n (1.1.1)
20
+ concurrent-ruby (~> 1.0)
21
+ jaro_winkler (1.5.2)
22
+ minitest (5.11.3)
23
+ parallel (1.13.0)
24
+ parser (2.6.0.0)
25
+ ast (~> 2.4.0)
26
+ powerpack (0.1.2)
27
+ rainbow (3.0.0)
28
+ rake (10.5.0)
29
+ rspec (3.8.0)
30
+ rspec-core (~> 3.8.0)
31
+ rspec-expectations (~> 3.8.0)
32
+ rspec-mocks (~> 3.8.0)
33
+ rspec-core (3.8.0)
34
+ rspec-support (~> 3.8.0)
35
+ rspec-expectations (3.8.2)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.8.0)
38
+ rspec-mocks (3.8.0)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.8.0)
41
+ rspec-support (3.8.0)
42
+ rubocop (0.63.1)
43
+ jaro_winkler (~> 1.5.1)
44
+ parallel (~> 1.10)
45
+ parser (>= 2.5, != 2.5.1.1)
46
+ powerpack (~> 0.1)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ ruby-progressbar (~> 1.7)
49
+ unicode-display_width (~> 1.4.0)
50
+ ruby-progressbar (1.10.0)
51
+ standard (0.0.26)
52
+ rubocop (>= 0.63)
53
+ thread_safe (0.3.6)
54
+ tzinfo (1.2.5)
55
+ thread_safe (~> 0.1)
56
+ unicode-display_width (1.4.1)
57
+ yard (0.9.16)
58
+
59
+ PLATFORMS
60
+ ruby
61
+
62
+ DEPENDENCIES
63
+ bundler (~> 1.16)
64
+ byebug (~> 10.0)
65
+ etalon!
66
+ rake (~> 10.0)
67
+ rspec (~> 3.8)
68
+ standard (~> 0.0)
69
+ yard (~> 0.9)
70
+
71
+ BUNDLED WITH
72
+ 1.17.3
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Olivier Lacan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,79 @@
1
+ # Etalon [![Build Status][ci-badge]][ci-url]
2
+
3
+ A simple tool to instrument Ruby code and output basic metrics to a
4
+ logger or store them in a hash.
5
+
6
+ From the French noun `étalon` meaning:
7
+ > standard: something used as a measure for comparative evaluations
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'etalon'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install etalon
24
+
25
+ In that last case, you'll need to manually `require "etalon"`.
26
+
27
+ ## Usage
28
+
29
+ Assuming the following instrumented code:
30
+
31
+ ```ruby
32
+ class Cooking
33
+ def self.potato
34
+ Etalon.time("Making taters") do
35
+ peel_potato
36
+ cook_potato
37
+ end
38
+ end
39
+ end
40
+ ```
41
+
42
+ You can do the following:
43
+
44
+ ```
45
+ $ irb
46
+ require "cooking"
47
+ => true
48
+
49
+ Etalon.activate
50
+ => true
51
+
52
+ Etalon.print_timings
53
+ => {:making_taters=>["count: 1", "min: 0", "max: 400", "mean: 400.0", "deviation: 0.0", "top 5: [400]"]}
54
+ ```
55
+
56
+ If `Rails.logger` is available, Etalon will also output the following with
57
+ a call to `Rails.logger.debug` in the relevant log file:
58
+
59
+ ```
60
+ Making Taters - count: 1 | min: 0 | max: 400 | mean: 400.0 | deviation: ±0.0% | top 5: [400]
61
+ ```
62
+
63
+ If `Rails.logger` isn't available, Etalon attempts to require
64
+ [`syslog/logger`][syslog-logger] from the Ruby standard library as a fallback
65
+ logging mechanism.
66
+
67
+ [syslog-logger]: https://www.rubydoc.info/stdlib/syslog/2.3.1/Syslog/Logger
68
+
69
+ ## Contributing
70
+
71
+ [Bug reports][bugs] and [pull requests][pulls] are welcome.
72
+
73
+ See [contribution guidelines][contributions].
74
+
75
+ [bugs]: https://github.com/olivierlacan/etalon/issues
76
+ [pulls]: https://github.com/olivierlacan/etalon/pulls
77
+ [contributions]: https://github.com/olivierlacan/etalon/blob/master/CONTRIBUTING.md
78
+ [ci-badge]: https://travis-ci.org/olivierlacan/etalon.svg?branch=master
79
+ [ci-url]: https://travis-ci.org/olivierlacan/etalon
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "etalon"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,43 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "etalon/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "etalon"
7
+ spec.version = Etalon::VERSION
8
+ spec.licenses = ["MIT"]
9
+ spec.authors = ["Olivier Lacan"]
10
+ spec.email = ["hi@olivierlacan.com"]
11
+
12
+ spec.summary = "A very simple tool to instrument Ruby code"
13
+ spec.description = '
14
+ A very simple tool to instrument Ruby code and output basic metrics to a
15
+ logger or store them in a hash.
16
+ '.split.join(" ")
17
+ spec.homepage = "https://github.com/olivierlacan/etalon"
18
+
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = spec.homepage
22
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
23
+ end
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+ spec.metadata["yard.run"] = "yri"
34
+
35
+ spec.add_dependency "activesupport", "> 5.0"
36
+
37
+ spec.add_development_dependency "bundler", "~> 1.16"
38
+ spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "rspec", "~> 3.8"
40
+ spec.add_development_dependency "yard", "~> 0.9"
41
+ spec.add_development_dependency "byebug", "~> 10.0"
42
+ spec.add_development_dependency "standard", "~> 0.0"
43
+ end
@@ -0,0 +1,167 @@
1
+ require "etalon/version"
2
+ require "active_support/inflector"
3
+
4
+ # Etalon is a simple tool to instrument Ruby code and output basic
5
+ # metrics to a logger or store them in a hash.
6
+ module Etalon
7
+ class << self
8
+ #
9
+ # @return [Boolean] whether Etalon is active and recording metrics.
10
+ def active?
11
+ # rubocop:disable Style/DoubleNegation
12
+ !!ENV["ETALON_ACTIVE"]
13
+ # rubocop:enable Style/DoubleNegation
14
+ end
15
+
16
+ # Runs timing metrics on the supplied block of code and stores those metrics
17
+ # for later logging or analysis using the supplied @identifier.
18
+ #
19
+ #
20
+ # @param identifier [String] A unique identifier used to store calls to
21
+ # the supplied block and report them later.
22
+ # @return the supplied block's return value
23
+ def time(identifier)
24
+ if active?
25
+ unless block_given?
26
+ raise "Please supply a block of code for Etalon to instrument"
27
+ end
28
+
29
+ start = Time.now
30
+
31
+ return_value = yield
32
+
33
+ duration = elapsed(start)
34
+
35
+ key = key_from(identifier: identifier)
36
+ store = instrument_store_for(key: key)
37
+
38
+ store[:count] += 1
39
+ store[:min] = duration if duration < store[:min]
40
+ store[:max] = duration if duration > store[:max]
41
+ store[:all] << duration
42
+
43
+ return_value
44
+ else
45
+ yield
46
+ end
47
+ end
48
+
49
+ #
50
+ # Uses either Rails.logger or a Syslog::Logger instance to print out
51
+ # iteration count, minimum, maximum, average and standard deviation
52
+ # timings for each individual call instrumented by #time.
53
+ #
54
+ # @return [Hash] all stored metrics indexed by identifier
55
+ def print_timings
56
+ if active?
57
+ instrument_store.each_with_object({}) do |(key, metrics), memo|
58
+ count, min, max, all = metrics.values_at(:count, :min, :max, :all)
59
+ top = all.sort.reverse.take(5)
60
+ mean = mean(all).floor(2)
61
+ deviation = standard_deviation(all).floor(2)
62
+
63
+ title = key.to_s.titleize
64
+
65
+ output = [
66
+ "count: #{count}",
67
+ "min: #{min}",
68
+ "max: #{max}",
69
+ "mean: #{mean}",
70
+ "deviation: ±#{deviation}%",
71
+ "top 5: #{top}",
72
+ ]
73
+
74
+ logger.debug("#{title} - #{output.join(" | ")}")
75
+
76
+ memo[key] = output
77
+ end
78
+ end
79
+ end
80
+
81
+ #
82
+ # Resets Etalon's internal storage to remove all stored timings.
83
+ #
84
+ # @return [type] [description]
85
+ def reset_timings
86
+ @instrument_store = nil
87
+ end
88
+
89
+ #
90
+ # Activates Etalon.
91
+ #
92
+ # @return [Boolean] Etalon's current activation status
93
+ def activate
94
+ !!ENV["ETALON_ACTIVE"] = "true"
95
+ end
96
+
97
+ #
98
+ # Deactivates Etalon.
99
+ #
100
+ # @return [Boolean] Etalon's current activation status
101
+ def deactivate
102
+ !!ENV["ETALON_ACTIVE"] = nil
103
+ end
104
+
105
+ private
106
+
107
+ def instrument_store
108
+ @instrument_store ||= {}
109
+ end
110
+
111
+ def instrument_store_for(key:)
112
+ instrument_store[key] ||= {
113
+ count: 0,
114
+ min: Float::INFINITY,
115
+ max: 0,
116
+ all: [],
117
+ }
118
+ end
119
+
120
+ def key_from(identifier:)
121
+ parameterize(identifier, separator: "_").to_sym
122
+ end
123
+
124
+ def elapsed(start)
125
+ ((Time.now - start) * 1000).floor
126
+ end
127
+
128
+ def mean(samples)
129
+ (samples.sum / samples.length.to_f)
130
+ end
131
+
132
+ def square(number)
133
+ number ** 2
134
+ end
135
+
136
+ def variance(samples)
137
+ return 0 if samples.length < 2
138
+
139
+ sum = samples.inject(0) do |store, value|
140
+ store + square(value - mean(samples))
141
+ end
142
+
143
+ sum.fdiv((samples.length - 1).to_f)
144
+ end
145
+
146
+ def standard_deviation(samples)
147
+ return 0 if samples.length < 2
148
+
149
+ Math.sqrt(variance(samples))
150
+ end
151
+
152
+ def logger
153
+ @logger ||= begin
154
+ if defined?(Rails.logger)
155
+ Rails.logger
156
+ else
157
+ require("syslog/logger")
158
+ Syslog::Logger.new
159
+ end
160
+ end
161
+ end
162
+
163
+ def parameterize(*args)
164
+ ActiveSupport::Inflector.parameterize(*args)
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,3 @@
1
+ module Etalon
2
+ VERSION = "0.1.0" #:no-doc
3
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: etalon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Olivier Lacan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-02-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: standard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.0'
111
+ description: A very simple tool to instrument Ruby code and output basic metrics to
112
+ a logger or store them in a hash.
113
+ email:
114
+ - hi@olivierlacan.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".ruby-version"
122
+ - ".standard.yml"
123
+ - ".travis.yml"
124
+ - CHANGELOG.md
125
+ - CONTRIBUTING.md
126
+ - Gemfile
127
+ - Gemfile.lock
128
+ - LICENSE.md
129
+ - README.md
130
+ - Rakefile
131
+ - bin/console
132
+ - bin/setup
133
+ - etalon.gemspec
134
+ - lib/etalon.rb
135
+ - lib/etalon/version.rb
136
+ homepage: https://github.com/olivierlacan/etalon
137
+ licenses:
138
+ - MIT
139
+ metadata:
140
+ homepage_uri: https://github.com/olivierlacan/etalon
141
+ source_code_uri: https://github.com/olivierlacan/etalon
142
+ changelog_uri: https://github.com/olivierlacan/etalon/blob/master/CHANGELOG.md
143
+ yard.run: yri
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubygems_version: 3.0.2
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: A very simple tool to instrument Ruby code
163
+ test_files: []