diff --git a/.rubocop.yml b/.rubocop.yml
index 8dc2d1c4794cf7563f3a1cd625e7fd43df58a5c1..cff28e11d4fbf85b711e12763f45a885c1cf12b7 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,8 +2,9 @@ require:
   - rubocop-rails
 
 AllCops:
-  TargetRubyVersion: 2.5
+  TargetRubyVersion: 2.6
   NewCops: disable
+  SuggestExtensions: false
   Exclude:
     - 'spec/**/*'
     - 'db/**/*'
@@ -41,6 +42,10 @@ Layout/FirstHashElementIndentation:
 Layout/HashAlignment:
   Enabled: false
 
+Layout/LineLength:
+  AllowURI: true
+  Enabled: false
+
 Layout/SpaceAroundMethodCallOperator:
   Enabled: true
 
@@ -56,6 +61,9 @@ Lint/DuplicateElsifCondition:
 Lint/MixedRegexpCaptureTypes:
   Enabled: true
 
+Lint/NonLocalExitFromIterator:
+  Enabled: false
+
 Lint/RaiseException:
   Enabled: true
 
@@ -93,10 +101,6 @@ Metrics/CyclomaticComplexity:
   Exclude:
     - 'lib/mastodon/*_cli.rb'
 
-Layout/LineLength:
-  AllowURI: true
-  Enabled: false
-
 Metrics/MethodLength:
   CountComments: false
   Max: 65
@@ -108,11 +112,14 @@ Metrics/ModuleLength:
   Max: 200
 
 Metrics/ParameterLists:
-  Max: 5
+  Max: 6
   CountKeywordArgs: true
+  MaxOptionalParameters: 4
 
 Metrics/PerceivedComplexity:
   Max: 25
+  Exclude:
+    - 'lib/mastodon/*_cli.rb'
 
 Naming/MemoizedInstanceVariableName:
   Enabled: false
@@ -166,6 +173,10 @@ Rails/InverseOf:
 Rails/LexicallyScopedActionFilter:
   Enabled: false
 
+Rails/Output:
+  Exclude:
+    - 'lib/mastodon/*_cli.rb'
+
 Rails/OutputSafety:
   Enabled: true
 
@@ -204,6 +215,9 @@ Style/CollectionMethods:
   PreferredMethods:
     find_all: 'select'
 
+Style/CombinableLoops:
+  Enabled: false
+
 Style/Documentation:
   Enabled: false
 
@@ -255,6 +269,9 @@ Style/Lambda:
 Style/MutableConstant:
   Enabled: false
 
+Style/OptionalBooleanParameter:
+  Enabled: false
+
 Style/PercentLiteralDelimiters:
   PreferredDelimiters:
     '%i': '()'
@@ -307,3 +324,7 @@ Style/TrailingCommaInHashLiteral:
 
 Style/UnpackFirst:
   Enabled: false
+
+Style/WordArray:
+  Exclude:
+    - 'app/helpers/languages_helper.rb'
diff --git a/Gemfile b/Gemfile
index ce5e231d06a469d2b4e17d7107b597d5b7707045..ab0d3c49383e1108e4e433976cb130e51d1096e7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -132,7 +132,7 @@ group :development do
   gem 'letter_opener', '~> 1.8'
   gem 'letter_opener_web', '~> 2.0'
   gem 'memory_profiler'
-  gem 'rubocop', '~> 1.30', require: false
+  gem 'rubocop', '~> 1.31', require: false
   gem 'rubocop-rails', '~> 2.15', require: false
   gem 'brakeman', '~> 5.2', require: false
   gem 'bundler-audit', '~> 0.9', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index f68442d43981c83e0584a839fc5040fa9dedf18a..7cd957fd60cbfe0f3b261d318b5710d4205f3dc5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -305,7 +305,7 @@ GEM
     httplog (1.5.0)
       rack (>= 1.0)
       rainbow (>= 2.0.0)
-    i18n (1.10.0)
+    i18n (1.12.0)
       concurrent-ruby (~> 1.0)
     i18n-tasks (1.0.11)
       activesupport (>= 4.0.2)
@@ -396,7 +396,7 @@ GEM
     mime-types-data (3.2022.0105)
     mini_mime (1.1.2)
     mini_portile2 (2.8.0)
-    minitest (5.16.0)
+    minitest (5.16.2)
     msgpack (1.5.2)
     multi_json (1.15.0)
     multipart-post (2.1.1)
@@ -569,7 +569,8 @@ GEM
     rspec-support (3.11.0)
     rspec_junit_formatter (0.5.1)
       rspec-core (>= 2, < 4, != 2.12.0)
-    rubocop (1.30.1)
+    rubocop (1.31.2)
+      json (~> 2.3)
       parallel (~> 1.10)
       parser (>= 3.1.0.0)
       rainbow (>= 2.2.2, < 4.0)
@@ -578,9 +579,9 @@ GEM
       rubocop-ast (>= 1.18.0, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 1.4.0, < 3.0)
-    rubocop-ast (1.18.0)
+    rubocop-ast (1.19.1)
       parser (>= 3.1.1.0)
-    rubocop-rails (2.15.0)
+    rubocop-rails (2.15.2)
       activesupport (>= 4.2.0)
       rack (>= 1.1)
       rubocop (>= 1.7.0, < 2.0)
@@ -678,7 +679,7 @@ GEM
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.8.2)
-    unicode-display_width (2.1.0)
+    unicode-display_width (2.2.0)
     uniform_notifier (1.16.0)
     validate_email (0.1.6)
       activemodel (>= 3.0)
@@ -822,7 +823,7 @@ DEPENDENCIES
   rspec-rails (~> 5.1)
   rspec-sidekiq (~> 3.1)
   rspec_junit_formatter (~> 0.5)
