rspec-tracer 0.1.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd68858a56e3f240a0710c3dc4d7af601268bc2f4029c3a67f5e93ccd301dc48
4
- data.tar.gz: b89cb78a0fef102e99dd60ccb53b45238d0785d912750c13b9546e0e2fcbe6f3
3
+ metadata.gz: 2817cccf4825e28177bb8794f8d261635f81ec5c1bd6ca0242ba171e702850ca
4
+ data.tar.gz: 9c5f6af579eec43a994c28b5e8132fec5d71f7a2ddddfb531fafd5c51943d283
5
5
  SHA512:
6
- metadata.gz: 6e203ace8d29199999af09cd82418e0160160dae0077b5f4cb56c9c4de7bf40c25c5506e5fbc2d9081af4e7e69c47a80b62ce0a5de94aaee473f9506c62b4d83
7
- data.tar.gz: f955b25c90b5fad1a0f0d4dd1c46f6c3b8c7e1c7d9d5a330a2cb4a13ba543d5264cd0fcdf7fcd545f44fa8d5c636dc6194341cb1ea484a22fd37c925b254d05c
6
+ metadata.gz: 2d3af598e09b8ac043b5f605acf39b588701c4f0e7b4d74646eb0da74c1c85746db60f215e02cd5fba1880bb75288d0d35df3986b08cc71cfbad4d45ad722d2f
7
+ data.tar.gz: 7ce36336213d4d37337afa5b50fd774bd6ef7b235539f3a289f1a804a878fba3fa1e7972e9bd09bb8083c80929c0fc3b6bf0b30f257542fdb5e5c466c1247360
data/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
- ## [Unreleased]
1
+ ## [0.5.0] - 2021-09-03
2
+
3
+ ### Fixed
4
+
5
+ - Limit number of cached files download (#16)
6
+
7
+ ## [0.4.0] - 2021-09-03
8
+
9
+ ### Added
10
+
11
+ - Support for CI
12
+
13
+ ## [0.3.0] - 2021-08-30
14
+
15
+ ### Fixed
16
+
17
+ - `docile` version compatability with `simplecov`
18
+
19
+ ## [0.2.0] - 2021-08-28
20
+
21
+ ### Fixed
22
+
23
+ - Failures when RSpec required files are outside of project
2
24
 
3
25
  ## [0.1.0] - 2021-08-27
4
26
 
data/README.md CHANGED
@@ -14,16 +14,50 @@ Knowing the examples and files dependency gives us a better insight into the cod
14
14
  and we have **a clear idea of what to test for when making any changes**. With this data,
15
15
  we can also analyze the coupling between different components and much more.
16
16
 
17
+ ## Note
18
+
19
+ You should take some time and go through the [document](./RSPEC_TRACER.md) describing
20
+ the **intention** and implementation details of **skipping tests**, **managing coverage**,
21
+ and **caching on CI**, etc.
22
+
23
+ ## Table of Contents
24
+
25
+ * [Demo](#demo)
26
+ * [Installation](#installation)
27
+ * [Compatibility](#compatibility)
28
+ * [Additional Tools](#additional-tools)
29
+ * [Getting Started](#getting-started)
30
+ * [Environment Variables](#environment-variables)
31
+ * [CI](#ci)
32
+ * [LOCAL_AWS](#local_aws)
33
+ * [RSPEC_TRACER_NO_SKIP](#rspec_tracer_no_skip)
34
+ * [RSPEC_TRACER_S3_URI](#rspec_tracer_s3_uri)
35
+ * [RSPEC_TRACER_UPLOAD_LOCAL_CACHE](#rspec_tracer_upload_local_cache)
36
+ * [TEST_SUITES](#test_suites)
37
+ * [TEST_SUITE_ID](#test_suite_id)
38
+ * [Sample Reports](#sample-reports)
39
+ * [Examples](#examples)
40
+ * [Examples Dependency](#examples-dependency)
41
+ * [Files Dependency](#files-dependency)
42
+ * [Configuring RSpec Tracer](#configuring-rspec-tracer)
43
+ * [Filters](#filters)
44
+ * [Defining Custom Filteres](#defining-custom-filteres)
45
+ * [String Filter](#string-filter)
46
+ * [Regex Filter](#regex-filter)
47
+ * [Block Filter](#block-filter)
48
+ * [Array Filter](#array-filter)
49
+ * [Contributing](#contributing)
50
+ * [License](#license)
51
+ * [Code of Conduct](#code-of-conduct)
52
+
53
+ ## Demo
54
+
17
55
  **First Run**
18
56
  ![](./readme_files/first_run.gif)
19
57
 
20
58
  **Next Run**
21
59
  ![](./readme_files/next_run.gif)
22
60
 
23
- ## Note
24
-
25
- **RSpec Tracer is currently available for use in the local development
26
- environment only.**
27
61
 
28
62
  ## Installation
29
63
 
@@ -41,8 +75,14 @@ And, add the followings to your `.gitignore`:
41
75
 
42
76
  ### Compatibility
43
77
 
44
- RSpec Tracer requires **Ruby 2.5+** and **rspec-core >= 3.6.0**. If you are using
45
- SimpleCov, it is recommended to use **simplecov >= 0.12.0**.
78
+ RSpec Tracer requires **Ruby 2.5+** and **rspec-core >= 3.6.0**. To use with **Rails 5+**,
79
+ make sure to use **rspec-rails >= 4.0.0**. If you are using SimpleCov, it is
80
+ recommended to use **simplecov >= 0.12.0**.
81
+
82
+ ### Additional Tools
83
+
84
+ To use RSpec Tracer on CI, you need to have an **S3 bucket** and
85
+ **[AWS CLI](https://aws.amazon.com/cli/)** installed.
46
86
 
47
87
  ## Getting Started
48
88
 
@@ -58,7 +98,7 @@ SimpleCov, it is recommended to use **simplecov >= 0.12.0**.
58
98
  SimpleCov.start
59
99
 
60
100
  # Load RSpec Tracer
61
- require 'rspec-tracer'
101
+ require 'rspec_tracer'
62
102
  RSpecTracer.start
63
103
  ```
64
104
 
@@ -74,18 +114,47 @@ SimpleCov, it is recommended to use **simplecov >= 0.12.0**.
74
114
 
75
115
  ```ruby
76
116
  # Load RSpec Tracer
77
- require 'rspec-tracer'
117
+ require 'rspec_tracer'
78
118
  RSpecTracer.start
79
119
  ```
80
120
 
81
- 2. Run the tests with RSpec using `bundle exec rspec`.
82
- 3. After running your tests, open `rspec_tracer_report/index.html` in the
121
+ 2. To enable RSpec Tracer to share cache between different builds on CI, update the
122
+ Rakefile in your project to have the following:
123
+
124
+ ```ruby
125
+ spec = Gem::Specification.find_by_name('rspec-tracer')
126
+
127
+ load "#{spec.gem_dir}/lib/rspec_tracer/remote_cache/Rakefile"
128
+ ```
129
+ 3. Before running tests, download the remote cache using the following rake task:
130
+
131
+ ```sh
132
+ bundle exec rake rspec_tracer:remote_cache:download
133
+ ```
134
+ 4. Run the tests with RSpec using `bundle exec rspec`.
135
+ 5. After running tests, upload the local cache using the following rake task:
136
+
137
+ ```sh
138
+ bundle exec rake rspec_tracer:remote_cache:upload
139
+ ```
140
+ 6. After running your tests, open `rspec_tracer_report/index.html` in the
83
141
  browser of your choice.
84
142
 
85
143
  ## Environment Variables
86
144
 
87
145
  To get better control on execution, you can use the following two environment variables:
88
146
 
147
+ ### CI
148
+
149
+ Mostly all the CI have `CI=true`. If not, you should explicitly set it to `true`.
150
+
151
+ ### LOCAL_AWS
152
+
153
+ In case you want to test out the caching feature in the local development environment.
154
+ You can install [localstack](https://github.com/localstack/localstack) and
155
+ [awscli-local](https://github.com/localstack/awscli-local) and then invoke the
156
+ rake tasks with `LOCAL_AWS=true`.
157
+
89
158
  ### RSPEC_TRACER_NO_SKIP
90
159
 
91
160
  The default value is `false.` If set to `true`, the RSpec Tracer will not skip
@@ -95,6 +164,28 @@ any tests. Note that it will continue to maintain cache files and generate repor
95
164
  RSPEC_TRACER_NO_SKIP=true bundle exec rspec
96
165
  ```
97
166
 
167
+ ### RSPEC_TRACER_S3_URI
168
+
169
+ You should provide the S3 bucket path to store the cache files.
170
+
171
+ ```ruby
172
+ export RSPEC_TRACER_S3_URI=s3://ci-artifacts-bucket/rspec-tracer-cache
173
+ ```
174
+
175
+ ### RSPEC_TRACER_UPLOAD_LOCAL_CACHE
176
+
177
+ By default, RSpec Tracer does not upload local cache files. You can set this
178
+ environment variable to `true` to upload the local cache to S3.
179
+
180
+ ### TEST_SUITES
181
+
182
+ Set this environment variable when using test suite id. It determines the total
183
+ number of different test suites you are running.
184
+
185
+ ```ruby
186
+ export TEST_SUITES=8
187
+ ```
188
+
98
189
  ### TEST_SUITE_ID
99
190
 
100
191
  If you have a large set of tests to run, it is recommended to run them in
@@ -107,6 +198,21 @@ TEST_SUITE_ID=1 bundle exec rspec spec/models
107
198
  TEST_SUITE_ID=2 bundle exec rspec spec/helpers
108
199
  ```
109
200
 
201
+ If you run parallel builds on the CI, you should specify the test suite ID and
202
+ the total number of test suites when downloading the cache files.
203
+
204
+ ```sh
205
+ $ TEST_SUITES=5 TEST_SUITE_ID=1 bundle exec rake rspec_tracer:remote_cache:download
206
+ ```
207
+
208
+ In this case, the appropriate cache should have all the cache files available on
209
+ the S3 for each test suite, not just for the current one. Also, while uploading,
210
+ make sure to provide the test suite id.
211
+
212
+ ```sh
213
+ $ TEST_SUITE_ID=1 bundle exec rake rspec_tracer:remote_cache:upload
214
+ ```
215
+
110
216
  ## Sample Reports
111
217
 
112
218
  You get the following three reports:
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'git'
4
+
5
+ module RSpecTracer
6
+ module RemoteCache
7
+ class Cache
8
+ class CacheDownloadError < StandardError; end
9
+
10
+ class CacheUploadError < StandardError; end
11
+
12
+ class LocalCacheNotFoundError < StandardError; end
13
+
14
+ CACHE_FILES_PER_TEST_SUITE = 7
15
+
16
+ def initialize
17
+ @s3_uri = ENV['RSPEC_TRACER_S3_URI']
18
+ @aws_s3 = if ENV.fetch('LOCAL_AWS', 'false') == 'true'
19
+ 'awslocal'
20
+ else
21
+ 'aws'
22
+ end
23
+ end
24
+
25
+ def download
26
+ if @s3_uri.nil?
27
+ puts 'S3 URI is not configured'
28
+
29
+ return
30
+ end
31
+
32
+ prepare_for_download
33
+
34
+ if @cache_sha.nil?
35
+ puts 'Could not find a suitable cache sha to download'
36
+
37
+ return
38
+ end
39
+
40
+ download_files
41
+
42
+ puts "Downloaded cache from #{@download_prefix} to #{@download_path}"
43
+ rescue StandardError => e
44
+ puts "Errored: #{e.message}"
45
+ end
46
+
47
+ def upload
48
+ if @s3_uri.nil?
49
+ puts 'S3 URI is not configured'
50
+
51
+ return
52
+ end
53
+
54
+ prepare_for_upload
55
+ upload_files
56
+
57
+ puts "Uploaded cache from #{@upload_path} to #{@upload_prefix}"
58
+ rescue CacheUploadError => e
59
+ puts "Errored: #{e.message}"
60
+ end
61
+
62
+ private
63
+
64
+ def prepare_for_download
65
+ @test_suite_id = ENV['TEST_SUITE_ID']
66
+ @test_suites = ENV['TEST_SUITES']
67
+
68
+ if @test_suite_id.nil? ^ @test_suites.nil?
69
+ raise(
70
+ CacheDownloadError,
71
+ 'Both the enviornment variables TEST_SUITE_ID and TEST_SUITES are not set'
72
+ )
73
+ end
74
+
75
+ @git = RSpecTracer::RemoteCache::Git.new
76
+ @git.prepare_for_download
77
+
78
+ generate_cached_files_count_and_regex
79
+
80
+ @cache_sha = nearest_cache_sha
81
+ end
82
+
83
+ def generate_cached_files_count_and_regex
84
+ if @test_suites.nil?
85
+ @last_run_files_count = 1
86
+ @last_run_files_regex = '/%<ref>s/last_run.json$'
87
+ @cached_files_count = CACHE_FILES_PER_TEST_SUITE
88
+ @cached_files_regex = '/%<ref>s/[0-9a-f]{32}/.+.json'
89
+ else
90
+ @test_suites = @test_suites.to_i
91
+ @test_suites_regex = (1..@test_suites).to_a.join('|')
92
+
93
+ @last_run_files_count = @test_suites
94
+ @last_run_files_regex = "/%<ref>s/(#{@test_suites_regex})/last_run.json$"
95
+ @cached_files_count = CACHE_FILES_PER_TEST_SUITE * @test_suites.to_i
96
+ @cached_files_regex = "/%<ref>s/(#{@test_suites_regex})/[0-9a-f]{32}/.+.json$"
97
+ end
98
+ end
99
+
100
+ def nearest_cache_sha
101
+ @git.ref_list.detect do |ref|
102
+ prefix = "#{@s3_uri}/#{ref}/"
103
+
104
+ puts "Testing prefix #{prefix}"
105
+
106
+ objects = `#{@aws_s3} s3 ls #{prefix} --recursive`.chomp.split("\n")
107
+
108
+ last_run_regex = Regexp.new(format(@last_run_files_regex, ref: ref))
109
+
110
+ next if objects.count { |object| object.match?(last_run_regex) } != @last_run_files_count
111
+
112
+ cache_regex = Regexp.new(format(@cached_files_regex, ref: ref))
113
+
114
+ objects.count { |object| object.match?(cache_regex) } == @cached_files_count
115
+ end
116
+ end
117
+
118
+ def download_files
119
+ @download_prefix = "#{@s3_uri}/#{@cache_sha}/#{@test_suite_id}/".sub(%r{/+$}, '/')
120
+ @download_path = RSpecTracer.cache_path
121
+
122
+ raise CacheDownloadError, 'Failed to download cache files' unless system(
123
+ @aws_s3, 's3', 'cp',
124
+ File.join(@download_prefix, 'last_run.json'),
125
+ @download_path,
126
+ out: File::NULL, err: File::NULL
127
+ )
128
+
129
+ @run_id = last_run_id
130
+
131
+ return if system(
132
+ @aws_s3, 's3', 'cp',
133
+ File.join(@download_prefix, @run_id),
134
+ File.join(@download_path, @run_id),
135
+ '--recursive',
136
+ out: File::NULL, err: File::NULL
137
+ )
138
+
139
+ FileUtils.rm_rf(@download_path)
140
+
141
+ raise CacheDownloadError, 'Failed to download cache files'
142
+ end
143
+
144
+ def prepare_for_upload
145
+ @git = RSpecTracer::RemoteCache::Git.new
146
+ @test_suite_id = ENV['TEST_SUITE_ID']
147
+ @upload_prefix = if @test_suite_id.nil?
148
+ "#{@s3_uri}/#{@git.branch_ref}/"
149
+ else
150
+ "#{@s3_uri}/#{@git.branch_ref}/#{@test_suite_id}/"
151
+ end
152
+
153
+ @upload_path = RSpecTracer.cache_path
154
+ @run_id = last_run_id
155
+ end
156
+
157
+ def upload_files
158
+ return if system(
159
+ @aws_s3, 's3', 'cp',
160
+ File.join(@upload_path, 'last_run.json'),
161
+ @upload_prefix,
162
+ out: File::NULL, err: File::NULL
163
+ ) && system(
164
+ @aws_s3, 's3', 'cp',
165
+ File.join(@upload_path, @run_id),
166
+ File.join(@upload_prefix, @run_id),
167
+ '--recursive',
168
+ out: File::NULL, err: File::NULL
169
+ )
170
+
171
+ raise CacheUploadError, 'Failed to upload cache files'
172
+ end
173
+
174
+ def last_run_id
175
+ file_name = File.join(RSpecTracer.cache_path, 'last_run.json')
176
+
177
+ return unless File.file?(file_name)
178
+
179
+ run_id = JSON.parse(File.read(file_name))['run_id']
180
+
181
+ raise LocalCacheNotFoundError, 'Could not find any local cache to upload' if run_id.nil?
182
+
183
+ run_id
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpecTracer
4
+ module RemoteCache
5
+ class Git
6
+ class GitOperationError < StandardError; end
7
+
8
+ attr_reader :branch_ref, :ref_list
9
+
10
+ def initialize
11
+ fetch_head_ref
12
+ fetch_branch_ref
13
+ end
14
+
15
+ def prepare_for_download
16
+ fetch_unreachable_refs
17
+ fetch_ancestry_refs
18
+ fetch_ordered_refs
19
+ end
20
+
21
+ private
22
+
23
+ def fetch_head_ref
24
+ @head_ref = `git rev-parse HEAD`.chomp
25
+
26
+ raise GitOperationError, 'Could not find HEAD commit sha' unless $CHILD_STATUS.success?
27
+ end
28
+
29
+ def fetch_branch_ref
30
+ @merged_parents = []
31
+ @ignored_refs = []
32
+
33
+ unless merged?
34
+ @branch_ref = @head_ref
35
+
36
+ return
37
+ end
38
+
39
+ @ignored_refs << @head_ref
40
+
41
+ fetch_merged_parents
42
+ fetch_merged_branch_ref
43
+ end
44
+
45
+ def merged?
46
+ system('git', 'rev-parse', 'HEAD^2', out: File::NULL, err: File::NULL)
47
+ end
48
+
49
+ def fetch_merged_parents
50
+ first_parent = `git rev-parse HEAD^1`.chomp
51
+ @merged_parents << first_parent if $CHILD_STATUS.success?
52
+
53
+ second_parent = `git rev-parse HEAD^2`.chomp
54
+ @merged_parents << second_parent if $CHILD_STATUS.success?
55
+
56
+ raise GitOperationError, 'Could not find merged commit parents' if @merged_parents.length != 2
57
+ end
58
+
59
+ def fetch_merged_branch_ref
60
+ @origin_head_ref = `git rev-parse origin/HEAD`.chomp
61
+ @branch_ref = nil
62
+
63
+ if @merged_parents.first != @origin_head_ref
64
+ @branch_ref = @head_ref
65
+ @ignored_refs = []
66
+
67
+ return
68
+ end
69
+
70
+ @branch_ref = @merged_parents.last
71
+ @ignored_refs = @ignored_refs.to_set | `git rev-list #{@branch_ref}..origin/HEAD`.chomp.split
72
+
73
+ raise GitOperationError, 'Could not find ignored refs' unless $CHILD_STATUS.success?
74
+ end
75
+
76
+ def fetch_unreachable_refs
77
+ command = <<-COMMAND.strip.gsub(/\s+/, ' ')
78
+ git fsck
79
+ --no-progress
80
+ --unreachable
81
+ --connectivity-only #{@branch_ref}
82
+ | awk '/commit/ { print $3 }'
83
+ | head -n 25
84
+ COMMAND
85
+
86
+ @unreachable_refs = `#{command}`.chomp.split
87
+
88
+ raise GitOperationError, 'Could not find unreachable refs' unless $CHILD_STATUS.success?
89
+ end
90
+
91
+ def fetch_ancestry_refs
92
+ @ancestry_refs = `git rev-list --max-count=25 #{@branch_ref}`.chomp.split
93
+
94
+ raise GitOperationError, 'Could not find ancestry refs' unless $CHILD_STATUS.success?
95
+ end
96
+
97
+ def fetch_ordered_refs
98
+ unordered_refs = (@unreachable_refs.to_set | @ancestry_refs) - @ignored_refs
99
+
100
+ command = <<-COMMAND.strip.gsub(/\s+/, ' ')
101
+ git rev-list
102
+ --topo-order
103
+ --no-walk=sorted
104
+ #{unordered_refs.to_a.join(' ')}
105
+ COMMAND
106
+
107
+ @ref_list = `#{command}`.chomp.split
108
+
109
+ raise GitOperationError, 'Could not find refs to download cache' unless $CHILD_STATUS.success?
110
+ end
111
+ end
112
+ end
113
+ end
@@ -208,10 +208,11 @@ module RSpecTracer
208
208
  rspec_root = RSpec::Core::RubyProject.root
209
209
  rspec_path = RSpec.configuration.default_path
210
210
 
211
- RSpec.configuration.requires.map do |file_name|
211
+ RSpec.configuration.requires.each_with_object([]) do |file_name, required_files|
212
212
  file_name = "#{file_name}.rb" if File.extname(file_name).empty?
213
+ file_path = File.join(rspec_root, rspec_path, file_name)
213
214
 
214
- File.join(rspec_root, rspec_path, file_name)
215
+ required_files << file_path if File.file?(file_path)
215
216
  end
216
217
  end
217
218
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSpecTracer
4
- VERSION = '0.1.0'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/rspec_tracer.rb CHANGED
@@ -17,6 +17,7 @@ require_relative 'rspec_tracer/coverage_reporter'
17
17
  require_relative 'rspec_tracer/defaults'
18
18
  require_relative 'rspec_tracer/example'
19
19
  require_relative 'rspec_tracer/html_reporter/reporter'
20
+ require_relative 'rspec_tracer/remote_cache/cache'
20
21
  require_relative 'rspec_tracer/rspec_reporter'
21
22
  require_relative 'rspec_tracer/rspec_runner'
22
23
  require_relative 'rspec_tracer/ruby_coverage'
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abhimanyu Singh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-26 00:00:00.000000000 Z
11
+ date: 2021-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.1.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.1'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 1.1.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.1'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rspec-core
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +91,8 @@ files:
85
91
  - lib/rspec_tracer/html_reporter/views/examples_dependency.erb
86
92
  - lib/rspec_tracer/html_reporter/views/files_dependency.erb
87
93
  - lib/rspec_tracer/html_reporter/views/layout.erb
94
+ - lib/rspec_tracer/remote_cache/cache.rb
95
+ - lib/rspec_tracer/remote_cache/git.rb
88
96
  - lib/rspec_tracer/reporter.rb
89
97
  - lib/rspec_tracer/rspec_reporter.rb
90
98
  - lib/rspec_tracer/rspec_runner.rb
@@ -97,7 +105,7 @@ licenses:
97
105
  - MIT
98
106
  metadata:
99
107
  homepage_uri: https://github.com/avmnu-sng/rspec-tracer
100
- source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v0.1.0
108
+ source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v0.5.0
101
109
  changelog_uri: https://github.com/avmnu-sng/rspec-tracer/blob/main/CHANGELOG.md
102
110
  bug_tracker_uri: https://github.com/avmnu-sng/rspec-tracer/issues
103
111
  post_install_message: