From 0c2e64184f79405e4a00119541ed633d7d0ef675 Mon Sep 17 00:00:00 2001 From: Howard Miller <3620291+h-m-m@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:12:58 -0400 Subject: [PATCH 1/2] Add rubocop and clean up some code items --- .rubocop.yml | 65 +++++++++++++++++++++++++++ Gemfile | 11 +++-- Gemfile.lock | 32 +++++++++++++ _config.yml | 3 ++ _plugins/content_code.rb | 36 ++++++++++----- _plugins/content_typography.rb | 6 ++- _plugins/copy_to_destination.rb | 4 +- _plugins/pretty_jsonify.rb | 8 ++-- _plugins/yaml_content_disposition.rb | 4 +- scripts/htmlproofer | 5 ++- spec/capybara_helper.rb | 2 + spec/integration/accordion_js_spec.rb | 2 + spec/page.md_spec.rb | 6 ++- spec/risc.json_spec.rb | 6 ++- spec/spec_helper.rb | 7 ++- spec/support/matchers.rb | 8 ++-- 16 files changed, 168 insertions(+), 37 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..41f6f2e6 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,65 @@ +# The behavior of RuboCop can be controlled via the .rubocop.yml +# configuration file. It makes it possible to enable/disable +# certain cops (checks) and to alter their behavior if they accept +# any parameters. The file can be placed either in your home +# directory or in some project directory. +# +# RuboCop will start looking for the configuration file in the directory +# where the inspected file is and continue its way up to the root directory. +# +# See https://docs.rubocop.org/rubocop/configuration + +plugins: +- rubocop-capybara +- rubocop-rspec + +AllCops: + NewCops: enable + +# Conveniences because we're using Jekyll + +RSpec/DescribeClass: + Enabled: false + +Style/Documentation: + Enabled: false + +RSpec/ExampleLength: + Max: 15 + +# end Jekyl-specific choices + +# Settings copied over from team preferences for Partner Portal + +RSpec/NotToNot: + EnforcedStyle: to_not + +Capybara/NegationMatcher: + EnforcedStyle: not_to + +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +RSpec/ExpectChange: + # A couple people expressed a preference for block + EnforcedStyle: block + +Naming/RescuedExceptionsVariableName: + PreferredName: err + +Style/HashSyntax: + EnforcedShorthandSyntax: consistent + +Layout/DotPosition: + EnforcedStyle: leading + +Layout/MultilineMethodCallIndentation: + Enabled: false + +Layout/FirstArgumentIndentation: + Enabled: false + +RSpec/MultipleExpectations: + Enabled: false + +# End team settings from Partner Portal \ No newline at end of file diff --git a/Gemfile b/Gemfile index ecdd3a92..1b6a9f37 100644 --- a/Gemfile +++ b/Gemfile @@ -1,23 +1,28 @@ +# frozen_string_literal: true + source 'https://rubygems.org' ruby File.read('.ruby-version').strip gem 'jekyll', '~> 4.3.0' -gem 'jekyll-sass-converter', '~> 3.0.0' -gem 'kramdown-parser-gfm', '~> 1.0' gem 'jekyll-redirect-from' +gem 'jekyll-sass-converter', '~> 3.0.0' gem 'jekyll-sitemap' +gem 'kramdown-parser-gfm', '~> 1.0' group :development, :test do gem 'pry-byebug' + gem 'rubocop', require: false + gem 'rubocop-capybara', require: false + gem 'rubocop-rspec', require: false end group :test do gem 'capybara' gem 'html-proofer', '~> 4.0' gem 'nokogiri', '>= 1.10.5' - gem 'rackup' # required for `Capybara.server = :webrick` gem 'rack-jekyll' + gem 'rackup' # required for `Capybara.server = :webrick` gem 'rspec' gem 'rspec_junit_formatter', require: false gem 'selenium-webdriver' diff --git a/Gemfile.lock b/Gemfile.lock index 9543334d..b14b8f11 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ GEM specs: addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) + ast (2.4.3) base64 (0.3.0) bigdecimal (3.1.8) byebug (12.0.0) @@ -66,10 +67,13 @@ GEM jekyll (>= 3.7, < 5.0) jekyll-watch (2.2.1) listen (~> 3.0) + json (2.12.2) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) liquid (4.0.4) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) @@ -84,8 +88,12 @@ GEM mini_portile2 (~> 2.8.2) racc (~> 1.4) parallel (1.26.3) + parser (3.3.8.0) + ast (~> 2.4.1) + racc pathutil (0.16.2) forwardable-extended (~> 2.6) + prism (1.4.0) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -127,6 +135,27 @@ GEM rspec-support (3.13.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) + rubocop (1.76.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.45.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-capybara (2.22.1) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-rspec (3.6.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + ruby-progressbar (1.13.0) rubyzip (2.4.1) safe_yaml (1.0.5) sass-embedded (1.80.6) @@ -167,6 +196,9 @@ DEPENDENCIES rackup rspec rspec_junit_formatter + rubocop + rubocop-capybara + rubocop-rspec selenium-webdriver RUBY VERSION diff --git a/_config.yml b/_config.yml index 3fcb5142..b4e72b98 100644 --- a/_config.yml +++ b/_config.yml @@ -44,10 +44,13 @@ exclude: - .sass-cache/ - .jekyll-cache/ - assets/scss + - bin - gemfiles/ - Gemfile - Gemfile.lock - node_modules/ + - scripts + - spec - vendor/bundle/ - vendor/cache/ - vendor/gems/ diff --git a/_plugins/content_code.rb b/_plugins/content_code.rb index 32be65ee..b037e4f5 100644 --- a/_plugins/content_code.rb +++ b/_plugins/content_code.rb @@ -1,25 +1,37 @@ +# frozen_string_literal: true + require 'rouge' # Include tabindex for accessibility reasons # See: https://github.com/rouge-ruby/rouge?tab=readme-ov-file#formatters -class Rouge::Formatters::HTMLPygmentsA11y < Rouge::Formatters::HTMLPygments - def stream(tokens, &b) - yield %(
)
-    @inner.stream(tokens, &b)
-    yield "
" +module Rouge + module Formatters + class HTMLPygmentsA11y < Rouge::Formatters::HTMLPygments + def stream(tokens, &) + yield %(
)
+        @inner.stream(tokens, &)
+        yield '
' + end + end end end -class Rouge::Formatters::HTMLLegacyA11y < Rouge::Formatters::HTMLLegacy - def initialize(opts={}) - @formatter = opts[:inline_theme] ? Rouge::Formatters::HTMLInline.new(opts[:inline_theme]) - : Rouge::Formatters::HTML.new +module Rouge + module Formatters + class HTMLLegacyA11y < Rouge::Formatters::HTMLLegacy + def initialize(opts = {}) # rubocop:disable Lint/MissingSuper + @formatter = if opts[:inline_theme] + Rouge::Formatters::HTMLInline.new(opts[:inline_theme]) + else + Rouge::Formatters::HTML.new + end + @formatter = Rouge::Formatters::HTMLTable.new(@formatter, opts) if opts[:line_numbers] - @formatter = Rouge::Formatters::HTMLTable.new(@formatter, opts) if opts[:line_numbers] + return unless opts.fetch(:wrap, true) - if opts.fetch(:wrap, true) - @formatter = Rouge::Formatters::HTMLPygmentsA11y.new(@formatter, opts.fetch(:css_class, 'codehilite')) + @formatter = Rouge::Formatters::HTMLPygmentsA11y.new(@formatter, opts.fetch(:css_class, 'codehilite')) + end end end end diff --git a/_plugins/content_typography.rb b/_plugins/content_typography.rb index 0258ca4a..c93d47cd 100644 --- a/_plugins/content_typography.rb +++ b/_plugins/content_typography.rb @@ -1,10 +1,13 @@ +# frozen_string_literal: true + module Kramdown module Parser class Kramdown + # rubocop:disable Naming/MethodParameterName prepend(Module.new do def add_link(el, *args) add_link_class!(el) if el.type == :a - super(el, *args) + super end def parse_autolink @@ -17,6 +20,7 @@ def add_link_class!(el) el.attr['class'] = [*el.attr['class'], 'usa-link'].join(' ') end end) + # rubocop:enable Naming/MethodParameterName end end end diff --git a/_plugins/copy_to_destination.rb b/_plugins/copy_to_destination.rb index a0f3349a..fd558eb7 100644 --- a/_plugins/copy_to_destination.rb +++ b/_plugins/copy_to_destination.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + module Jekyll module CopyToDestination class CopyGenerator < Generator - def generate(site) + def generate(site) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength folders = site.config['copy_to_destination'] || [] static_files = folders.map do |relative_path| diff --git a/_plugins/pretty_jsonify.rb b/_plugins/pretty_jsonify.rb index 48fbf122..804ac6af 100644 --- a/_plugins/pretty_jsonify.rb +++ b/_plugins/pretty_jsonify.rb @@ -1,13 +1,11 @@ +# frozen_string_literal: true + require 'json' module LoginGov module PrettyJsonify def pretty_jsonify(input) - json = if input.kind_of?(String) - JSON.parse(input) - else - json - end + json = JSON.parse(input) if input.is_a?(String) JSON.pretty_generate(json) end diff --git a/_plugins/yaml_content_disposition.rb b/_plugins/yaml_content_disposition.rb index 09043f59..93a4eb4b 100644 --- a/_plugins/yaml_content_disposition.rb +++ b/_plugins/yaml_content_disposition.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'webrick' module Jekyll @@ -5,7 +7,7 @@ module Commands class Serve class Servlet < WEBrick::HTTPServlet::FileHandler prepend(Module.new do - def do_GET(req, res) + def do_GET(req, res) # rubocop:disable Naming/MethodName res.header.merge!('Content-Disposition' => 'attachment') if req.path.end_with?('.yml') super end diff --git a/scripts/htmlproofer b/scripts/htmlproofer index d976fe64..758ceeac 100755 --- a/scripts/htmlproofer +++ b/scripts/htmlproofer @@ -1,4 +1,6 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # Run HTMLProofer via Ruby so we can do advanced things like ignore bad peer certificates which turn # up in external links. require 'html-proofer' @@ -22,7 +24,7 @@ proofer_options.merge!( typhoeus: { ssl_verifypeer: false, ssl_verifyhost: 0, - followlocation: false, + followlocation: false }, swap_urls: { "http://localhost:#{site_config['port']}" => 'https://developers.login.gov' @@ -39,7 +41,6 @@ proofer.before_request do |request| # Some URLs behave differently if `accept-language` header is not included. Remove this in the # future if it's no longer needed. request.options[:headers]['Accept-Language'] = '*' - end proofer.run diff --git a/spec/capybara_helper.rb b/spec/capybara_helper.rb index c647efae..04946feb 100644 --- a/spec/capybara_helper.rb +++ b/spec/capybara_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'capybara/rspec' require 'rack/jekyll' diff --git a/spec/integration/accordion_js_spec.rb b/spec/integration/accordion_js_spec.rb index 086e4b34..6ccde3f0 100644 --- a/spec/integration/accordion_js_spec.rb +++ b/spec/integration/accordion_js_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'capybara_helper' require 'pry-byebug' diff --git a/spec/page.md_spec.rb b/spec/page.md_spec.rb index bc7bdb18..2eb6ef19 100644 --- a/spec/page.md_spec.rb +++ b/spec/page.md_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' def redirect_page?(path) @@ -6,7 +8,7 @@ def redirect_page?(path) RSpec.describe 'all pages' do files = Dir.glob('_site/**/*.html') - files.reject! {|path| redirect_page?(path) } + files.reject! { |path| redirect_page?(path) } files.each do |page| describe page do let(:doc) { Nokogiri::HTML(File.new(page.to_s)) } @@ -24,7 +26,7 @@ def redirect_page?(path) expect(doc.to_s).to include('https://www.googletagmanager.com/gtag/js') end - it 'does not include markdown markup in description meta tags', aggregate_failures: true do + it 'does not include markdown markup in description meta tags', :aggregate_failures do description = doc.at_css('meta[name=description]') expect(description[:content]).to_not(include('](')) if description diff --git a/spec/risc.json_spec.rb b/spec/risc.json_spec.rb index 66182a26..b45ade31 100644 --- a/spec/risc.json_spec.rb +++ b/spec/risc.json_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'json' @@ -5,7 +7,7 @@ let(:json) { JSON.parse(File.read('_site/data/risc.json')) } it 'is is an array of supported_events' do - expect(json).to be + expect(json).to be_any expect(json['supported_events']).to be_a(Array) end -end \ No newline at end of file +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 31ee63c1..fd48f052 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,11 +1,10 @@ +# frozen_string_literal: true + require 'rspec' require 'pathname' require 'nokogiri' -require 'set' require 'uri' Dir['spec/support/**.rb'].each { |f| require File.expand_path(f) } -RSpec.configure do |config| - config.disable_monkey_patching! -end +RSpec.configure(&:disable_monkey_patching!) diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 77c62faa..8e2be56d 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec::Matchers.define :open_external_links_in_new_window do missing_target_blank = [] @@ -5,7 +7,7 @@ doc = actual doc.css('a[href^=http]').each do |a| - next if !a.ancestors('nav').empty? + next unless a.ancestors('nav').empty? missing_target_blank << a[:href] if a[:target] != '_blank' end @@ -59,9 +61,7 @@ ids = Set.new doc.css('[id]').each do |tag| - if ids.include?(tag[:id]) - duplicate_ids << tag[:id] - end + duplicate_ids << tag[:id] if ids.include?(tag[:id]) ids << tag[:id] end From 7ef75d0287022d50c8d1dc36233610ae6dde8443 Mon Sep 17 00:00:00 2001 From: Howard Miller <3620291+h-m-m@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:32:53 -0400 Subject: [PATCH 2/2] Bump Ruby version to 3.4 --- .rubocop.yml | 7 ++++++- .ruby-version | 2 +- Gemfile | 3 +-- Gemfile.lock | 4 +++- _plugins/content_code.rb | 2 -- _plugins/content_typography.rb | 2 -- _plugins/copy_to_destination.rb | 2 -- _plugins/pretty_jsonify.rb | 2 -- _plugins/yaml_content_disposition.rb | 2 -- scripts/htmlproofer | 2 -- spec/capybara_helper.rb | 2 -- spec/integration/accordion_js_spec.rb | 2 -- spec/page.md_spec.rb | 2 -- spec/risc.json_spec.rb | 2 -- spec/spec_helper.rb | 2 -- spec/support/matchers.rb | 2 -- 16 files changed, 11 insertions(+), 29 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 41f6f2e6..a99f6f29 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -62,4 +62,9 @@ Layout/FirstArgumentIndentation: RSpec/MultipleExpectations: Enabled: false -# End team settings from Partner Portal \ No newline at end of file +# End team settings from Partner Portal + +# Ruby 3.4 doesn't need this + +Style/FrozenStringLiteralComment: + EnforcedStyle: never diff --git a/.ruby-version b/.ruby-version index 5ae69bd5..47b322c9 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.5 +3.4.1 diff --git a/Gemfile b/Gemfile index 1b6a9f37..d3687b06 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,8 @@ -# frozen_string_literal: true - source 'https://rubygems.org' ruby File.read('.ruby-version').strip +gem 'csv' gem 'jekyll', '~> 4.3.0' gem 'jekyll-redirect-from' gem 'jekyll-sass-converter', '~> 3.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index b14b8f11..fe2ff0ad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,6 +19,7 @@ GEM coderay (1.1.3) colorator (1.1.0) concurrent-ruby (1.3.4) + csv (3.3.5) diff-lcs (1.5.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) @@ -184,6 +185,7 @@ PLATFORMS DEPENDENCIES capybara + csv html-proofer (~> 4.0) jekyll (~> 4.3.0) jekyll-redirect-from @@ -202,7 +204,7 @@ DEPENDENCIES selenium-webdriver RUBY VERSION - ruby 3.2.5p208 + ruby 3.4.1p0 BUNDLED WITH 2.6.9 diff --git a/_plugins/content_code.rb b/_plugins/content_code.rb index b037e4f5..be4185bf 100644 --- a/_plugins/content_code.rb +++ b/_plugins/content_code.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'rouge' # Include tabindex for accessibility reasons diff --git a/_plugins/content_typography.rb b/_plugins/content_typography.rb index c93d47cd..6d5be4fc 100644 --- a/_plugins/content_typography.rb +++ b/_plugins/content_typography.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - module Kramdown module Parser class Kramdown diff --git a/_plugins/copy_to_destination.rb b/_plugins/copy_to_destination.rb index fd558eb7..c1a24cfe 100644 --- a/_plugins/copy_to_destination.rb +++ b/_plugins/copy_to_destination.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - module Jekyll module CopyToDestination class CopyGenerator < Generator diff --git a/_plugins/pretty_jsonify.rb b/_plugins/pretty_jsonify.rb index 804ac6af..746525e7 100644 --- a/_plugins/pretty_jsonify.rb +++ b/_plugins/pretty_jsonify.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'json' module LoginGov diff --git a/_plugins/yaml_content_disposition.rb b/_plugins/yaml_content_disposition.rb index 93a4eb4b..81dcdfbb 100644 --- a/_plugins/yaml_content_disposition.rb +++ b/_plugins/yaml_content_disposition.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'webrick' module Jekyll diff --git a/scripts/htmlproofer b/scripts/htmlproofer index 758ceeac..8bdf3ef8 100755 --- a/scripts/htmlproofer +++ b/scripts/htmlproofer @@ -1,6 +1,4 @@ #!/usr/bin/env ruby -# frozen_string_literal: true - # Run HTMLProofer via Ruby so we can do advanced things like ignore bad peer certificates which turn # up in external links. require 'html-proofer' diff --git a/spec/capybara_helper.rb b/spec/capybara_helper.rb index 04946feb..c647efae 100644 --- a/spec/capybara_helper.rb +++ b/spec/capybara_helper.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'spec_helper' require 'capybara/rspec' require 'rack/jekyll' diff --git a/spec/integration/accordion_js_spec.rb b/spec/integration/accordion_js_spec.rb index 6ccde3f0..086e4b34 100644 --- a/spec/integration/accordion_js_spec.rb +++ b/spec/integration/accordion_js_spec.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'capybara_helper' require 'pry-byebug' diff --git a/spec/page.md_spec.rb b/spec/page.md_spec.rb index 2eb6ef19..e1e94aad 100644 --- a/spec/page.md_spec.rb +++ b/spec/page.md_spec.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'spec_helper' def redirect_page?(path) diff --git a/spec/risc.json_spec.rb b/spec/risc.json_spec.rb index b45ade31..db37a879 100644 --- a/spec/risc.json_spec.rb +++ b/spec/risc.json_spec.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'spec_helper' require 'json' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fd48f052..d561333a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'rspec' require 'pathname' require 'nokogiri' diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 8e2be56d..3f47db32 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - RSpec::Matchers.define :open_external_links_in_new_window do missing_target_blank = []