-  rubocop (~> 1.30)
+  rubocop (~> 1.31)
   rubocop-rails (~> 2.15)
   ruby-progressbar (~> 1.11)
   sanitize (~> 6.0)
@@ -848,3 +849,9 @@ DEPENDENCIES
   webpacker (~> 5.4)
   webpush (~> 0.3)
   xorcist (~> 1.1)
+
+RUBY VERSION
+   ruby 3.0.4p208
+
+BUNDLED WITH
+   2.2.33
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 5537cc9b0bd9e47d1b3525c66b55c96f61593ca5..a06754f07357fe34de0b5a16b4eb3e97503b34e6 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -30,7 +30,7 @@ class Api::V1::AccountsController < Api::BaseController
     self.response_body = Oj.dump(response.body)
     self.status        = response.status
   rescue ActiveRecord::RecordInvalid => e
-    render json: ValidationErrorFormatter.new(e, :'account.username' => :username, :'invite_request.text' => :reason).as_json, status: :unprocessable_entity
+    render json: ValidationErrorFormatter.new(e, 'account.username': :username, 'invite_request.text': :reason).as_json, status: :unprocessable_entity
   end
 
   def follow
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index f9a55eb4bd067eaebce36198483e88a0a66a9a53..b3688d67f32ff31d36095d388f277a5cc4f7e5c8 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -122,7 +122,7 @@ class Auth::SessionsController < Devise::SessionsController
     redirect_to new_user_session_path, alert: I18n.t('devise.failure.timeout')
   end
 
-  def set_attempt_session(user)
+  def set_attempt_session(user) # rubocop:disable Naming/AccessorMethodName
     session[:attempt_user_id]         = user.id
     session[:attempt_user_updated_at] = user.updated_at.to_s
   end
diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb
index 102e4b13281ad74a4367a47c68d8178a898057b5..1656dde1bddffccf4e18906c97dc9d552b50f72f 100644
--- a/app/helpers/jsonld_helper.rb
+++ b/app/helpers/jsonld_helper.rb
@@ -112,7 +112,7 @@ module JsonLdHelper
       if value.is_a?(Hash) && compacted_value.is_a?(Hash)
         patch_for_forwarding!(value, compacted_value)
       elsif value.is_a?(Array)
-        compacted_value = [compacted_value] unless compacted_value.is_a?(Array)
+        compacted_value = [compacted_value] unless compacted_value.is_a?(Array) # rubocop:disable Style/ArrayCoercion
         return if value.size != compacted_value.size
 
         compacted[key] = value.zip(compacted_value).map do |v, vc|
@@ -143,7 +143,7 @@ module JsonLdHelper
   def safe_for_forwarding?(original, compacted)
     original.without('@context', 'signature').all? do |key, value|
       compacted_value = compacted[key]
-      return false unless value.class == compacted_value.class
+      return false unless value.class == compacted_value.class # rubocop:disable Style/ClassEqualityComparison
 
       if value.is_a?(Hash)
         safe_for_forwarding?(value, compacted_value)
diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb
index 4077e19bdf0052842e3ceedeb2be8b5b5b72a233..7f60680cb764226d9efb03046a749ddb63fcadea 100644
--- a/app/helpers/languages_helper.rb
+++ b/app/helpers/languages_helper.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-module LanguagesHelper
+module LanguagesHelper # rubocop:disable Metrics/ModuleLength
   ISO_639_1 = {
     aa: ['Afar', 'Afaraf'].freeze,
     ab: ['Abkhaz', 'аҧсуа бызшәа'].freeze,
diff --git a/app/lib/activitypub/case_transform.rb b/app/lib/activitypub/case_transform.rb
index 7f716f86243ef83353d15683273b173a8a72f7f7..d36e01b8f2ec3be8b6ae7f843208147a9fdf1d3e 100644
--- a/app/lib/activitypub/case_transform.rb
+++ b/app/lib/activitypub/case_transform.rb
@@ -13,7 +13,7 @@ module ActivityPub::CaseTransform
       when Symbol then camel_lower(value.to_s).to_sym
       when String
         camel_lower_cache[value] ||= if value.start_with?('_:')
-                                       '_:' + value.gsub(/\A_:/, '').underscore.camelize(:lower)
+                                       "_:#{value.gsub(/\A_:/, '').underscore.camelize(:lower)}"
                                      else
                                        value.underscore.camelize(:lower)
                                      end
diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb
index 194849c23daf3fe82292cfdb341affd25e19dc58..360183dfc41d5ada48187612456dd257276a4cd2 100644
--- a/app/lib/emoji_formatter.rb
+++ b/app/lib/emoji_formatter.rb
@@ -62,7 +62,7 @@ class EmojiFormatter
       end
     end
 
-    result << html[last_index..-1]
+    result << html[last_index..]
 
     result.html_safe # rubocop:disable Rails/OutputSafety
   end
diff --git a/app/lib/extractor.rb b/app/lib/extractor.rb
index aea60dae5b34aad582e6ed31c9120a6483345ac7..41c4443577e6e28fc922c242f6224b5da864bff2 100644
--- a/app/lib/extractor.rb
+++ b/app/lib/extractor.rb
@@ -29,7 +29,7 @@ module Extractor
 
     text.scan(Account::MENTION_RE) do |screen_name, _|
       match_data = $LAST_MATCH_INFO
-      after      = $'
+      after      = Regexp.last_match.post_match
 
       unless Twitter::TwitterText::Regex[:end_mention_match].match?(after)
         _, domain = screen_name.split('@')
@@ -64,7 +64,7 @@ module Extractor
       match_data     = $LAST_MATCH_INFO
       start_position = match_data.char_begin(1) - 1
       end_position   = match_data.char_end(1)
-      after          = $'
+      after          = Regexp.last_match.post_match
 
       if %r{\A://}.match?(after)
         hash_text.match(/(.+)(https?\Z)/) do |matched|
diff --git a/app/lib/redis_configuration.rb b/app/lib/redis_configuration.rb
index e14d6c8b6705c3b75fd10d5cdac6d67e2168f119..1d0714411f9310c7b5345416bcebab2ba17a81e9 100644
--- a/app/lib/redis_configuration.rb
+++ b/app/lib/redis_configuration.rb
@@ -7,8 +7,8 @@ class RedisConfiguration
       @pool = ConnectionPool.new(size: new_pool_size) { new.connection }
     end
 
-    def with
-      pool.with { |redis| yield redis }
+    def with(&block)
+      pool.with(&block)
     end
 
     def pool
diff --git a/app/lib/text_formatter.rb b/app/lib/text_formatter.rb
index 48e2fc2338dcc17713d6851f01fc6c144585bbef..03a695cf833791bce47981f2de792a44f7460dd6 100644
--- a/app/lib/text_formatter.rb
+++ b/app/lib/text_formatter.rb
@@ -64,7 +64,7 @@ class TextFormatter
       indices.last
     end
 
-    result << h(text[last_index..-1])
+    result << h(text[last_index..])
 
     result
   end
@@ -75,8 +75,8 @@ class TextFormatter
 
     prefix      = url.match(URL_PREFIX_REGEX).to_s
     display_url = url[prefix.length, 30]
-    suffix      = url[prefix.length + 30..-1]
-    cutoff      = url[prefix.length..-1].length > 30
+    suffix      = url[prefix.length + 30..]
+    cutoff      = url[prefix.length..].length > 30
 
     <<~HTML.squish
       <a href="#{h(url)}" target="_blank" rel="#{rel.join(' ')}"><span class="invisible">#{h(prefix)}</span><span class="#{cutoff ? 'ellipsis' : ''}">#{h(display_url)}</span><span class="invisible">#{h(suffix)}</span></a>
diff --git a/app/lib/toc_generator.rb b/app/lib/toc_generator.rb
index 0c8f766ca42fdde089afdac7795c3ab5cbf81963..f20b0165a68c49bf5918e2148c645380e7f3c20d 100644
--- a/app/lib/toc_generator.rb
+++ b/app/lib/toc_generator.rb
@@ -53,7 +53,7 @@ class TOCGenerator
 
       next unless LISTED_ELEMENTS.include?(node.name)
 
-      depth          = node.name[1..-1]
+      depth          = node.name[1..]
       latest_section = @headers.last
 
       if latest_section.nil? || latest_section.depth >= depth
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 5fb7655a9b4837e48462a0fa70d1ec4903fd2a98..cb0404ed384f099b8ff4d7e510b941216d182c40 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -14,7 +14,7 @@ class UserSettingsDecorator
 
   private
 
-  def process_update
+  def process_update # rubocop:disable Metrics/AbcSize
     user.settings['notification_emails'] = merged_notification_emails if change?('notification_emails')
     user.settings['interactions']        = merged_interactions if change?('interactions')
     user.settings['default_privacy']     = default_privacy_preference if change?('setting_default_privacy')
diff --git a/app/lib/validation_error_formatter.rb b/app/lib/validation_error_formatter.rb
index 3f964f739b559ee3622e82d47538b253e890609d..1d3e8955b3ce8bb065ec99f33a480b632ef674f9 100644
--- a/app/lib/validation_error_formatter.rb
+++ b/app/lib/validation_error_formatter.rb
@@ -19,7 +19,7 @@ class ValidationErrorFormatter
       messages = errors.messages[attribute_name]
 
       h[@aliases[attribute_name] || attribute_name] = attribute_errors.map.with_index do |error, index|
-        { error: 'ERR_' + error[:error].to_s.upcase, description: messages[index] }
+        { error: "ERR_#{error[:error].to_s.upcase}", description: messages[index] }
       end
     end
 
diff --git a/app/lib/webfinger.rb b/app/lib/webfinger.rb
index a681e0815faf83961015c5340afd28293b0b0688..a8f6f6d83fc610e604e762b42a264037d001fb31 100644
--- a/app/lib/webfinger.rb
+++ b/app/lib/webfinger.rb
@@ -99,7 +99,7 @@ class Webfinger
   end
 
   def standard_url
-    if @domain.end_with? ".onion"
+    if @domain.end_with? '.onion'
       "http://#{@domain}/.well-known/webfinger?resource=#{@uri}"
     else
       "https://#{@domain}/.well-known/webfinger?resource=#{@uri}"
@@ -107,7 +107,7 @@ class Webfinger
   end
 
   def host_meta_url
-    if @domain.end_with? ".onion"
+    if @domain.end_with? '.onion'
       "http://#{@domain}/.well-known/host-meta"
     else
       "https://#{@domain}/.well-known/host-meta"
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index a37682eca63ab674bb7df5dc89396948549f893b..73b623576c37d66fd97df882b9d13efa5baac83d 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -9,9 +9,7 @@ class ApplicationMailer < ActionMailer::Base
 
   protected
 
-  def locale_for_account(account)
-    I18n.with_locale(account.user_locale || I18n.default_locale) do
-      yield
-    end
+  def locale_for_account(account, &block)
+    I18n.with_locale(account.user_locale || I18n.default_locale, &block)
   end
 end
diff --git a/app/models/account_alias.rb b/app/models/account_alias.rb
index b421c66e211df1cf10e782bd0cf6cf961b26ac15..081a534f336b9e1b10709eaab45752d6e268d210 100644
--- a/app/models/account_alias.rb
+++ b/app/models/account_alias.rb
@@ -25,7 +25,7 @@ class AccountAlias < ApplicationRecord
 
   def acct=(val)
     val = val.to_s.strip
-    super(val.start_with?('@') ? val[1..-1] : val)
+    super(val.start_with?('@') ? val[1..] : val)
   end
 
   def pretty_acct
diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb
index 6067b54b784c9a8db383976a68a94c8cbf56c880..8afedba718263169a0cf6d85dad3304f4f76f896 100644
--- a/app/models/account_warning.rb
+++ b/app/models/account_warning.rb
@@ -16,6 +16,7 @@
 #
 
 class AccountWarning < ApplicationRecord
+  # rubocop:disable Lint/RedundantCopDisableDirective, Layout/FirstHashElementIndentation
   enum action: {
     none:                       0,
     disable:                    1_000,
@@ -25,6 +26,7 @@ class AccountWarning < ApplicationRecord
     silence:                    3_000,
     suspend:                    4_000,
   }, _suffix: :action
+  # rubocop:enable Lint/RedundantCopDisableDirective, Layout/FirstHashElementIndentation
 
   belongs_to :account, inverse_of: :account_warnings
   belongs_to :target_account, class_name: 'Account', inverse_of: :strikes
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index a7401362f4041393f864918615e744929f618e0d..6b1321d52383782170c687224db41281510819b4 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-module AccountInteractions
+module AccountInteractions # rubocop:disable Metrics/ModuleLength
   extend ActiveSupport::Concern
 
   class_methods do
diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb
index 4d902abcba9c0bc98058acd2a10ebe22c7080626..c64fc7d807d0064ab46e61e48cc75cdfead48aeb 100644
--- a/app/models/concerns/expireable.rb
+++ b/app/models/concerns/expireable.rb
@@ -17,7 +17,7 @@ module Expireable
     end
 
     def expires_in=(interval)
-      self.expires_at = interval.present? ? interval.to_i.seconds.from_now : nil 
+      self.expires_at = interval.present? ? interval.to_i.seconds.from_now : nil
       @expires_in     = interval
     end
 
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index 289e3b66f9860f3dfa7b5cc2c40b55e001d43039..57328400452488bb28fd3b17f01329f942a6fa6e 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -46,7 +46,7 @@ class CustomEmoji < ApplicationRecord
   scope :local, -> { where(domain: nil) }
   scope :remote, -> { where.not(domain: nil) }
   scope :alphabetic, -> { order(domain: :asc, shortcode: :asc) }
-  scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) }
+  scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches("%.#{domain}"))) }
   scope :listed, -> { local.where(disabled: false).where(visible_in_picker: true) }
 
   remotable_attachment :image, LIMIT
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index a15206b5effc6d72e949a9add149c5c98b8b6630..b571a0bc7f068442d9cecfbd19919a1a4b2d55c7 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -63,7 +63,7 @@ class DomainBlock < ApplicationRecord
 
       uri      = Addressable::URI.new.tap { |u| u.host = domain.strip.gsub(/[\/]/, '') }
       segments = uri.normalized_host.split('.')
