Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: myronmarston/vcr
...
head fork: myronmarston/vcr
Checking mergeability… Don't worry, you can still create the pull request.
  • 14 commits
  • 13 files changed
  • 0 commit comments
  • 3 contributors
Commits on Jul 25, 2012
@JonathanTron JonathanTron Typhoeus 0.4.2 is out and works fine with VCR
d09de03
@myronmarston Merge pull request #184 from JonathanTron/patch-1
Typhoeus 0.4.2 is out and works fine with VCR
1fac6cf
@myronmarston Add @JonathanTron to contributors list.
12905a3
@myronmarston The new WebMock release has fixed the Net::HTTP empty body bug.
d9873fb
@myronmarston Ignore rbx18-mode failures.
The travis build failed with no indication as to why:

http://travis-ci.org/#!/myronmarston/vcr/jobs/1952677/L30

..and I've often had problems with the rbx build due to rbx issues.
a1be691
Commits on Aug 12, 2012
@myronmarston Relax the faraday version constraint.
c5b249a
Commits on Aug 13, 2012
@myronmarston Allow jruby 18 failure.
I'm getting a weird error from Jruby:

$ script/ci.sh
81CachingCallSite.java:311:in `cacheAndCall': java.lang.NullPointerException
82	from CachingCallSite.java:169:in `call'
83	from /home/vagrant/.rvm/rubies/jruby-1.6.7.2/lib/ruby/site_ruby/1.8/rubygems/version.rb:279:in `__file__'
84	from /home/vagrant/.rvm/rubies/jruby-1.6.7.2/lib/ruby/site_ruby/1.8/rubygems/version.rb:-1:in `__file__'
85	from JittedMethod.java:127:in `call'
86	from DefaultMethod.java:183:in `call'
87	from CachingCallSite.java:133:in `call'
88	from CallNoArgNode.java:63:in `interpret'
89	from LocalAsgnNode.java:123:in `interpret'
90	from NewlineNode.java:104:in `interpret'
91	from BlockNode.java:71:in `interpret'
92	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
93	from InterpretedMethod.java:190:in `call'
94	from DefaultMethod.java:199:in `call'
95	from RuntimeHelpers.java:2622:in `invokedynamic'
96	from RubyComparable.java:149:in `op_ge'
97	from RubyComparable$s$1$0$op_ge.gen:65535:in `call'
98	from CachingCallSite.java:312:in `cacheAndCall'
99	from CachingCallSite.java:169:in `call'
100	from GeCallSite.java:37:in `call'
101	from CallOneArgNode.java:57:in `interpret'
102	from IfNode.java:111:in `interpret'
103	from NewlineNode.java:104:in `interpret'
104	from BlockNode.java:71:in `interpret'
105	from IfNode.java:117:in `interpret'
106	from NewlineNode.java:104:in `interpret'
107	from BlockNode.java:71:in `interpret'
108	from ASTInterpreter.java:111:in `INTERPRET_BLOCK'
109	from InterpretedBlock.java:374:in `evalBlockBody'
110	from InterpretedBlock.java:347:in `yield'
111	from InterpretedBlock.java:304:in `yield'
112	from Block.java:130:in `yield'
113	from YieldNode.java:119:in `interpret'
114	from IfNode.java:117:in `interpret'
115	from NewlineNode.java:104:in `interpret'
116	from BlockNode.java:71:in `interpret'
117	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
118	from InterpretedMethod.java:169:in `call'
119	from DefaultMethod.java:191:in `call'
120	from CachingCallSite.java:142:in `callBlock'
121	from CachingCallSite.java:148:in `call'
122	from RubyClass.java:822:in `newInstance'
123	from RubyClass$i$newInstance.gen:65535:in `call'
124	from CachingCallSite.java:302:in `cacheAndCall'
125	from CachingCallSite.java:144:in `callBlock'
126	from CachingCallSite.java:153:in `callIter'
127	from CallNoArgBlockNode.java:64:in `interpret'
128	from NewlineNode.java:104:in `interpret'
129	from RootNode.java:129:in `interpret'
130	from ASTInterpreter.java:95:in `INTERPRET_EVAL'
131	from ASTInterpreter.java:166:in `evalWithBinding'
132	from RubyKernel.java:1126:in `evalCommon'
133	from RubyKernel.java:1083:in `eval'
134	from RubyKernel$s$0$3$eval.gen:65535:in `call'
135	from DynamicMethod.java:227:in `call'
136	from DynamicMethod.java:223:in `call'
137	from CachingCallSite.java:235:in `call'
138	from FCallThreeArgNode.java:40:in `interpret'
139	from LocalAsgnNode.java:123:in `interpret'
140	from NewlineNode.java:104:in `interpret'
141	from BlockNode.java:71:in `interpret'
142	from RescueNode.java:216:in `executeBody'
143	from RescueNode.java:120:in `interpretWithJavaExceptions'
144	from RescueNode.java:110:in `interpret'
145	from BeginNode.java:83:in `interpret'
146	from NewlineNode.java:104:in `interpret'
147	from BlockNode.java:71:in `interpret'
148	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
149	from InterpretedMethod.java:190:in `call'
150	from DefaultMethod.java:199:in `call'
151	from CachingCallSite.java:167:in `call'
152	from CallOneArgNode.java:57:in `interpret'
153	from DAsgnNode.java:110:in `interpret'
154	from NewlineNode.java:104:in `interpret'
155	from BlockNode.java:71:in `interpret'
156	from ASTInterpreter.java:111:in `INTERPRET_BLOCK'
157	from InterpretedBlock.java:374:in `evalBlockBody'
158	from InterpretedBlock.java:347:in `yield'
159	from InterpretedBlock.java:304:in `yield'
160	from Block.java:130:in `yield'
161	from RubyArray.java:1608:in `eachCommon'
162	from RubyArray.java:1615:in `each'
163	from RubyArray$i$0$0$each.gen:65535:in `call'
164	from CachingCallSite.java:302:in `cacheAndCall'
165	from CachingCallSite.java:144:in `callBlock'
166	from CachingCallSite.java:153:in `callIter'
167	from CallNoArgBlockNode.java:64:in `interpret'
168	from NewlineNode.java:104:in `interpret'
169	from ASTInterpreter.java:111:in `INTERPRET_BLOCK'
170	from InterpretedBlock.java:374:in `evalBlockBody'
171	from InterpretedBlock.java:347:in `yield'
172	from InterpretedBlock.java:304:in `yield'
173	from Block.java:130:in `yield'
174	from RubyArray.java:1608:in `eachCommon'
175	from RubyArray.java:1615:in `each'
176	from RubyArray$i$0$0$each.gen:65535:in `call'
177	from CachingCallSite.java:302:in `cacheAndCall'
178	from CachingCallSite.java:144:in `callBlock'
179	from CachingCallSite.java:153:in `callIter'
180	from CallNoArgBlockNode.java:64:in `interpret'
181	from NewlineNode.java:104:in `interpret'
182	from BlockNode.java:71:in `interpret'
183	from IfNode.java:119:in `interpret'
184	from NewlineNode.java:104:in `interpret'
185	from BlockNode.java:71:in `interpret'
186	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
187	from InterpretedMethod.java:147:in `call'
188	from DefaultMethod.java:183:in `call'
189	from CachingCallSite.java:292:in `cacheAndCall'
190	from CachingCallSite.java:135:in `call'
191	from CallNoArgNode.java:63:in `interpret'
192	from CallNoArgBlockNode.java:60:in `interpret'
193	from NewlineNode.java:104:in `interpret'
194	from BlockNode.java:71:in `interpret'
195	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
196	from InterpretedMethod.java:169:in `call'
197	from DefaultMethod.java:191:in `call'
198	from RubyClass.java:552:in `finvoke'
199	from RuntimeHelpers.java:529:in `invoke'
200	from RubyEnumerable.java:93:in `callEach'
201	from RubyEnumerable.java:650:in `selectCommon'
202	from RubyEnumerable.java:672:in `find_all'
203	from RubyEnumerable$s$0$0$find_all.gen:65535:in `call'
204	from CachingCallSite.java:302:in `cacheAndCall'
205	from CachingCallSite.java:144:in `callBlock'
206	from CachingCallSite.java:153:in `callIter'
207	from CallNoArgBlockNode.java:64:in `interpret'
208	from LocalAsgnNode.java:123:in `interpret'
209	from NewlineNode.java:104:in `interpret'
210	from BlockNode.java:71:in `interpret'
211	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
212	from InterpretedMethod.java:190:in `call'
213	from DefaultMethod.java:199:in `call'
214	from CachingCallSite.java:312:in `cacheAndCall'
215	from CachingCallSite.java:169:in `call'
216	from FCallOneArgNode.java:36:in `interpret'
217	from LocalAsgnNode.java:123:in `interpret'
218	from NewlineNode.java:104:in `interpret'
219	from BlockNode.java:71:in `interpret'
220	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
221	from InterpretedMethod.java:147:in `call'
222	from DefaultMethod.java:183:in `call'
223	from CachingCallSite.java:292:in `cacheAndCall'
224	from CachingCallSite.java:135:in `call'
225	from CallNoArgNode.java:63:in `interpret'
226	from LocalAsgnNode.java:123:in `interpret'
227	from NewlineNode.java:104:in `interpret'
228	from BlockNode.java:71:in `interpret'
229	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
230	from InterpretedMethod.java:147:in `call'
231	from DefaultMethod.java:183:in `call'
232	from CachingCallSite.java:292:in `cacheAndCall'
233	from CachingCallSite.java:135:in `call'
234	from CallNoArgNode.java:63:in `interpret'
235	from LocalAsgnNode.java:123:in `interpret'
236	from NewlineNode.java:104:in `interpret'
237	from BlockNode.java:71:in `interpret'
238	from ASTInterpreter.java:74:in `INTERPRET_METHOD'
239	from InterpretedMethod.java:233:in `call'
240	from DefaultMethod.java:215:in `call'
241	from CachingCallSite.java:332:in `cacheAndCall'
242	from CachingCallSite.java:203:in `call'
243	from /home/vagrant/.rvm/gems/jruby-1.6.7.2@global/bin/bundle:22:in `__file__'
244	from /home/vagrant/.rvm/gems/jruby-1.6.7.2@global/bin/bundle:-1:in `load'
245	from Ruby.java:697:in `runScript'
246	from Ruby.java:690:in `runScript'
247	from Ruby.java:597:in `runNormally'
248	from Ruby.java:446:in `runFromMain'
249	from Main.java:369:in `doRunFromMain'
250	from Main.java:258:in `internalRun'
251	from Main.java:224:in `run'
252	from Main.java:208:in `run'
253	from Main.java:188:in `main'
254
255Done. Build script exited with: 1
ae9de23
Commits on Aug 15, 2012
@Jacobkg Jacobkg Fix for #188. Add mention of debug logging configuration option to un…
…handled request error message. Also added it to the no_cassette.feature.
a683b67
@myronmarston Update changelog and readme.
b93fdcd
@myronmarston Fix failing specs.
- The debug_logger note wasn't included in the error message when there is no cassette.
- The new Faraday release includes my fix for the handling of an empty response by its Net::HTTP adapter.
eb91c8a
@myronmarston Excon 0.16 is out and works fine with VCR.
d748f06
Commits on Aug 18, 2012
@myronmarston My Faraday fix was in 0.8.3 but that got yanked and it's not in 0.8.4.
93aa595
Commits on Sep 05, 2012
@myronmarston Fix excon compatibility.
We need to remove the undesirable options from the connection's instance variable params, and not simply from the params that are passed to #request.

I suspect that there might have been edge case bugs before now with the old
logic.

Fixes #193.
f7beeed
Commits on Sep 06, 2012
@Jacobkg Jacobkg Include scenario outline row in vcr name for scenario outlines
e1465e6
View
2  .travis.yml
@@ -19,6 +19,8 @@ branches:
- travis-testing
matrix:
allow_failures:
+ - rvm: jruby-18mode
- rvm: jruby-19mode
- rvm: rbx-19mode
+ - rvm: rbx-18mode
View
6 CHANGELOG.md
@@ -2,6 +2,12 @@
[Full Changelog](http://github.com/myronmarston/vcr/compare/v2.2.3...v2.2.4)
+Enhancements:
+
+* Include note about `debug_logger` option in error message for
+ unhandled HTTP requests. Thanks to [Jacob Green](https://github.com/Jacobkg)
+ for implementing this.
+
Bug Fixes:
* Fix excon so real requests are made with a connection constructed with
View
4 README.md
@@ -149,11 +149,13 @@ Thanks also to the following people who have contributed patches or helpful sugg
* [Flaviu Simihaian](https://github.com/closedbracket)
* [Gordon Wilson](https://github.com/gordoncww)
* [Ingemar](https://github.com/ingemar)
+* [Jacob Green](https://github.com/Jacobkg)
* [Jeff Pollard](https://github.com/Fluxx)
+* [Jonathan Tron](https://github.com/JonathanTron)
* [Justin Smestad](https://github.com/jsmestad)
* [Karl Baum](https://github.com/kbaum)
* [Michael Lavrisha](https://github.com/vrish88)
-* [Mislav Marohnić](https://github.com/mislav)
+* [Mislav Marohnić](https://github.com/mislav)
* [Nathaniel Bibler](https://github.com/nbibler)
* [Oliver Searle-Barnes](https://github.com/opsb)
* [Omer Rauchwerger](https://github.com/rauchy)
View
4 features/cassettes/no_cassette.feature
@@ -6,6 +6,10 @@ Feature: Error for HTTP request made when no cassette is in use
use. The error is helpful to pinpoint where HTTP requests are
made so you can use a VCR cassette at that point in your code.
+ If you want insight about how VCR attempted to handle the request,
+ you can use the [debug\_logger](../configuration/debug-logging)
+ configuration option to log more details.
+
If you want to allow an HTTP request to proceed as normal, you can
set the [allow\_http\_connections\_when\_no\_cassette](../configuration/allow-http-connections-when-no-cassette)
configuration option or you can temporarily turn VCR off:
View
71 features/test_frameworks/cucumber_scenario_outline.feature
@@ -0,0 +1,71 @@
+Feature: Cucumber with Scenario Outline
+
+ vcr :use_scenario_name works with Scenario Outlines
+
+ @exclude-jruby
+ Scenario: Record HTTP interactions in a scenario by tagging it
+ Given a file named "lib/server.rb" with:
+ """ruby
+ if ENV['WITH_SERVER'] == 'true'
+ start_sinatra_app(:port => 7777) do
+ get('/:path') { "Hello #{params[:path]}" }
+ end
+ end
+ """
+
+ Given a file named "features/support/vcr.rb" with:
+ """ruby
+ require "lib/server"
+ require 'vcr'
+
+ VCR.configure do |c|
+ c.hook_into :fakeweb
+ c.cassette_library_dir = 'features/cassettes'
+ end
+
+ VCR.cucumber_tags do |t|
+ t.tag '@vcr', :use_scenario_name => true
+ end
+ """
+ And a file named "features/step_definitions/steps.rb" with:
+ """ruby
+ require 'net/http'
+
+ When /^a request is made to "([^"]*)"$/ do |url|
+ @response = Net::HTTP.get_response(URI.parse(url))
+ end
+
+ When /^(.*) within a cassette named "([^"]*)"$/ do |step, cassette_name|
+ VCR.use_cassette(cassette_name) { When step }
+ end
+
+ Then /^the response should be "([^"]*)"$/ do |expected_response|
+ @response.body.should == expected_response
+ end
+ """
+ And a file named "features/vcr_example.feature" with:
+ """
+ Feature: VCR example
+
+ Note: Cucumber treats the pre-amble as part of the feature name. When
+ using the :use_scenario_name option, VCR will only use the first line
+ of the feature name as the directory for the cassette.
+
+ @vcr
+ Scenario Outline: scenario outline
+ When a request is made to "http://localhost:7777/localhost_request_1"
+ Then the response should be "Hello localhost_request_1"
+ Examples:
+ | key | value |
+ | foo | bar |
+ """
+ And the directory "features/cassettes" does not exist
+ When I run `cucumber WITH_SERVER=true features/vcr_example.feature`
+ Then it should pass with "1 scenario (1 passed)"
+ And the file "features/cassettes/VCR_example/scenario_outline/_foo_bar_.yml" should contain "Hello localhost_request_1"
+
+ # Run again without the server; we'll get the same responses because VCR
+ # will replay the recorded responses.
+ When I run `cucumber features/vcr_example.feature`
+ Then it should pass with "1 scenario (1 passed)"
+ And the file "features/cassettes/VCR_example/scenario_outline/_foo_bar_.yml" should contain "Hello localhost_request_1"
View
11 lib/vcr/errors.rb
@@ -183,6 +183,13 @@ def format_foot_note(url, index)
"change your :match_requests_on cassette option to be more lenient",
"or use a custom request matcher to allow it to match"],
"https://www.relishapp.com/myronmarston/vcr/v/%s/docs/request-matching"
+ ],
+
+ :try_debug_logger => [
+ ["If you're surprised VCR is raising this error",
+ "and want insight about how VCR attempted to handle the request,",
+ "you can use the debug_logger configuraiton option to log more details"],
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/configuration/debug-logging"
]
}
@@ -196,7 +203,7 @@ def suggestion_for(key)
def suggestions
return no_cassette_suggestions unless cassette = VCR.current_cassette
- [:use_new_episodes, :ignore_request].tap do |suggestions|
+ [:try_debug_logger, :use_new_episodes, :ignore_request].tap do |suggestions|
suggestions.push(*record_mode_suggestion)
suggestions << :allow_playback_repeats if cassette.http_interactions.has_used_interaction_matching?(request)
suggestions.map! { |k| suggestion_for(k) }
@@ -205,7 +212,7 @@ def suggestions
end
def no_cassette_suggestions
- [:use_a_cassette, :allow_http_connections_when_no_cassette, :ignore_request].map do |key|
+ [:try_debug_logger, :use_a_cassette, :allow_http_connections_when_no_cassette, :ignore_request].map do |key|
suggestion_for(key)
end
end
View
22 lib/vcr/library_hooks/excon.rb
@@ -2,7 +2,7 @@
require 'vcr/request_handler'
require 'excon'
-VCR::VersionChecker.new('Excon', Excon::VERSION, '0.9.6', '0.15').check_version!
+VCR::VersionChecker.new('Excon', Excon::VERSION, '0.9.6', '0.16').check_version!
module VCR
class LibraryHooks
@@ -46,22 +46,30 @@ def response_from_excon_error(error)
end
end
+ PARAMS_TO_DELETE = [:expects, :idempotent,
+ :instrumentor_name, :instrumentor,
+ :response_block, :request_block]
+
def real_request_params
# Excon supports a variety of options that affect how it handles failure
# and retry; we don't want to use any options here--we just want to get
# a raw response, and then the main request (with :mock => true) can
# handle failure/retry on its own with its set options.
- params.merge(:mock => false, :retry_limit => 0).tap do |p|
- [:expects, :idempotent, :instrumentor_name, :instrumentor, :response_block, :request_block].each do |key|
- p.delete(key)
- end
- end
+ scrub_params_from params.merge(:mock => false, :retry_limit => 0)
end
def new_connection
# Ensure the connection is constructed with the exact same args
# that the orginal connection was constructed with.
- ::Excon::Connection.new(*params.fetch(:__construction_args))
+ *args, options = params.fetch(:__construction_args)
+ options = scrub_params_from(options) if options.is_a?(Hash)
+ ::Excon::Connection.new(*args, options)
+ end
+
+ def scrub_params_from(hash)
+ hash = hash.dup
+ PARAMS_TO_DELETE.each { |key| hash.delete(key) }
+ hash
end
def perform_real_request
View
2  lib/vcr/library_hooks/typhoeus.rb
@@ -2,7 +2,7 @@
require 'vcr/request_handler'
require 'typhoeus'
-VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.3.2', '0.3').check_version!
+VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.3.2', '0.4').check_version!
module VCR
class LibraryHooks
View
6 lib/vcr/test_frameworks/cucumber.rb
@@ -40,7 +40,11 @@ def tags(*tag_names)
options = original_options.dup
cassette_name = if options.delete(:use_scenario_name)
- "#{scenario.feature.name.split("\n").first}/#{scenario.name}"
+ feature = scenario.respond_to?(:scenario_outline) ? scenario.scenario_outline.feature : scenario.feature
+ file_name = feature.name.split("\n").first
+ file_name << "/#{scenario.scenario_outline.name}" if scenario.respond_to?(:scenario_outline)
+ file_name << "/#{scenario.name}"
+ file_name
else
"cucumber_tags/#{tag_name.gsub(/\A@/, '')}"
end
View
2  spec/support/shared_example_groups/hook_into_http_library.rb
@@ -56,7 +56,7 @@ def self.test_record_and_playback(description, query)
test_record_and_playback "with a complex escaped query param", "q=#{CGI.escape("A&(! 234k !@ kasdj232\#$ kjw35")}"
it 'plays back an empty body response exactly as it was recorded (e.g. nil vs empty string)' do
- pending "awaiting an external fix", :if => library.gsub('_', '/').include?('net/http') do
+ pending "awaiting an external fix", :if => library.gsub('_', '/').include?('net/http') && library_hook_name != :webmock do
get_body = lambda do
VCR.use_cassette('empty_body', :record => :once) do
get_body_object make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/204")
View
10 spec/vcr/errors_spec.rb
@@ -42,6 +42,10 @@ def request_with(values)
it 'does not double-insert the asterisks for the bullet points' do
message.should_not match(/\s+\*\s+\*/)
end
+
+ it 'mentions the debug logging configuration option' do
+ message.should include('debug_logger')
+ end
end
context 'when there is a current cassette' do
@@ -122,6 +126,12 @@ def request_with(values)
message.should include('2 HTTP interactions ')
end
end
+
+ it 'mentions the debug logging configuration option' do
+ VCR.use_cassette('example', :record => :new_episodes) do
+ message.should include('debug_logger')
+ end
+ end
end
end
end
View
9 spec/vcr/test_frameworks/cucumber_spec.rb
@@ -61,6 +61,15 @@ def test_tag(cassette_attribute, tag, expected_value, scenario=current_scenario)
test_tag(:name, 'tag1', 'My feature name/My scenario name')
end
+ it "makes a unique name for each element of scenario outline" do
+ subject.send(tag_method, 'tag1', :use_scenario_name => true)
+
+ scenario_with_outline = stub(:name => "My row name",
+ :scenario_outline => stub(:feature => stub(:name => "My feature name\nThe preamble text is not included"),
+ :name => "My scenario outline name"))
+ test_tag(:name, 'tag1', 'My feature name/My scenario outline name/My row name', scenario_with_outline)
+ end
+
it 'does not pass :use_scenario_name along the given options to the cassette' do
subject.send(tag_method, 'tag1', :use_scenario_name => true)
View
4 vcr.gemspec
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'fakeweb', '~> 1.3.0'
s.add_development_dependency 'webmock', '~> 1.8.3'
- s.add_development_dependency 'faraday', '~> 0.8.0.rc2'
+ s.add_development_dependency 'faraday', '~> 0.8'
s.add_development_dependency 'httpclient', '~> 2.2'
s.add_development_dependency 'excon', '>= 0.11.0', '< 1.0'
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'patron', '~> 0.4.15'
s.add_development_dependency 'em-http-request', '~> 1.0.2'
s.add_development_dependency 'curb', '~> 0.8.0'
- s.add_development_dependency 'typhoeus', '~> 0.3.3'
+ s.add_development_dependency 'typhoeus', '>= 0.3.3', '< 0.5.0'
s.add_development_dependency 'yajl-ruby', '~> 1.1.0'
end
end

No commit comments for this range

Something went wrong with that request. Please try again.