diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index 93436de..3c13171 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -3,6 +3,8 @@ on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest + env: + BUNDLE_GEMFILE: gemfiles/rubocop.gemfile steps: - uses: actions/checkout@v7 - name: Set up Ruby diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e9e543..6f4462e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,19 @@ jobs: - "4.0" - "jruby-9.4" - "jruby-10" + gemfile: + - Gemfile + include: + # See https://github.com/dblock/strava-ruby-client/issues/113: json + # 2.x is the version this gem currently supports. json_3 is + # commented out until Faraday's :json middleware supports json >= + # 3.0, since it currently fails (Faraday::ParsingError). + - ruby-version: "3.4" + gemfile: gemfiles/json_2.gemfile + # - ruby-version: "3.4" + # gemfile: gemfiles/json_3.gemfile + env: + BUNDLE_GEMFILE: ${{ matrix.gemfile }} steps: - uses: actions/checkout@v7 - name: Set up Ruby @@ -31,7 +44,7 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: coverage/lcov.info - flag-name: ${{ matrix.ruby-version }} + flag-name: ${{ matrix.gemfile == 'Gemfile' && matrix.ruby-version || format('{0}-{1}', matrix.ruby-version, matrix.gemfile) }} parallel: true integration: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 6f68543..07768c8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ .tool-versions .vscode Gemfile.lock +gemfiles/*.gemfile.lock pkg coverage diff --git a/.rubocop.yml b/.rubocop.yml index eb92522..643c84e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,7 @@ AllCops: NewCops: enable Exclude: - vendor/**/* + - gemfiles/**/* Naming/MethodName: Enabled: false diff --git a/Appraisals b/Appraisals new file mode 100644 index 0000000..f04553b --- /dev/null +++ b/Appraisals @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Tests the gem against the two major json releases that are relevant to +# https://github.com/dblock/strava-ruby-client/issues/113: json < 3.0, where +# JSON.parse accepts a positional options hash (the form Faraday's :json +# response middleware uses), and json >= 3.0, where JSON.parse only accepts +# keyword arguments and Faraday's call raises an ArgumentError. +appraise 'json-2' do + gem 'json', '~> 2.3' +end + +appraise 'json-3' do + gem 'json', '~> 3.0' +end diff --git a/CHANGELOG.md b/CHANGELOG.md index efb2546..36a6601 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 3.1.1 (Next) +* [#113](https://github.com/dblock/strava-ruby-client/issues/113): Adds Appraisals (`json-2`, `json-3`) - [@dblock](https://github.com/dblock). * Your contribution here. ### 3.1.0 (2026/08/29) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ee278c..660f7ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,26 @@ bundle install bundle exec rake ``` +Rubocop uses its own `gemfiles/rubocop.gemfile`, kept separate so its pinned version doesn't constrain the main Gemfile's dependency resolution. + +``` +BUNDLE_GEMFILE=gemfiles/rubocop.gemfile bundle install +BUNDLE_GEMFILE=gemfiles/rubocop.gemfile bundle exec rubocop +``` + +This gem is tested against multiple `json` gem versions using [Appraisal](https://github.com/thoughtbot/appraisal), defined in `Appraisals`. To run the test suite against a specific `json` version, e.g. to reproduce [#113](https://github.com/dblock/strava-ruby-client/issues/113): + +``` +BUNDLE_GEMFILE=gemfiles/json_3.gemfile bundle install +BUNDLE_GEMFILE=gemfiles/json_3.gemfile bundle exec rake spec +``` + +If you add or change a runtime/test dependency in the main `Gemfile`, regenerate the appraisal gemfiles. + +``` +bundle exec appraisal generate +``` + ## Contribute Code ### Obtain a Strava Token diff --git a/Gemfile b/Gemfile index d3f59ce..3bbd50f 100755 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,14 @@ source 'http://rubygems.org' gemspec +# Faraday's :json response middleware is incompatible with json >= 3.0 (see +# https://github.com/dblock/strava-ruby-client/issues/113), so pin json here +# rather than relying on rubocop's own transitive constraint. The `json-3` +# appraisal (see Appraisals) is used to track when this can be removed. +gem 'json', '~> 2.3' + group :development, :test do + gem 'appraisal' gem 'csv' gem 'danger-changelog', '~> 0.8.0' gem 'danger-pr-comment' @@ -17,9 +24,6 @@ group :development, :test do gem 'pry' gem 'rake' gem 'rspec' - gem 'rubocop', '1.68.0' - gem 'rubocop-rake' - gem 'rubocop-rspec' gem 'tcx' gem 'vcr' gem 'webmock' diff --git a/Rakefile b/Rakefile index cd00c82..418ac7d 100644 --- a/Rakefile +++ b/Rakefile @@ -17,7 +17,9 @@ RSpec::Core::RakeTask.new(:'spec:integration') do |spec| spec.pattern = FileList['spec/integration/**/*_spec.rb'] end -require 'rubocop/rake_task' -RuboCop::RakeTask.new +# Rubocop lives in its own Gemfile (gemfiles/rubocop.gemfile), not the main +# Gemfile, so it doesn't constrain dependency resolution there (see +# https://github.com/dblock/strava-ruby-client/issues/113). Run it with +# `BUNDLE_GEMFILE=gemfiles/rubocop.gemfile bundle exec rubocop`. -task default: %i[rubocop spec] +task default: %i[spec] diff --git a/gemfiles/json_2.gemfile b/gemfiles/json_2.gemfile new file mode 100644 index 0000000..f4c3695 --- /dev/null +++ b/gemfiles/json_2.gemfile @@ -0,0 +1,32 @@ +# This file was generated by Appraisal + +source "http://rubygems.org" + +gem "json", "~> 2.3" + +group :development, :test do + gem "appraisal" + gem "csv" + gem "danger-changelog", "~> 0.8.0" + gem "danger-pr-comment" + gem "danger-toc", "~> 0.2.0" + gem "dotenv" + gem "faraday-retry" + gem "gpx" + gem "multi_xml" + gem "polylines" + gem "pry" + gem "rake" + gem "rspec" + gem "tcx" + gem "vcr" + gem "webmock" + gem "webrick", "~> 1.9" +end + +group :test do + gem "simplecov" + gem "simplecov-lcov", require: false +end + +gemspec path: "../" diff --git a/gemfiles/json_3.gemfile b/gemfiles/json_3.gemfile new file mode 100644 index 0000000..503edea --- /dev/null +++ b/gemfiles/json_3.gemfile @@ -0,0 +1,32 @@ +# This file was generated by Appraisal + +source "http://rubygems.org" + +gem "json", "~> 3.0" + +group :development, :test do + gem "appraisal" + gem "csv" + gem "danger-changelog", "~> 0.8.0" + gem "danger-pr-comment" + gem "danger-toc", "~> 0.2.0" + gem "dotenv" + gem "faraday-retry" + gem "gpx" + gem "multi_xml" + gem "polylines" + gem "pry" + gem "rake" + gem "rspec" + gem "tcx" + gem "vcr" + gem "webmock" + gem "webrick", "~> 1.9" +end + +group :test do + gem "simplecov" + gem "simplecov-lcov", require: false +end + +gemspec path: "../" diff --git a/gemfiles/rubocop.gemfile b/gemfiles/rubocop.gemfile new file mode 100644 index 0000000..271c7f3 --- /dev/null +++ b/gemfiles/rubocop.gemfile @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Rubocop is kept in its own Gemfile, separate from the main Gemfile, so that +# its exact pinned version (and its own transitive dependency constraints, +# e.g. on json) don't participate in dependency resolution for the gem's +# runtime/test Gemfile or its Appraisals. See +# https://github.com/dblock/strava-ruby-client/issues/113. + +source 'http://rubygems.org' + +gem 'rubocop', '1.68.0' +gem 'rubocop-rake' +gem 'rubocop-rspec'