-      variants = segments.map.with_index { |_, i| segments[i..-1].join('.') }
+      variants = segments.map.with_index { |_, i| segments[i..].join('.') }
 
       where(domain: variants).order(Arel.sql('char_length(domain) desc')).first
     rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
diff --git a/app/models/preview_card_provider.rb b/app/models/preview_card_provider.rb
index 15b24e2bdfd61e6a12a9ac81e9e0412630b5837d..b6209bb62d40d70aee3f6ffaddeb85cca1855b3a 100644
--- a/app/models/preview_card_provider.rb
+++ b/app/models/preview_card_provider.rb
@@ -52,6 +52,6 @@ class PreviewCardProvider < ApplicationRecord
 
   def self.matching_domain(domain)
     segments = domain.split('.')
-    where(domain: segments.map.with_index { |_, i| segments[i..-1].join('.') }).order(Arel.sql('char_length(domain) desc')).first
+    where(domain: segments.map.with_index { |_, i| segments[i..].join('.') }).order(Arel.sql('char_length(domain) desc')).first
   end
 end
diff --git a/app/serializers/activitypub/outbox_serializer.rb b/app/serializers/activitypub/outbox_serializer.rb
index 4f4f950a5ac7c09180c4a79553db24f9c79e7d76..ad56d748e1e9877d49ab5c5efa758358587a82f1 100644
--- a/app/serializers/activitypub/outbox_serializer.rb
+++ b/app/serializers/activitypub/outbox_serializer.rb
@@ -2,7 +2,7 @@
 
 class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer
   def self.serializer_for(model, options)
-    if model.class.name == 'ActivityPub::ActivityPresenter'
+    if model.instance_of?(ActivityPub::ActivityPresenter)
       ActivityPub::ActivitySerializer
     else
       super
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index 037f519d3e6c1f99587d684c9e2c231c6f0d824e..7cdc52f04b2cfe7318877895b81d91404851396d 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -53,7 +53,7 @@ class BackupService < BaseService
       end
     end
 
