Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#8827] Change Style/FormatStringToken style to template #10723

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1 @@
* [#8827](https://github.com/rubocop/rubocop/issues/8827): Change the enforced style of `Style/FormatStringToken` to `template`. ([@pirj][])
8 changes: 4 additions & 4 deletions config/default.yml
Expand Up @@ -3635,20 +3635,20 @@ Style/FormatString:
Style/FormatStringToken:
Description: 'Use a consistent style for format string tokens.'
Enabled: true
EnforcedStyle: annotated
EnforcedStyle: template
SupportedStyles:
# Prefer simple looking "template" style tokens like `%{name}`, `%{age}`
- template
# Prefer tokens which contain a sprintf like type annotation like
# `%<name>s`, `%<age>d`, `%<score>f`
- annotated
# Prefer simple looking "template" style tokens like `%{name}`, `%{age}`
- template
- unannotated
# `MaxUnannotatedPlaceholdersAllowed` defines the number of `unannotated`
# style token in a format string to be allowed when enforced style is not
# `unannotated`.
MaxUnannotatedPlaceholdersAllowed: 1
VersionAdded: '0.49'
VersionChanged: '1.0'
VersionChanged: '<<next>>'
IgnoredMethods: []

Style/FrozenStringLiteralComment:
Expand Down
18 changes: 9 additions & 9 deletions docs/modules/ROOT/pages/cops_style.adoc
Expand Up @@ -4208,7 +4208,7 @@ puts '%10s' % 'hoge'
| Yes
| No
| 0.49
| 1.0
| <<next>>
|===

Use a consistent style for named format string tokens.
Expand All @@ -4227,28 +4227,28 @@ if the number of them is less than or equals to

=== Examples

==== EnforcedStyle: annotated (default)
==== EnforcedStyle: template (default)

[source,ruby]
----
# bad
format('%{greeting}', greeting: 'Hello')
format('%<greeting>s', greeting: 'Hello')
format('%s', 'Hello')

# good
format('%<greeting>s', greeting: 'Hello')
format('%{greeting}', greeting: 'Hello')
----

==== EnforcedStyle: template
==== EnforcedStyle: annotated

[source,ruby]
----
# bad
format('%<greeting>s', greeting: 'Hello')
format('%{greeting}', greeting: 'Hello')
format('%s', 'Hello')

# good
format('%{greeting}', greeting: 'Hello')
format('%<greeting>s', greeting: 'Hello')
----

==== EnforcedStyle: unannotated
Expand Down Expand Up @@ -4300,8 +4300,8 @@ redirect('foo/%{bar_id}')
| Name | Default value | Configurable values

| EnforcedStyle
| `annotated`
| `annotated`, `template`, `unannotated`
| `template`
| `template`, `annotated`, `unannotated`

| MaxUnannotatedPlaceholdersAllowed
| `1`
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/config_obsoletion/changed_enforced_styles.rb
Expand Up @@ -5,7 +5,7 @@ class ConfigObsoletion
# Encapsulation of a ConfigObsoletion rule for changing a parameter
# @api private
class ChangedEnforcedStyles < ParameterRule
BASE_MESSAGE = 'obsolete `%<parameter>s: %<value>s` (for `%<cop>s`) found in %<path>s'
BASE_MESSAGE = 'obsolete `%{parameter}: %{value}` (for `%{cop}`) found in %{path}'

def violated?
super && config[cop][parameter] == value
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/config_obsoletion/changed_parameter.rb
Expand Up @@ -5,7 +5,7 @@ class ConfigObsoletion
# Encapsulation of a ConfigObsoletion rule for changing a parameter
# @api private
class ChangedParameter < ParameterRule
BASE_MESSAGE = 'obsolete parameter `%<parameter>s` (for `%<cop>s`) found in %<path>s'
BASE_MESSAGE = 'obsolete parameter `%{parameter}` (for `%{cop}`) found in %{path}'

def message
base = format(BASE_MESSAGE, parameter: parameter, cop: cop, path: smart_loaded_path)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/config_obsoletion/extracted_cop.rb
Expand Up @@ -21,7 +21,7 @@ def violated?
end

def rule_message
msg = '%<name>s been extracted to the `%<gem>s` gem.'
msg = '%{name} been extracted to the `%{gem}` gem.'
format(msg,
name: affected_cops.size > 1 ? "`#{department}` cops have" : "`#{old_name}` has",
gem: gem)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/config_obsoletion/removed_cop.rb
Expand Up @@ -8,7 +8,7 @@ class ConfigObsoletion
class RemovedCop < CopRule
attr_reader :old_name, :metadata

BASE_MESSAGE = 'The `%<old_name>s` cop has been removed'
BASE_MESSAGE = 'The `%{old_name}` cop has been removed'

def initialize(config, old_name, metadata)
super(config, old_name)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/bundler/duplicated_gem.rb
Expand Up @@ -38,8 +38,8 @@ module Bundler
class DuplicatedGem < Base
include RangeHelp

MSG = 'Gem `%<gem_name>s` requirements already given on line ' \
'%<line_of_first_occurrence>d of the Gemfile.'
MSG = 'Gem `%{gem_name}` requirements already given on line ' \
'%{line_of_first_occurrence} of the Gemfile.'

def on_new_investigation
return if processed_source.blank?
Expand Down
8 changes: 4 additions & 4 deletions lib/rubocop/cop/bundler/gem_filename.rb
Expand Up @@ -30,13 +30,13 @@ class GemFilename < Base
include RangeHelp

MSG_GEMFILE_REQUIRED = '`gems.rb` file was found but `Gemfile` is required ' \
'(file path: %<file_path>s).'
'(file path: %{file_path}).'
MSG_GEMS_RB_REQUIRED = '`Gemfile` was found but `gems.rb` file is required ' \
'(file path: %<file_path>s).'
'(file path: %{file_path}).'
MSG_GEMFILE_MISMATCHED = 'Expected a `Gemfile.lock` with `Gemfile` but found ' \
'`gems.locked` file (file path: %<file_path>s).'
'`gems.locked` file (file path: %{file_path}).'
MSG_GEMS_RB_MISMATCHED = 'Expected a `gems.locked` file with `gems.rb` but found ' \
'`Gemfile.lock` (file path: %<file_path>s).'
'`Gemfile.lock` (file path: %{file_path}).'
GEMFILE_FILES = %w[Gemfile Gemfile.lock].freeze
GEMS_RB_FILES = %w[gems.rb gems.locked].freeze

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/bundler/insecure_protocol_source.rb
Expand Up @@ -42,7 +42,7 @@ class InsecureProtocolSource < Base
include RangeHelp
extend AutoCorrector

MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
MSG = 'The source `:%{source}` is deprecated because HTTP requests ' \
'are insecure. ' \
"Please change your source to 'https://rubygems.org' " \
"if possible, or 'http://rubygems.org' if not."
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/bundler/ordered_gems.rb
Expand Up @@ -30,7 +30,7 @@ class OrderedGems < Base

MSG = 'Gems should be sorted in an alphabetical order within their ' \
'section of the Gemfile. ' \
'Gem `%<previous>s` should appear before `%<current>s`.'
'Gem `%{previous}` should appear before `%{current}`.'

def on_new_investigation
return if processed_source.blank?
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/correctors/each_to_for_corrector.rb
Expand Up @@ -6,8 +6,8 @@ module Cop
class EachToForCorrector
extend NodePattern::Macros

CORRECTION_WITH_ARGUMENTS = 'for %<variables>s in %<collection>s do'
CORRECTION_WITHOUT_ARGUMENTS = 'for _ in %<enumerable>s do'
CORRECTION_WITH_ARGUMENTS = 'for %{variables} in %{collection} do'
CORRECTION_WITHOUT_ARGUMENTS = 'for _ in %{enumerable} do'

def initialize(block_node)
@block_node = block_node
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/correctors/for_to_each_corrector.rb
Expand Up @@ -6,7 +6,7 @@ module Cop
class ForToEachCorrector
extend NodePattern::Macros

CORRECTION = '%<collection>s.each do |%<argument>s|'
CORRECTION = '%{collection}.each do |%{argument}|'

def initialize(for_node)
@for_node = for_node
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/gemspec/duplicated_assignment.rb
Expand Up @@ -38,8 +38,8 @@ class DuplicatedAssignment < Base
include RangeHelp
include GemspecHelp

MSG = '`%<assignment>s` method calls already given on line ' \
'%<line_of_first_occurrence>d of the gemspec.'
MSG = '`%{assignment}` method calls already given on line ' \
'%{line_of_first_occurrence} of the gemspec.'

# @!method assignment_method_declarations(node)
def_node_search :assignment_method_declarations, <<~PATTERN
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/gemspec/ordered_dependencies.rb
Expand Up @@ -56,7 +56,7 @@ class OrderedDependencies < Base

MSG = 'Dependencies should be sorted in an alphabetical order within ' \
'their section of the gemspec. ' \
'Dependency `%<previous>s` should appear before `%<current>s`.'
'Dependency `%{previous}` should appear before `%{current}`.'

def on_new_investigation
return if processed_source.blank?
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/gemspec/required_ruby_version.rb
Expand Up @@ -57,7 +57,7 @@ class RequiredRubyVersion < Base

RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
'(%<target_ruby_version>s, which may be specified in ' \
'(%{target_ruby_version}, which may be specified in ' \
'.rubocop.yml) should be equal.'
MISSING_MSG = '`required_ruby_version` should be specified.'

Expand Down
8 changes: 4 additions & 4 deletions lib/rubocop/cop/generator.rb
Expand Up @@ -13,7 +13,7 @@ class Generator

module RuboCop
module Cop
module %<department>s
module %{department}
# TODO: Write cop description and example of bad / good code. For every
# `SupportedStyle` and unique configuration, there needs to be examples.
# Examples must have valid Ruby syntax. Do not use upticks.
Expand Down Expand Up @@ -53,7 +53,7 @@ module %<department>s
# # good
# good_foo_method(args)
#
class %<cop_name>s < Base
class %{cop_name} < Base
# TODO: Implement the cop in here.
#
# In many cases, you can use a node matcher for matching node pattern.
Expand Down Expand Up @@ -81,7 +81,7 @@ def on_send(node)
SPEC_TEMPLATE = <<~SPEC
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s, :config do
RSpec.describe RuboCop::Cop::%{department}::%{cop_name}, :config do
let(:config) { RuboCop::Config.new }

# TODO: Write test code
Expand All @@ -104,7 +104,7 @@ def on_send(node)

CONFIGURATION_ADDED_MESSAGE =
'[modify] A configuration for the cop is added into ' \
'%<configuration_file_path>s.'
'%{configuration_file_path}.'

def initialize(name, output: $stdout)
@badge = Badge.parse(name)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/generator/configuration_injector.rb
Expand Up @@ -8,10 +8,10 @@ class Generator
# namespace and injects the provided one in alpha
class ConfigurationInjector
TEMPLATE = <<~YAML
%<badge>s:
%{badge}:
Description: 'TODO: Write a description of the cop.'
Enabled: pending
VersionAdded: '%<version_added>s'
VersionAdded: '%{version_added}'
YAML

def initialize(configuration_file_path:, badge:, version_added: '<<next>>')
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/internal_affairs/cop_description.rb
Expand Up @@ -21,7 +21,7 @@ module InternalAffairs
class CopDescription < Base
extend AutoCorrector

MSG = 'Description should be started with %<suggestion>s instead of `This cop ...`.'
MSG = 'Description should be started with %{suggestion} instead of `This cop ...`.'

SPECIAL_WORDS = %w[is can could should will would must may].freeze
COP_DESC_OFFENSE_REGEX = \
Expand Down
Expand Up @@ -33,7 +33,7 @@ module InternalAffairs
class EmptyLineBetweenExpectOffenseAndCorrection < Base
extend AutoCorrector

MSG = 'Add empty line between `expect_offense` and `%<expect_correction>s`.'
MSG = 'Add empty line between `expect_offense` and `%{expect_correction}`.'
RESTRICT_ON_SEND = %i[expect_offense].freeze
CORRECTION_EXPECTATION_METHODS = %i[expect_correction expect_no_corrections].freeze

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/internal_affairs/example_description.rb
Expand Up @@ -30,7 +30,7 @@ class << self
attr_accessor :descriptions
end

MSG = 'Description does not match use of `%<method_name>s`.'
MSG = 'Description does not match use of `%{method_name}`.'

RESTRICT_ON_SEND = %i[
expect_offense
Expand Down
Expand Up @@ -18,7 +18,7 @@ module InternalAffairs
class LocationLineEqualityComparison < Base
extend AutoCorrector

MSG = 'Use `%<preferred>s`.'
MSG = 'Use `%{preferred}`.'

# @!method line_send(node)
def_node_matcher :line_send, <<~PATTERN
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/internal_affairs/method_name_end_with.rb
Expand Up @@ -29,7 +29,7 @@ class MethodNameEndWith < Base
include RangeHelp
extend AutoCorrector

MSG = 'Use `%<method_name>s` instead of `%<method_suffix>s`.'
MSG = 'Use `%{method_name}` instead of `%{method_suffix}`.'
SUGGEST_METHOD_FOR_SUFFIX = {
'=' => 'assignment_method?',
'!' => 'bang_method?',
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/internal_affairs/method_name_equal.rb
Expand Up @@ -16,7 +16,7 @@ class MethodNameEqual < Base
include RangeHelp
extend AutoCorrector

MSG = 'Use `method?(%<method_name>s)` instead of `method_name == %<method_name>s`.'
MSG = 'Use `method?(%{method_name})` instead of `method_name == %{method_name}`.'
RESTRICT_ON_SEND = %i[==].freeze

# @!method method_name?(node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/internal_affairs/node_matcher_directive.rb
Expand Up @@ -23,9 +23,9 @@ class NodeMatcherDirective < Base
extend AutoCorrector
include RangeHelp

MSG = 'Precede `%<method>s` with a `@!method` YARD directive.'
MSG = 'Precede `%{method}` with a `@!method` YARD directive.'
MSG_WRONG_NAME = '`@!method` YARD directive has invalid method name, ' \
'use `%<expected>s` instead of `%<actual>s`.'
'use `%{expected}` instead of `%{actual}`.'
MSG_TOO_MANY = 'Multiple `@!method` YARD directives found for this matcher.'

RESTRICT_ON_SEND = %i[def_node_matcher def_node_search].to_set.freeze
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/internal_affairs/node_type_predicate.rb
Expand Up @@ -16,7 +16,7 @@ module InternalAffairs
class NodeTypePredicate < Base
extend AutoCorrector

MSG = 'Use `#%<type>s_type?` to check node type.'
MSG = 'Use `#%{type}_type?` to check node type.'
RESTRICT_ON_SEND = %i[==].freeze

# @!method node_type_check(node)
Expand Down
Expand Up @@ -16,7 +16,7 @@ module InternalAffairs
class OffenseLocationKeyword < Base
extend AutoCorrector

MSG = 'Use `:%<keyword>s` as the location argument to `#add_offense`.'
MSG = 'Use `:%{keyword}` as the location argument to `#add_offense`.'
RESTRICT_ON_SEND = %i[add_offense].freeze

def on_send(node)
Expand Down
Expand Up @@ -19,7 +19,7 @@ class RedundantDescribedClassAsSubject < Base
include RangeHelp
extend AutoCorrector

MSG = 'Remove the redundant `subject`%<additional_message>s.'
MSG = 'Remove the redundant `subject`%{additional_message}.'

# @!method described_class_subject?(node)
def_node_matcher :described_class_subject?, <<~PATTERN
Expand Down
Expand Up @@ -23,7 +23,7 @@ class RedundantLetRuboCopConfigNew < Base
include RangeHelp
extend AutoCorrector

MSG = 'Remove `let` that is `RuboCop::Config.new` with no arguments%<additional_message>s.'
MSG = 'Remove `let` that is `RuboCop::Config.new` with no arguments%{additional_message}.'

# @!method let_rubocop_config_new?(node)
def_node_matcher :let_rubocop_config_new?, <<~PATTERN
Expand Down
3 changes: 1 addition & 2 deletions lib/rubocop/cop/internal_affairs/undefined_config.rb
Expand Up @@ -9,8 +9,7 @@ class UndefinedConfig < Base
Safe SafeAutoCorrect AutoCorrect Severity StyleGuide Details Reference Include Exclude
].freeze
RESTRICT_ON_SEND = %i[[] fetch].freeze
MSG = '`%<name>s` is not defined in the configuration for `%<cop>s` ' \
'in `config/default.yml`.'
MSG = '`%{name}` is not defined in the configuration for `%{cop}` in `config/default.yml`.'

# @!method cop_class_def(node)
def_node_search :cop_class_def, <<~PATTERN
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/access_modifier_indentation.rb
Expand Up @@ -38,7 +38,7 @@ class AccessModifierIndentation < Base
include RangeHelp
extend AutoCorrector

MSG = '%<style>s access modifiers like `%<node>s`.'
MSG = '%{style} access modifiers like `%{node}`.'

def on_class(node)
return unless node.body&.begin_type?
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/block_alignment.rb
Expand Up @@ -66,7 +66,7 @@ class BlockAlignment < Base
include RangeHelp
extend AutoCorrector

MSG = '%<current>s is not aligned with %<prefer>s%<alt_prefer>s.'
MSG = '%{current} is not aligned with %{prefer}%{alt_prefer}.'

# @!method block_end_align_target?(node, child)
def_node_matcher :block_end_align_target?, <<~PATTERN
Expand Down