From 09b2acb649d23ec3d2c6dfdc6db47d0121b5998c Mon Sep 17 00:00:00 2001 From: PeterHattyar Date: Thu, 15 Feb 2024 12:18:54 +0000 Subject: [PATCH 1/2] use recommended Rspec defaults --- .gitignore | 1 + spec/spec_helper.rb | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f05cf8c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/spec/examples.txt diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 23a62aa..4a703c5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -46,9 +46,6 @@ # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin # This allows you to limit a spec run to individual examples or groups # you care about by tagging them with `:focus` metadata. When nothing # is tagged with `:focus`, all examples get run. RSpec also provides @@ -96,5 +93,4 @@ # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed -=end end From dbf26c4c0c5f8e4d402f1a790c716f6ccc4d4882 Mon Sep 17 00:00:00 2001 From: PeterHattyar Date: Thu, 15 Feb 2024 12:03:35 +0000 Subject: [PATCH 2/2] add rubocop & correct offenses --- .github/workflows/ci.yml | 7 ++-- .rubocop.yml | 18 ++++++++++ Gemfile | 11 +++--- Gemfile.lock | 69 ++++++++++++++++++++++++++++++++++++ Rakefile | 3 +- lib/version_checker.rb | 16 ++++----- spec/spec_helper.rb | 2 +- spec/version_checker_spec.rb | 30 +++++++++------- 8 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 .rubocop.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e0ffff..0b304d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,6 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 - - name: Install dependencies and run Rake - run: | - bundle install - bundle exec rspec + - run: bundle install + - run: bundle exec rspec + - run: bundle exec rubocop diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..f001947 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,18 @@ +inherit_gem: + rubocop-govuk: + - config/default.yml + - config/rspec.yml + +inherit_mode: + merge: + - Exclude + +# ************************************************************** +# TRY NOT TO ADD OVERRIDES IN THIS FILE +# +# This repo is configured to follow the RuboCop GOV.UK styleguide. +# Any rules you override here will cause this repo to diverge from +# the way we write code in all other GOV.UK repos. +# +# See https://github.com/alphagov/rubocop-govuk/blob/main/CONTRIBUTING.md +# ************************************************************** diff --git a/Gemfile b/Gemfile index fb4e025..fd21c6a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" -gem 'octokit' -gem 'webmock' -gem 'rake' +gem "octokit" +gem "rake" +gem "webmock" group :development, :test do - gem 'rspec' + gem "rspec" + gem "rubocop-govuk", require: false end diff --git a/Gemfile.lock b/Gemfile.lock index bfa0956..d3a2979 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,23 +1,53 @@ GEM remote: https://rubygems.org/ specs: + activesupport (7.1.3) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) + ast (2.4.2) base64 (0.2.0) + bigdecimal (3.1.6) + concurrent-ruby (1.2.3) + connection_pool (2.4.1) crack (0.4.5) rexml diff-lcs (1.5.0) + drb (2.2.0) + ruby2_keywords faraday (2.7.11) base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) hashdiff (1.0.1) + i18n (1.14.1) + concurrent-ruby (~> 1.0) + json (2.7.1) + language_server-protocol (3.17.0.3) + minitest (5.22.2) + mutex_m (0.2.0) octokit (8.0.0) faraday (>= 1, < 3) sawyer (~> 0.9) + parallel (1.24.0) + parser (3.3.0.5) + ast (~> 2.4.1) + racc public_suffix (5.0.3) + racc (1.7.3) + rack (3.0.9) + rainbow (3.1.1) rake (13.1.0) + regexp_parser (2.9.0) rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -32,10 +62,48 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-support (3.12.1) + rubocop (1.60.2) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.30.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.20.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.25.1) + rubocop (~> 1.41) + rubocop-govuk (4.14.0) + rubocop (= 1.60.2) + rubocop-ast (= 1.30.0) + rubocop-rails (= 2.23.1) + rubocop-rake (= 0.6.0) + rubocop-rspec (= 2.26.1) + rubocop-rails (2.23.1) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) + rubocop-rake (0.6.0) + rubocop (~> 1.0) + rubocop-rspec (2.26.1) + rubocop (~> 1.40) + rubocop-capybara (~> 2.17) + rubocop-factory_bot (~> 2.22) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) @@ -48,6 +116,7 @@ DEPENDENCIES octokit rake rspec + rubocop-govuk webmock BUNDLED WITH diff --git a/Rakefile b/Rakefile index 248c2d5..7b062d5 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,8 @@ -require './lib/version_checker' +require "./lib/version_checker" task default: %w[gem_release_alert] +desc "Checks for GOV.UK gems which have unreleased changes" task :gem_release_alert do VersionChecker.new.print_version_discrepancies end diff --git a/lib/version_checker.rb b/lib/version_checker.rb index 081627d..a29abc3 100644 --- a/lib/version_checker.rb +++ b/lib/version_checker.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'uri' -require 'net/http' -require 'json' -require 'octokit' +require "uri" +require "net/http" +require "json" +require "octokit" class HttpError < RuntimeError end @@ -13,14 +13,14 @@ class VersionChecker def print_version_discrepancies all_govuk_gems.group_by { |gem| gem["team"] }.each do |team, gems| - message = gems.filter_map do |gem| + message = gems.filter_map { |gem| repo_name = gem["app_name"] rubygems_version = fetch_rubygems_version(repo_name) if !rubygems_version.nil? && - files_changed_since_tag(repo_name, "v" + rubygems_version).any? { |path| path_built_into_gem?(path) } + files_changed_since_tag(repo_name, "v#{rubygems_version}").any? { |path| path_built_into_gem?(path) } " #{repo_name} has unreleased changes since v#{rubygems_version}" end - end.join("\n") + }.join("\n") puts team puts message @@ -40,7 +40,7 @@ def fetch_rubygems_version(gem_name) uri = URI("https://rubygems.org/api/v1/gems/#{gem_name}.json") res = Net::HTTP.get_response(uri) - JSON.parse(res.body)['version'] if res.is_a?(Net::HTTPSuccess) + JSON.parse(res.body)["version"] if res.is_a?(Net::HTTPSuccess) end def files_changed_since_tag(repo, tag) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a703c5..cc85d02 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -require 'webmock/rspec' +require "webmock/rspec" # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. diff --git a/spec/version_checker_spec.rb b/spec/version_checker_spec.rb index af9a002..84e7cb4 100644 --- a/spec/version_checker_spec.rb +++ b/spec/version_checker_spec.rb @@ -1,48 +1,52 @@ # frozen_string_literal: true -require 'version_checker' -require 'base64' +require "version_checker" +require "base64" RSpec.describe VersionChecker do - it 'fetches version number of a gem from rubygems' do - stub_rubygems_call('6.0.1') + subject(:version_checker) { described_class.new } - expect(subject.fetch_rubygems_version('example')).to eq('6.0.1') + it "fetches version number of a gem from rubygems" do + stub_rubygems_call("6.0.1") + + expect(version_checker.fetch_rubygems_version("example")).to eq("6.0.1") end it "detects when there are no files changed since the last release that are built into the gem" do stub_devdocs_call - stub_rubygems_call('1.2.3') + stub_rubygems_call("1.2.3") stub_files_changed_since_tag(["README.md"]) - expect { subject.print_version_discrepancies }.to output("#platform-security-reliability-team\n\n").to_stdout + expect { version_checker.print_version_discrepancies }.to output("#platform-security-reliability-team\n\n").to_stdout end it "detects when there are files changed since the last release that are built into the gem" do stub_devdocs_call - stub_rubygems_call('1.2.2') + stub_rubygems_call("1.2.2") stub_files_changed_since_tag(["lib/foo.rb"]) - expect { subject.print_version_discrepancies }.to output( - "#platform-security-reliability-team\n example has unreleased changes since v1.2.2\n" + expect { version_checker.print_version_discrepancies }.to output( + "#platform-security-reliability-team\n example has unreleased changes since v1.2.2\n", ).to_stdout end + # rubocop:disable RSpec/SubjectStub def stub_files_changed_since_tag(files) - allow(subject).to receive(:files_changed_since_tag) do + allow(version_checker).to receive(:files_changed_since_tag) do files end end + # rubocop:enable RSpec/SubjectStub def stub_rubygems_call(version) repo = { "version": version } - stub_request(:get, 'https://rubygems.org/api/v1/gems/example.json') + stub_request(:get, "https://rubygems.org/api/v1/gems/example.json") .to_return(status: 200, body: repo.to_json, headers: {}) end def stub_devdocs_call repo = [{ "app_name": "example", "team": "#platform-security-reliability-team" }] - stub_request(:get, 'https://docs.publishing.service.gov.uk/gems.json') + stub_request(:get, "https://docs.publishing.service.gov.uk/gems.json") .to_return(status: 200, body: repo.to_json, headers: {}) end end