-    archive_filename = ['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(16)].join('-') + '.tar.gz'
+    archive_filename = "#{['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(16)].join('-')}.tar.gz"
 
     @backup.dump      = ActionDispatch::Http::UploadedFile.new(tempfile: tmp_file, filename: archive_filename)
     @backup.processed = true
@@ -86,14 +86,14 @@ class BackupService < BaseService
   def dump_actor!(tar)
     actor = serialize(account, ActivityPub::ActorSerializer)
 
-    actor[:icon][:url]  = 'avatar' + File.extname(actor[:icon][:url])  if actor[:icon]
-    actor[:image][:url] = 'header' + File.extname(actor[:image][:url]) if actor[:image]
+    actor[:icon][:url]  = "avatar#{File.extname(actor[:icon][:url])}"  if actor[:icon]
+    actor[:image][:url] = "header#{File.extname(actor[:image][:url])}" if actor[:image]
     actor[:outbox]      = 'outbox.json'
     actor[:likes]       = 'likes.json'
     actor[:bookmarks]   = 'bookmarks.json'
 
-    download_to_tar(tar, account.avatar, 'avatar' + File.extname(account.avatar.path)) if account.avatar.exists?
-    download_to_tar(tar, account.header, 'header' + File.extname(account.header.path)) if account.header.exists?
+    download_to_tar(tar, account.avatar, "avatar#{File.extname(account.avatar.path)}") if account.avatar.exists?
+    download_to_tar(tar, account.header, "header#{File.extname(account.header.path)}") if account.header.exists?
 
     json = Oj.dump(actor)
 
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index e5b5b730eca2e5175a1faa8678876993da106f69..969e77e788651a4d2148c47c395d97595153d1f9 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -45,7 +45,7 @@ class FetchLinkCardService < BaseService
   def html
     return @html if defined?(@html)
 
-    Request.new(:get, @url).add_headers('Accept' => 'text/html', 'User-Agent' => Mastodon::Version.user_agent + ' Bot').perform do |res|
+    Request.new(:get, @url).add_headers('Accept' => 'text/html', 'User-Agent' => '${Mastodon::Version.user_agent} Bot').perform do |res|
       # We follow redirects, and ideally we want to save the preview card for
       # the destination URL and not any link shortener in-between, so here
       # we set the URL to the one of the last response in the redirect chain
diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb
index 8f7d96b8e94c0ecc9c1e02a028d507a0d8641531..744e77044ab89f234ea866f588e3ea55210b3856 100644
--- a/app/validators/existing_username_validator.rb
+++ b/app/validators/existing_username_validator.rb
@@ -21,8 +21,8 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
 
     if options[:multiple]
       record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: usernames_with_no_accounts.join(', '))) if usernames_with_no_accounts.any?
-    else
-      record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) if usernames_with_no_accounts.any? || usernames_and_domains.size > 1
+    elsif usernames_with_no_accounts.any? || usernames_and_domains.size > 1
+      record.errors.add(attribute, I18n.t('existing_username_validator.not_found'))
     end
   end
 end
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index e107912b77df6352a5234e5f3e1213c9d96d3e4a..727d24d9194641719c6396d6c7d0d20c1340f019 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -53,7 +53,7 @@ class StatusLengthValidator < ActiveModel::Validator
       entity[:indices].last
     end
 
-    result << str[last_index..-1]
+    result << str[last_index..]
     result
   end
 end
diff --git a/lib/active_record/batches.rb b/lib/active_record/batches.rb
index 55d29e52ef41d7b9523d004b884b131bb5e599ec..91e50cc43dac0999270cc600823f73ba52f7c068 100644
--- a/lib/active_record/batches.rb
+++ b/lib/active_record/batches.rb
@@ -29,7 +29,7 @@ module ActiveRecord
           if flatten
             yield record[1]
           else
-            yield record[1..-1]
+            yield record[1..]
           end
         end
 
diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
index a7c78c4a7aa86abbac00789e3263e957c185d372..1c98eb952e955f2ad05942f3194746eb01026475 100644
--- a/lib/mastodon/domains_cli.rb
+++ b/lib/mastodon/domains_cli.rb
@@ -97,7 +97,7 @@ module Mastodon
       failed          = Concurrent::AtomicFixnum.new(0)
       start_at        = Time.now.to_f
       seed            = start ? [start] : Instance.pluck(:domain)
-      blocked_domains = Regexp.new('\\.?' + DomainBlock.where(severity: 1).pluck(:domain).join('|') + '$')
+      blocked_domains = Regexp.new("\\.?#{DomainBlock.where(severity: 1).pluck(:domain).join('|')}$")
       progress        = create_progress_bar
 
       pool = Concurrent::ThreadPoolExecutor.new(min_threads: 0, max_threads: options[:concurrency], idletime: 10, auto_terminate: true, max_queue: 0)
diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb
index a3e94790985882a7777a71254bbfe7ea5acceb46..88065c2a39e5f55d24f86c7e9140486f1d094e75 100644
--- a/lib/mastodon/emoji_cli.rb
+++ b/lib/mastodon/emoji_cli.rb
@@ -49,7 +49,7 @@ module Mastodon
           next if filename.start_with?('._')
 
           shortcode    = [options[:prefix], filename, options[:suffix]].compact.join
-          custom_emoji = CustomEmoji.local.find_by("LOWER(shortcode) = ?", shortcode.downcase)
+          custom_emoji = CustomEmoji.local.find_by('LOWER(shortcode) = ?', shortcode.downcase)
 
           if custom_emoji && !options[:overwrite]
             skipped += 1
@@ -68,7 +68,7 @@ module Mastodon
             failed += 1
             say('Failure/Error: ', :red)
             say(entry.full_name)
-            say('    ' + custom_emoji.errors[:image].join(', '), :red)
+            say("    #{custom_emoji.errors[:image].join(', ')}", :red)
           end
         end
       end
diff --git a/lib/mastodon/maintenance_cli.rb b/lib/mastodon/maintenance_cli.rb
index 6e5242bffdd5c7cd25aeb1f752c4b8ed9a98259a..54e359d93ac814c698470d99088566ee1945bfaf 100644
--- a/lib/mastodon/maintenance_cli.rb
+++ b/lib/mastodon/maintenance_cli.rb
@@ -183,7 +183,7 @@ module Mastodon
       deduplicate_tags!
       deduplicate_webauthn_credentials!
 
-      Scenic.database.refresh_materialized_view('instances', concurrently: true, cascade: false) if ActiveRecord::Migrator.current_version >= 2020_12_06_004238
+      Scenic.database.refresh_materialized_view('instances', concurrently: true, cascade: false) if ActiveRecord::Migrator.current_version >= 2020_12_06_004238 # rubocop:disable Style/NumericLiterals
       Rails.cache.clear
 
       @prompt.say 'Finished!'
@@ -207,7 +207,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring index_accounts_on_username_and_domain_lower…'
-      if ActiveRecord::Migrator.current_version < 20200620164023 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2020_06_20_16_40_23 # rubocop:disable Style/NumericLiterals
         ActiveRecord::Base.connection.add_index :accounts, 'lower (username), lower(domain)', name: 'index_accounts_on_username_and_domain_lower', unique: true
       else
         ActiveRecord::Base.connection.add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true
@@ -250,7 +250,7 @@ module Mastodon
         end
       end
 
-      if ActiveRecord::Migrator.current_version < 20220118183010 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_01_18_18_30_10 # rubocop:disable Style/NumericLiterals
         ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE remember_token IS NOT NULL GROUP BY remember_token HAVING count(*) > 1").each do |row|
           users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse.drop(1)
           @prompt.warn "Unsetting remember token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}"
@@ -273,9 +273,9 @@ module Mastodon
       @prompt.say 'Restoring users indexes…'
       ActiveRecord::Base.connection.add_index :users, ['confirmation_token'], name: 'index_users_on_confirmation_token', unique: true
       ActiveRecord::Base.connection.add_index :users, ['email'], name: 'index_users_on_email', unique: true
-      ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 20220118183010
+      ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 2022_01_18_18_30_10 # rubocop:disable Style/NumericLiterals
 
-      if ActiveRecord::Migrator.current_version < 20220310060641 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_10_06_06_41 # rubocop:disable Style/NumericLiterals
         ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
       else
         ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, where: 'reset_password_token IS NOT NULL', opclass: :text_pattern_ops
@@ -291,7 +291,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring account domain blocks indexes…'
-      ActiveRecord::Base.connection.add_index :account_domain_blocks, ['account_id', 'domain'], name: 'index_account_domain_blocks_on_account_id_and_domain', unique: true
+      ActiveRecord::Base.connection.add_index :account_domain_blocks, %w(account_id domain), name: 'index_account_domain_blocks_on_account_id_and_domain', unique: true
     end
 
     def deduplicate_account_identity_proofs!
@@ -305,7 +305,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring account identity proofs indexes…'
-      ActiveRecord::Base.connection.add_index :account_identity_proofs, ['account_id', 'provider', 'provider_username'], name: 'index_account_proofs_on_account_and_provider_and_username', unique: true
+      ActiveRecord::Base.connection.add_index :account_identity_proofs, %w(account_id provider provider_username), name: 'index_account_proofs_on_account_and_provider_and_username', unique: true
     end
 
     def deduplicate_announcement_reactions!
@@ -319,7 +319,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring announcement_reactions indexes…'
-      ActiveRecord::Base.connection.add_index :announcement_reactions, ['account_id', 'announcement_id', 'name'], name: 'index_announcement_reactions_on_account_id_and_announcement_id', unique: true
+      ActiveRecord::Base.connection.add_index :announcement_reactions, %w(account_id announcement_id name), name: 'index_announcement_reactions_on_account_id_and_announcement_id', unique: true
     end
 
     def deduplicate_conversations!
@@ -338,7 +338,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring conversations indexes…'
-      if ActiveRecord::Migrator.current_version < 20220307083603 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_07_08_36_03 # rubocop:disable Style/NumericLiterals
         ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true
       else
         ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops
@@ -361,7 +361,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring custom_emojis indexes…'
-      ActiveRecord::Base.connection.add_index :custom_emojis, ['shortcode', 'domain'], name: 'index_custom_emojis_on_shortcode_and_domain', unique: true
+      ActiveRecord::Base.connection.add_index :custom_emojis, %w(shortcode domain), name: 'index_custom_emojis_on_shortcode_and_domain', unique: true
     end
 
     def deduplicate_custom_emoji_categories!
@@ -488,7 +488,7 @@ module Mastodon
       end
 
       @prompt.say 'Restoring statuses indexes…'
-      if ActiveRecord::Migrator.current_version < 20220310060706 # rubocop:disable Style/NumericLiterals
+      if ActiveRecord::Migrator.current_version < 2022_03_10_06_07_06 # rubocop:disable Style/NumericLiterals
         ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true
       else
         ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops
diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
index 36ca71844f0dcd73903e6005e00c06df38346c59..46a1538ea833d88a89917b6874154abd15651f5e 100644
--- a/lib/mastodon/media_cli.rb
+++ b/lib/mastodon/media_cli.rb
@@ -260,7 +260,7 @@ module Mastodon
     def lookup(url)
       path = Addressable::URI.parse(url).path
 
-      path_segments = path.split('/')[2..-1]
+      path_segments = path.split('/')[2..]
       path_segments.delete('cache')
 
       unless [7, 10].include?(path_segments.size)
diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb
index 2ab8150ec93ed2485ebea14b4a91dc7e035f70d2..e31754f3f45cb817e4817b9fe0d913105cef348a 100644
--- a/lib/mastodon/migration_helpers.rb
+++ b/lib/mastodon/migration_helpers.rb
@@ -284,13 +284,6 @@ module Mastodon
     # table - The name of the table.
     # column - The name of the column to update.
     # value - The value for the column.
-    #
-    # Rubocop's Metrics/AbcSize metric is disabled for this method as Rubocop
-    # determines this method to be too complex while there's no way to make it
-    # less "complex" without introducing extra methods (which actually will
-    # make things _more_ complex).
-    #
-    # rubocop: disable Metrics/AbcSize
     def update_column_in_batches(table_name, column, value)
       if transaction_open?
         raise 'update_column_in_batches can not be run inside a transaction, ' \
diff --git a/lib/mastodon/premailer_webpack_strategy.rb b/lib/mastodon/premailer_webpack_strategy.rb
index 56ef09c1a889494e9e08167e4a9f8767e93a1c0a..f0b8133337b9baa102228da7fda396ecc41020e5 100644
--- a/lib/mastodon/premailer_webpack_strategy.rb
+++ b/lib/mastodon/premailer_webpack_strategy.rb
@@ -12,7 +12,7 @@ module PremailerWebpackStrategy
     css = if url.start_with?('http')
             HTTP.get(url).to_s
           else
-            url = url[1..-1] if url.start_with?('/')
+            url = url[1..] if url.start_with?('/')
             File.read(Rails.root.join('public', url))
           end
 
diff --git a/lib/mastodon/redis_config.rb b/lib/mastodon/redis_config.rb
index 98dc4788d1451efc23fd7cc859e7c2f8cbb51574..d126799eb0dd561a9f063523552a468bc7b37b26 100644
--- a/lib/mastodon/redis_config.rb
+++ b/lib/mastodon/redis_config.rb
@@ -1,17 +1,17 @@
 # frozen_string_literal: true
 
 def setup_redis_env_url(prefix = nil, defaults = true)
-  prefix = prefix.to_s.upcase + '_' unless prefix.nil?
+  prefix = "#{prefix.to_s.upcase}_" unless prefix.nil?
   prefix = '' if prefix.nil?
 
-  return if ENV[prefix + 'REDIS_URL'].present?
+  return if ENV["#{prefix}REDIS_URL"].present?
 
-  password = ENV.fetch(prefix + 'REDIS_PASSWORD') { '' if defaults }
-  host     = ENV.fetch(prefix + 'REDIS_HOST') { 'localhost' if defaults }
-  port     = ENV.fetch(prefix + 'REDIS_PORT') { 6379 if defaults }
-  db       = ENV.fetch(prefix + 'REDIS_DB') { 0 if defaults }
+  password = ENV.fetch("#{prefix}REDIS_PASSWORD") { '' if defaults }
+  host     = ENV.fetch("#{prefix}REDIS_HOST")     { 'localhost' if defaults }
+  port     = ENV.fetch("#{prefix}REDIS_PORT")     { 6379 if defaults }
+  db       = ENV.fetch("#{prefix}REDIS_DB")       { 0 if defaults }
 
-  ENV[prefix + 'REDIS_URL'] = begin
+  ENV["#{prefix}REDIS_URL"] = begin
     if [password, host, port, db].all?(&:nil?)
       ENV['REDIS_URL']
     else
@@ -27,7 +27,7 @@ setup_redis_env_url(:cache, false)
 setup_redis_env_url(:sidekiq, false)
 
 namespace         = ENV.fetch('REDIS_NAMESPACE', nil)
-cache_namespace   = namespace ? namespace + '_cache' : 'cache'
+cache_namespace   = namespace ? "#{namespace}_cache" : 'cache'
 sidekiq_namespace = namespace
 
 REDIS_CACHE_PARAMS = {
diff --git a/lib/mastodon/snowflake.rb b/lib/mastodon/snowflake.rb
index fe0dc1722eeb377eebbdafb286632ffc35983a56..8030288aff700834747eb394ec27f648b61a887d 100644
--- a/lib/mastodon/snowflake.rb
+++ b/lib/mastodon/snowflake.rb
@@ -115,7 +115,7 @@ module Mastodon::Snowflake
         # And only those that are using timestamp_id.
         next unless (data = DEFAULT_REGEX.match(id_col.default_function))
 
-        seq_name = data[:seq_prefix] + '_id_seq'
+        seq_name = "#{data[:seq_prefix]}_id_seq"
 
         # If we were on Postgres 9.5+, we could do CREATE SEQUENCE IF
         # NOT EXISTS, but we can't depend on that. Instead, catch the
diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb
index d66a176235bece272056a3ad219854fdefc29a4c..4025bd71c37d5e5b022494cf29d66b2c692713b2 100644
--- a/lib/paperclip/attachment_extensions.rb
+++ b/lib/paperclip/attachment_extensions.rb
@@ -8,7 +8,7 @@ module Paperclip
 
     # monkey-patch to avoid unlinking too avoid unlinking source file too early
     # see https://github.com/kreeti/kt-paperclip/issues/64
-    def post_process_style(name, style) #:nodoc:
+    def post_process_style(name, style) # :nodoc:
       raise "Style #{name} has no processors defined." if style.processors.blank?
 
       intermediate_files = []
@@ -16,16 +16,14 @@ module Paperclip
       # if we're processing the original, close + unlink the source tempfile
       intermediate_files << original if name == :original
 
-      @queued_for_write[name] = style.processors.
-                                inject(original) do |file, processor|
+      @queued_for_write[name] = style.processors.reduce(original) do |file, processor|
         file = Paperclip.processor(processor).make(file, style.processor_options, self)
         intermediate_files << file unless file == original
         file
       end
 
       unadapted_file = @queued_for_write[name]
-      @queued_for_write[name] = Paperclip.io_adapters.
-                                for(@queued_for_write[name], @options[:adapter_options])
+      @queued_for_write[name] = Paperclip.io_adapters.for(@queued_for_write[name], @options[:adapter_options])
       unadapted_file.close if unadapted_file.respond_to?(:close)
       @queued_for_write[name]
     rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e
diff --git a/lib/paperclip/gif_transcoder.rb b/lib/paperclip/gif_transcoder.rb
index d14465c018428f24ac79d4e0b7f7ae80dacf069d..c28a48a05ec1fe76db202c182a2f140fc65aa38f 100644
--- a/lib/paperclip/gif_transcoder.rb
+++ b/lib/paperclip/gif_transcoder.rb
@@ -109,7 +109,7 @@ module Paperclip
       final_file = Paperclip::Transcoder.make(file, options, attachment)
 
       if options[:style] == :original
-        attachment.instance.file_file_name    = File.basename(attachment.instance.file_file_name, '.*') + '.mp4'
+        attachment.instance.file_file_name    = "#{File.basename(attachment.instance.file_file_name, '.*')}.mp4"
         attachment.instance.file_content_type = 'video/mp4'
         attachment.instance.type              = MediaAttachment.types[:gifv]
       end
diff --git a/lib/paperclip/type_corrector.rb b/lib/paperclip/type_corrector.rb
index 17e2fc5daaa147779c57742ce7ad774a4f995581..030b98b122b3dca975c0a494fff4423e19369a6a 100644
--- a/lib/paperclip/type_corrector.rb
+++ b/lib/paperclip/type_corrector.rb
@@ -7,7 +7,7 @@ module Paperclip
     def make
       return @file unless options[:format]
 
-      target_extension = '.' + options[:format]
+      target_extension = ".#{options[:format]}"
       extension        = File.extname(attachment.instance_read(:file_name))
 
       return @file unless options[:style] == :original && target_extension && extension != target_extension
diff --git a/lib/rails/engine_extensions.rb b/lib/rails/engine_extensions.rb
index 4848b15f254dc740a3fe5d6552d46ed0f26ec3fb..f456ea19929a06877fde5a3905b254c6b02ab5cf 100644
--- a/lib/rails/engine_extensions.rb
+++ b/lib/rails/engine_extensions.rb
@@ -1,9 +1,11 @@
+# frozen_string_literal: true
+
 module Rails
   module EngineExtensions
     # Rewrite task loading code to filter digitalocean.rake task
     def run_tasks_blocks(app)
       Railtie.instance_method(:run_tasks_blocks).bind(self).call(app)
-      paths["lib/tasks"].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) }
+      paths['lib/tasks'].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) }
     end
   end
 end
diff --git a/lib/tasks/branding.rake b/lib/tasks/branding.rake
index 2eec7c9e14df0349eb845abf6ff883278560a74a..142a6c7ddf1f3ce143efaae9f4cfc463f4b31bbd 100644
--- a/lib/tasks/branding.rake
+++ b/lib/tasks/branding.rake
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 namespace :branding do
   desc 'Generate necessary graphic assets for branding from source SVG files'
   task generate: :environment do
diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake
index d9db7994027bc08e2f73106713c7ed03de35569e..c30fac8e1bbe807cfec4fa66d755b61af9c3bf36 100644
--- a/lib/tasks/emojis.rake
+++ b/lib/tasks/emojis.rake
@@ -69,7 +69,7 @@ namespace :emojis do
       end
     end
 
-    existence_maps = grouped_codes.map { |c| c.index_with { |cc| File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg')) } }
+    existence_maps = grouped_codes.map { |c| c.index_with { |cc| File.exist?(Rails.root.join('public', 'emoji', "#{codepoints_to_filename(cc)}.svg")) } }
     map = {}
 
     existence_maps.each do |group|
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index d652468b37fb7318ee3c31ada99c79c5dea3c9ad..b5553dab6c9952b6fac304d322684976cc69bab2 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -399,11 +399,13 @@ namespace :mastodon do
             prompt.say 'Running `RAILS_ENV=production rails assets:precompile` ...'
             prompt.say "\n\n"
 
+            # rubocop:disable Metrics/BlockNesting
             if !system(env.transform_values(&:to_s).merge({ 'RAILS_ENV' => 'production' }), 'rails assets:precompile')
               prompt.error 'That failed! Maybe you need swap space?'
             else
               prompt.say 'Done!'
             end
+            # rubocop:enable Metrics/BlockNesting
           end
         end
 
diff --git a/lib/tasks/repo.rake b/lib/tasks/repo.rake
index 795b54c59c313792ad8417c7bce66e10f5302c51..c8aafc1de618dad34d175148f76b4a7e8a654c78 100644
--- a/lib/tasks/repo.rake
+++ b/lib/tasks/repo.rake
@@ -50,7 +50,7 @@ namespace :repo do
         file.each_line do |line|
           if line.start_with?('-')
             new_line = line.gsub(/#([[:digit:]]+)*/) do |pull_request_reference|
-              pull_request_number = pull_request_reference[1..-1]
+              pull_request_number = pull_request_reference[1..]
               response = nil
 
               loop do
diff --git a/lib/tasks/statistics.rake b/lib/tasks/statistics.rake
index 82f2b5416227026fe12fe09ed71c80f708da42c9..a788b1c168597035b760a6557d67570dcd2004ce 100644
--- a/lib/tasks/statistics.rake
+++ b/lib/tasks/statistics.rake
@@ -7,7 +7,7 @@ namespace :mastodon do
   task :stats do
     require 'rails/code_statistics'
     [
-      %w(App\ Libraries app/lib),
+      ['App Libraries', 'app/lib'],
       %w(Presenters app/presenters),
       %w(Services app/services),
       %w(Validators app/validators),
diff --git a/lib/webpacker/manifest_extensions.rb b/lib/webpacker/manifest_extensions.rb
index 789eb81ccf31735cd59ec03ba64592f2661293b0..f9fe4c8030a6208c9fafef0515ddb2c9578b655a 100644
--- a/lib/webpacker/manifest_extensions.rb
+++ b/lib/webpacker/manifest_extensions.rb
@@ -4,6 +4,7 @@ module Webpacker::ManifestExtensions
   def lookup(name, pack_type = {})
     asset = super
 
+    # rubocop:disable Style/SingleArgumentDig
     if pack_type[:with_integrity] && asset.respond_to?(:dig)
       [asset.dig('src'), asset.dig('integrity')]
     elsif asset.respond_to?(:dig)
@@ -11,6 +12,7 @@ module Webpacker::ManifestExtensions
     else
       asset
     end
+    # rubocop:enable Style/SingleArgumentDig
   end
 end