summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2021-06-03 00:43:50 -0600
committerDan Allen <dan.j.allen@gmail.com>2021-07-31 03:13:49 -0600
commit7f768e1ab12e8ab22590ef03cf2c518cd84ef104 (patch)
treedb7ab68305db063ca3e6234951d88ee56348e29f
parent19440d76157b53e2c8b2ad4632d05db3e9fd39bd (diff)
resolves #2557 enable RuboCop to enforce a consistent code style and perform static analysis
-rw-r--r--.github/workflows/ci.yml3
-rw-r--r--.rubocop.yml414
-rw-r--r--Gemfile6
-rw-r--r--lib/asciidoctor/abstract_block.rb4
-rw-r--r--lib/asciidoctor/abstract_node.rb2
-rw-r--r--lib/asciidoctor/cli/invoker.rb2
-rw-r--r--lib/asciidoctor/cli/options.rb8
-rw-r--r--lib/asciidoctor/converter/html5.rb4
-rw-r--r--lib/asciidoctor/document.rb2
-rw-r--r--lib/asciidoctor/load.rb2
-rw-r--r--lib/asciidoctor/logging.rb4
-rw-r--r--lib/asciidoctor/parser.rb14
-rw-r--r--lib/asciidoctor/path_resolver.rb2
-rw-r--r--lib/asciidoctor/substitutors.rb14
-rw-r--r--lib/asciidoctor/syntax_highlighter/pygments.rb2
-rw-r--r--lib/asciidoctor/table.rb2
-rw-r--r--tasks/rubocop.rake15
-rw-r--r--test/api_test.rb2
-rw-r--r--test/extensions_test.rb4
-rw-r--r--test/invoker_test.rb2
-rw-r--r--test/logger_test.rb16
-rw-r--r--test/test_helper.rb2
22 files changed, 482 insertions, 44 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fdbf4969..da88a4e0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -90,6 +90,9 @@ jobs:
bundle --jobs 3 --retry 3
- name: Run tests
run: bundle exec ruby -w $(bundle exec ruby -e 'print File.join Gem.bindir, %q(rake)') test:all
+ - name: Run linter
+ if: matrix.primary
+ run: bundle exec rake lint
- name: Check default stylesheet
if: matrix.primary
run: |
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..778122c8
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,414 @@
+require:
+- rubocop-minitest
+- rubocop-rake
+AllCops:
+ TargetRubyVersion: 2.5
+Gemspec/DateAssignment:
+ Enabled: true
+Layout/ArgumentAlignment:
+ EnforcedStyle: with_fixed_indentation
+Layout/BeginEndAlignment:
+ Enabled: true
+Layout/CaseIndentation:
+ EnforcedStyle: end
+Layout/EndOfLine:
+ EnforcedStyle: lf
+Layout/EmptyLineAfterGuardClause:
+ Enabled: false # reason: unnecessary extra space
+Layout/EmptyLinesAroundAttributeAccessor:
+ Enabled: true
+Layout/FirstArgumentIndentation:
+ Enabled: true
+Layout/HashAlignment:
+ Enabled: true
+Layout/HeredocIndentation:
+ Enabled: false # reason: makes it harder to understand what indentation is significant
+Layout/IndentationWidth:
+ Enabled: true
+ IgnoredPatterns: ['^module Asciidoctor$'] # FIXME keep and remove indentation in CLI, Timings, and API, or remove and fix indentation
+Layout/LeadingCommentSpace:
+ Enabled: false # reason: this is just nitpicky
+Layout/LineEndStringConcatenationIndentation:
+ Enabled: true
+Layout/LineLength:
+ Enabled: false # FIXME enable me
+Layout/MultilineMethodCallIndentation:
+ EnforcedStyle: indented
+Layout/MultilineOperationIndentation:
+ EnforcedStyle: indented
+Layout/ParameterAlignment:
+ EnforcedStyle: with_fixed_indentation
+ IndentationWidth: 4
+Layout/RescueEnsureAlignment:
+ Enabled: true
+Layout/SpaceAroundMethodCallOperator:
+ Enabled: true
+Layout/SpaceAroundOperators:
+ Enabled: true
+ EnforcedStyleForExponentOperator: space
+Layout/SpaceBeforeBrackets:
+ Enabled: true
+Layout/SpaceInsideBlockBraces:
+ SpaceBeforeBlockParameters: false
+Lint/AmbiguousAssignment:
+ Enabled: true
+Lint/AmbiguousBlockAssociation:
+ Enabled: true # NOTE this is pedantic when using braces for single-line blocks
+Lint/BinaryOperatorWithIdenticalOperands:
+ Enabled: true
+Lint/ConstantDefinitionInBlock:
+ Enabled: true
+ Exclude: [ test/*.rb ]
+Lint/DeprecatedConstants:
+ Enabled: true
+Lint/DeprecatedOpenSSLConstant:
+ Enabled: true
+Lint/DuplicateBranch:
+ Enabled: true
+Lint/DuplicateElsifCondition:
+ Enabled: true
+Lint/DuplicateRegexpCharacterClassElement:
+ Enabled: true
+Lint/DuplicateRequire:
+ Enabled: true
+Lint/DuplicateRescueException:
+ Enabled: true
+Lint/EmptyBlock:
+ Enabled: true
+Lint/EmptyClass:
+ Enabled: true
+Lint/EmptyConditionalBody:
+ Enabled: true
+Lint/EmptyFile:
+ Enabled: true
+Lint/EmptyInPattern:
+ Enabled: true
+Lint/EmptyWhen:
+ Enabled: false # reason: an empty when can be important for excluding matches
+Lint/FloatComparison:
+ Enabled: true
+Lint/IdentityComparison:
+ Enabled: true
+Lint/LambdaWithoutLiteralBlock:
+ Enabled: true
+Lint/MissingSuper:
+ Enabled: false # FIXME consider enabling
+Lint/MixedRegexpCaptureTypes:
+ Enabled: true
+Lint/NoReturnInBeginEndBlocks:
+ Enabled: true
+Lint/NumberedParameterAssignment:
+ Enabled: true
+Lint/OrAssignmentToConstant:
+ Enabled: true
+Lint/OutOfRangeRegexpRef:
+ Enabled: true
+Lint/ParenthesesAsGroupedExpression:
+ Enabled: false # reason: we prefer to enclose assignments
+Lint/RaiseException:
+ Enabled: true
+Lint/RedundantDirGlobSort:
+ Enabled: true
+Lint/SelfAssignment:
+ Enabled: true
+Lint/StructNewOverride:
+ Enabled: true
+Lint/SuppressedException:
+ Enabled: true
+Lint/SymbolConversion:
+ Enabled: true
+Lint/ToEnumArguments:
+ Enabled: true
+Lint/TopLevelReturnWithArgument:
+ Enabled: true
+Lint/TrailingCommaInAttributeDeclaration:
+ Enabled: true
+Lint/TripleQuotes:
+ Enabled: true
+Lint/UnexpectedBlockArity:
+ Enabled: true
+Lint/UnmodifiedReduceAccumulator:
+ Enabled: true
+Lint/UnreachableLoop:
+ Enabled: true
+Lint/UnusedMethodArgument:
+ Enabled: false # reason: these are important for defining API methods
+Lint/UselessMethodDefinition:
+ Enabled: true
+Lint/UselessTimes:
+ Enabled: true
+Metrics/AbcSize:
+ Enabled: false
+Metrics/BlockLength:
+ Enabled: false
+Metrics/BlockNesting:
+ Max: 10
+Metrics/ClassLength:
+ Enabled: false
+Metrics/CyclomaticComplexity:
+ Enabled: false
+Metrics/MethodLength:
+ Enabled: false
+Metrics/ModuleLength:
+ Enabled: false
+Metrics/ParameterLists:
+ Max: 10
+ MaxOptionalParameters: 10
+Metrics/PerceivedComplexity:
+ Enabled: false
+Minitest/AssertInDelta:
+ Enabled: false
+Minitest/AssertionInLifecycleHook:
+ Enabled: true
+Minitest/AssertKindOf:
+ Enabled: true
+Minitest/AssertOutput:
+ Enabled: true
+Minitest/AssertPathExists:
+ Enabled: true
+Minitest/AssertSilent:
+ Enabled: true
+Minitest/AssertWithExpectedArgument:
+ Enabled: true
+Minitest/LiteralAsActualArgument:
+ Enabled: true
+Minitest/MultipleAssertions:
+ Enabled: false
+Minitest/RefuteInDelta:
+ Enabled: true
+Minitest/RefuteKindOf:
+ Enabled: true
+Minitest/RefutePathExists:
+ Enabled: true
+Minitest/TestMethodName:
+ Enabled: true
+Minitest/UnreachableAssertion:
+ Enabled: true
+Minitest/UnspecifiedException:
+ Enabled: true
+Naming/AccessorMethodName:
+ Enabled: true
+Naming/ConstantName:
+ Enabled: false # FIXME consider reenabling
+Naming/FileName:
+ Enabled: true
+Naming/HeredocDelimiterNaming:
+ Enabled: false # reason: EOS is meaningful
+Naming/InclusiveLanguage:
+ Enabled: true
+Naming/MethodParameterName:
+ Enabled: true
+Naming/PredicateName:
+ Enabled: false # FIXME consider reenabling later (might impact API)
+Naming/VariableNumber:
+ Enabled: false # reason: this is just nitpicky
+Security/Open:
+ Enabled: true
+Style/AccessorGrouping:
+ Enabled: true
+ EnforcedStyle: separated
+Style/Alias:
+ Enabled: true
+ EnforcedStyle: prefer_alias
+Style/ArgumentsForwarding:
+ Enabled: true
+Style/ArrayCoercion:
+ Enabled: false # reason: using [*values] is faster
+Style/AsciiComments:
+ Enabled: false # reason: this is just nitpicky
+Style/Attr:
+ Enabled: true
+Style/BisectedAttrAccessor:
+ Enabled: true
+Style/BlockComments:
+ Enabled: true
+Style/BlockDelimiters:
+ EnforcedStyle: line_count_based # FIXME we want this to be line_count_based except when chaining
+Style/CaseEquality:
+ Enabled: false # reason: === is a useful operator
+Style/CaseLikeIf:
+ Enabled: true
+Style/CharacterLiteral:
+ Enabled: false # reason: ? can make single characters easier to type
+Style/ClassAndModuleChildren:
+ Enabled: false # reason: both forms are useful
+Style/ClassVars:
+ Enabled: false # reason: an important language feature
+Style/CollectionCompact:
+ Enabled: true
+Style/CombinableLoops:
+ Enabled: true
+Style/CommandLiteral:
+ EnforcedStyle: percent_x
+Style/CommentAnnotation:
+ Enabled: true
+ Keywords:
+ - TODO
+ - FIXME
+ - HACK
+ - NOTE
+ - QUESTION
+ RequireColon: false
+Style/ConditionalAssignment:
+ EnforcedStyle: assign_inside_condition
+ IncludeTernaryExpressions: false
+Style/DocumentDynamicEvalDefinition:
+ Enabled: true
+Style/Documentation:
+ Enabled: false # FIXME reenable
+Style/DoubleNegation:
+ Enabled: true
+Style/EmptyLiteral:
+ Enabled: true
+Style/EndlessMethod:
+ Enabled: true
+Style/ExplicitBlockArgument:
+ Enabled: false # reason: yield is fine
+Style/ExponentialNotation:
+ Enabled: true
+Style/FormatString:
+ EnforcedStyle: sprintf
+Style/FormatStringToken:
+ Enabled: true
+ EnforcedStyle: unannotated
+Style/GlobalStdStream:
+ Enabled: true
+Style/GuardClause:
+ Enabled: true
+ Exclude: [ lib/asciidoctor/substitutors.rb ]
+Style/HashConversion:
+ Enabled: true
+Style/HashAsLastArrayItem:
+ Enabled: true
+ EnforcedStyle: no_braces
+Style/HashEachMethods:
+ Enabled: true
+Style/HashExcept:
+ Enabled: true
+Style/HashLikeCase:
+ Enabled: true
+Style/HashSyntax:
+ EnforcedStyle: ruby19
+Style/HashTransformKeys:
+ Enabled: true
+Style/HashTransformValues:
+ Enabled: true
+Style/IfWithBooleanLiteralBranches:
+ Enabled: true
+ AllowedMethods:
+ - empty?
+ - nil_or_empty?
+Style/IfUnlessModifier:
+ Enabled: false # reason: this gets crazy
+Style/IfUnlessModifierOfIfUnless:
+ Enabled: false # reason: we prefer this style to avoid extra nesting
+Style/InPatternThen:
+ Enabled: true
+Style/InfiniteLoop:
+ Enabled: false # reason: loop is measurably slower than while true
+Style/KeywordParametersOrder:
+ Enabled: true
+Style/MethodCallWithArgsParentheses:
+ Enabled: true
+ EnforcedStyle: omit_parentheses
+Style/MethodDefParentheses:
+ EnforcedStyle: require_no_parentheses
+Style/MultilineBlockChain:
+ Enabled: false # reason: no reason not to allow method call on block result
+Style/MultilineInPatternThen:
+ Enabled: true
+Style/MultilineIfModifier:
+ Enabled: false # reason: we prefer this style to avoid extra nesting
+Style/MultilineTernaryOperator:
+ Enabled: false # reason: a ternary is a ternary
+Style/MultipleComparison:
+ Enabled: false # reason: faster than the alternative of using Array#include?
+Style/MutableConstant:
+ Enabled: false # reason: freezing constants is pendantic
+Style/NegatedIfElseCondition:
+ Enabled: true
+Style/NestedParenthesizedCalls:
+ Enabled: true
+Style/NestedTernaryOperator:
+ Enabled: false # reason: a ternary is a ternary
+Style/NilLambda:
+ Enabled: true
+Style/NumericLiterals:
+ Enabled: false # reason: makes large numbers unreadable and harder to copy
+Style/NumericPredicate:
+ EnforcedStyle: comparison
+Style/OptionalBooleanParameter:
+ Enabled: false # reason: invasive
+Style/ParallelAssignment:
+ Enabled: false # reason: an important language feature
+Style/PercentLiteralDelimiters:
+ PreferredDelimiters:
+ default: "()"
+ "%i": "()"
+ "%r": "//"
+ "%w": "()"
+ "%W": "()"
+Style/PerlBackrefs:
+ Enabled: false # reason: an important language feature
+Style/QuotedSymbols:
+ Enabled: true
+Style/RedundantArgument:
+ Enabled: true
+Style/RedundantAssignment:
+ Enabled: true
+Style/RedundantBegin:
+ Enabled: true
+ Exclude: [ test/*.rb ] # TODO remove once support for Ruby < 2.5 is dropped; rule does not allow exception for blocks
+Style/RedundantFetchBlock:
+ Enabled: true
+Style/RedundantFileExtensionInRequire:
+ Enabled: true
+Style/RedundantPercentQ:
+ Enabled: false # reason: needed to escape strings with both single and double quotes
+Style/RedundantRegexpCharacterClass:
+ Enabled: true
+Style/RedundantRegexpEscape:
+ Enabled: true
+Style/RedundantSelfAssignment:
+ Enabled: true
+Style/RegexpLiteral:
+ Enabled: true
+ Exclude: [ test/*.rb ]
+Style/RescueModifier:
+ Enabled: false # reason: a useful language feature
+Style/RescueStandardError:
+ EnforcedStyle: implicit
+Style/MissingRespondToMissing:
+ Enabled: true
+Style/SafeNavigation:
+ Enabled: false # FIXME reenable in Asciidoctor 3
+Style/SingleArgumentDig:
+ Enabled: true
+Style/SlicingWithRange:
+ Enabled: true
+Style/SoleNestedConditional:
+ Enabled: false # FIXME reenable to catch some helpful fixes, but causes RuboCop to crash
+Style/SpecialGlobalVars:
+ EnforcedStyle: use_perl_names
+Style/StderrPuts:
+ Enabled: true
+ Exclude: [ lib/asciidoctor/cli/options.rb ]
+Style/StringChars:
+ Enabled: true
+Style/StringConcatenation:
+ Enabled: false # reason: string concatenation can be faster
+Style/SwapValues:
+ Enabled: true
+Style/SymbolArray:
+ EnforcedStyle: brackets
+Style/SymbolProc:
+ Enabled: false # reason: using a symbol proc is measurably slower than using a block in Opal and Ruby < 3
+Style/TernaryParentheses:
+ Enabled: true
+ EnforcedStyle: require_parentheses_when_complex
+Style/TrailingCommaInArrayLiteral:
+ EnforcedStyleForMultiline: consistent_comma
+Style/TrailingCommaInHashLiteral:
+ EnforcedStyleForMultiline: consistent_comma
+Style/WordArray:
+ Enabled: true
diff --git a/Gemfile b/Gemfile
index 37339965..0aeff54e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,6 +31,12 @@ end
# gem 'listen', :github => 'guard/listen'
#end
+group :lint do
+ gem 'rubocop', '~> 1.18.0', require: false
+ gem 'rubocop-minitest', '~> 0.14.0', require: false
+ gem 'rubocop-rake', '~> 0.6.0', require: false
+end unless (Gem::Version.new RUBY_VERSION) < (Gem::Version.new '2.5.0')
+
group :ci do
gem 'json', '~> 2.2.0' if RUBY_ENGINE == 'truffleruby'
gem 'simplecov', '~> 0.16.0'
diff --git a/lib/asciidoctor/abstract_block.rb b/lib/asciidoctor/abstract_block.rb
index bbe03c44..e2d28ba3 100644
--- a/lib/asciidoctor/abstract_block.rb
+++ b/lib/asciidoctor/abstract_block.rb
@@ -284,7 +284,7 @@ class AbstractBlock < AbstractNode
# Returns the converted String title for this Block, or nil if the source title is falsy
def title
# prevent substitutions from being applied to title multiple times
- @converted_title ||= @title && (apply_title_subs @title)
+ @converted_title ||= @title && (apply_title_subs @title) # rubocop:disable Naming/MemoizedInstanceVariableName
end
# Public: A convenience method that checks whether the title of this block is defined.
@@ -384,7 +384,7 @@ class AbstractBlock < AbstractNode
#
# Returns nothing.
def assign_caption value, caption_context = @context
- unless @caption || !@title || (@caption = value || @document.attributes['caption'])
+ unless @caption || !@title || (@caption = value || @document.attributes['caption']) # rubocop:disable Style/GuardClause
if (attr_name = CAPTION_ATTRIBUTE_NAMES[caption_context]) && (prefix = @document.attributes[attr_name])
@caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter %(#{caption_context}-number), self}. )
nil
diff --git a/lib/asciidoctor/abstract_node.rb b/lib/asciidoctor/abstract_node.rb
index 95d2792f..055809b6 100644
--- a/lib/asciidoctor/abstract_node.rb
+++ b/lib/asciidoctor/abstract_node.rb
@@ -158,7 +158,7 @@ class AbstractNode
# name - the String name of the option
#
# Returns nothing
- def set_option name
+ def set_option name # rubocop:disable Naming/AccessorMethodName
@attributes[%(#{name}-option)] = ''
nil
end
diff --git a/lib/asciidoctor/cli/invoker.rb b/lib/asciidoctor/cli/invoker.rb
index 4f98f948..3c2f758e 100644
--- a/lib/asciidoctor/cli/invoker.rb
+++ b/lib/asciidoctor/cli/invoker.rb
@@ -132,7 +132,7 @@ module Asciidoctor
end
end
@code = 1 if (logger.respond_to? :max_severity) && logger.max_severity && logger.max_severity >= opts[:failure_level]
- rescue ::Exception => e
+ rescue ::Exception => e # rubocop:disable Lint/RescueException
if ::SignalException === e
@code = e.signo
# add extra newline if Ctrl+C is used
diff --git a/lib/asciidoctor/cli/options.rb b/lib/asciidoctor/cli/options.rb
index 78a8bc89..02018767 100644
--- a/lib/asciidoctor/cli/options.rb
+++ b/lib/asciidoctor/cli/options.rb
@@ -158,7 +158,7 @@ module Asciidoctor
return 1
end
# Ruby 2.3 requires the extra brackets around the ::File.join method call
- elsif ::File.exist? (manpage_path = (::File.join ROOT_DIR, 'man', 'asciidoctor.1'))
+ elsif ::File.exist? (manpage_path = (::File.join ROOT_DIR, 'man', 'asciidoctor.1')) # rubocop:disable Lint/ParenthesesAsGroupedExpression
$stdout.puts ::File.read manpage_path
else
manpage_path = %x(man -w asciidoctor).chop rescue ''
@@ -174,7 +174,7 @@ module Asciidoctor
end
when 'syntax'
# Ruby 2.3 requires the extra brackets around the ::File.join method call
- if ::File.exist? (syntax_path = (::File.join ROOT_DIR, 'data', 'reference', 'syntax.adoc'))
+ if ::File.exist? (syntax_path = (::File.join ROOT_DIR, 'data', 'reference', 'syntax.adoc')) # rubocop:disable Lint/ParenthesesAsGroupedExpression
$stdout.puts ::File.read syntax_path
else
$stderr.puts 'asciidoctor: FAILED: syntax page not found; visit https://asciidoctor.org/docs'
@@ -227,7 +227,7 @@ module Asciidoctor
end
infiles.reject {|file| file == '-' }.each do |file|
- begin
+ begin # rubocop:disable Style/RedundantBegin
fstat = ::File.stat file
if fstat.file? || fstat.pipe?
unless fstat.readable?
@@ -270,7 +270,7 @@ module Asciidoctor
if (requires = self[:requires])
requires.uniq!
requires.each do |path|
- begin
+ begin # rubocop:disable Style/RedundantBegin
require path
rescue ::LoadError
raise $! if self[:trace]
diff --git a/lib/asciidoctor/converter/html5.rb b/lib/asciidoctor/converter/html5.rb
index 89f62b38..a8e73de1 100644
--- a/lib/asciidoctor/converter/html5.rb
+++ b/lib/asciidoctor/converter/html5.rb
@@ -1070,12 +1070,12 @@ Your browser does not support the audio tag.
# parse video_id/list_id syntax where list_id (i.e., playlist) is optional
target, list = (node.attr 'target').split '/', 2
- if (list ||= (node.attr 'list'))
+ if (list ||= node.attr 'list') # rubocop:disable Style/ParenthesesAroundCondition
list_param = %(&amp;list=#{list})
else
# parse dynamic playlist syntax: video_id1,video_id2,...
target, playlist = target.split ',', 2
- if (playlist ||= (node.attr 'playlist'))
+ if (playlist ||= node.attr 'playlist') # rubocop:disable Style/ParenthesesAroundCondition
# INFO playlist bar doesn't appear in Firefox unless showinfo=1 and modestbranding=1
list_param = %(&amp;playlist=#{playlist})
else
diff --git a/lib/asciidoctor/document.rb b/lib/asciidoctor/document.rb
index 9ff21462..e88fe824 100644
--- a/lib/asciidoctor/document.rb
+++ b/lib/asciidoctor/document.rb
@@ -83,7 +83,7 @@ module Asciidoctor
# can take the process to completion by calling the {Document#convert} method.
class Document < AbstractBlock
ImageReference = ::Struct.new :target, :imagesdir do
- alias to_s target
+ alias to_s target # rubocop:disable Style/Alias
end
Footnote = ::Struct.new :index, :id, :text
diff --git a/lib/asciidoctor/load.rb b/lib/asciidoctor/load.rb
index bbb8e9d1..8c5f40c9 100644
--- a/lib/asciidoctor/load.rb
+++ b/lib/asciidoctor/load.rb
@@ -49,7 +49,7 @@ module Asciidoctor
end
elsif (attrs.respond_to? :keys) && (attrs.respond_to? :[])
# coerce attrs to a real Hash
- attrs = {}.tap {|accum| attrs.keys.each {|k| accum[k] = attrs[k] } }
+ attrs = {}.tap {|accum| attrs.keys.each {|k| accum[k] = attrs[k] } } # rubocop:disable Style/HashEachMethods
else
raise ::ArgumentError, %(illegal type for attributes option: #{attrs.class.ancestors.join ' < '})
end
diff --git a/lib/asciidoctor/logging.rb b/lib/asciidoctor/logging.rb
index 84e9f185..9d255412 100644
--- a/lib/asciidoctor/logging.rb
+++ b/lib/asciidoctor/logging.rb
@@ -99,8 +99,8 @@ module LoggerManager
def memoize_logger
class << self
- alias logger logger # suppresses warning from CRuby
- attr_reader :logger
+ alias logger logger # suppresses warning from CRuby # rubocop:disable Style/Alias
+ attr_reader :logger # rubocop:disable Lint/DuplicateMethods
end
end
end
diff --git a/lib/asciidoctor/parser.rb b/lib/asciidoctor/parser.rb
index a2a52969..f042b98b 100644
--- a/lib/asciidoctor/parser.rb
+++ b/lib/asciidoctor/parser.rb
@@ -522,7 +522,7 @@ class Parser
block_context = style.to_sym
elsif delimited_block.masq.include?('admonition') && ADMONITION_STYLES.include?(style)
block_context = :admonition
- elsif block_extensions && extensions.registered_for_block?(style, block_context)
+ elsif block_extensions && extensions.registered_for_block?(style, block_context) # rubocop:disable Lint/DuplicateBranch
block_context = style.to_sym
else
logger.debug message_with_context %(unknown style for #{block_context} block: #{style}), source_location: reader.cursor_at_mark if logger.debug?
@@ -537,7 +537,7 @@ class Parser
# this loop is used for flow control; it only executes once, and only when delimited_block is not set
# break once a block is found or at end of loop
# returns nil if the line should be dropped
- while true
+ while true # rubocop:disable Lint/UnreachableLoop
# process lines verbatim
if style && Compliance.strict_verbatim_paragraphs && (VERBATIM_STYLES.include? style)
block_context = style.to_sym
@@ -712,7 +712,7 @@ class Parser
reader.unshift_line this_line
# advance to block parsing =>
break
- elsif block_extensions && extensions.registered_for_block?(style, :paragraph)
+ elsif block_extensions && extensions.registered_for_block?(style, :paragraph) # rubocop:disable Lint/DuplicateBranch
block_context = style.to_sym
cloaked_context = :paragraph
reader.unshift_line this_line
@@ -781,7 +781,7 @@ class Parser
attribution, citetitle = (block.apply_subs credit_line).split ', ', 2
attributes['attribution'] = attribution if attribution
attributes['citetitle'] = citetitle if citetitle
- else
+ else # rubocop:disable Lint/DuplicateBranch
# if [normal] is used over an indented paragraph, shift content to left margin
# QUESTION do we even need to shift since whitespace is normalized by XML in this case?
adjust_indentation! lines if indented && style == 'normal'
@@ -981,7 +981,7 @@ class Parser
end
# NOTE line matches the tip when delimiter is minimum length or fenced code
context, masq = DELIMITED_BLOCKS[tip]
- if context && (line_len == tip_len || (uniform? (line.slice 1, line_len), DELIMITED_BLOCK_TAILS[tip], (line_len - 1)))
+ if context && (line_len == tip_len || (uniform? (line.slice 1, line_len), DELIMITED_BLOCK_TAILS[tip], (line_len - 1))) # rubocop:disable Style/GuardClause
return_match_data ? (BlockMatchData.new context, masq, tip, line) : true
end
end
@@ -2029,7 +2029,7 @@ class Parser
return true
end
elsif !normal || (next_line.start_with? '/')
- if next_line == '//'
+ if next_line == '//' # rubocop:disable Style/GuardClause
return true
elsif normal && (uniform? next_line, '/', (ll = next_line.length))
unless ll == 3
@@ -2366,7 +2366,7 @@ class Parser
end
# NOTE cell may already be closed if table format is csv or dsv
- if parser_ctx.cell_open?
+ if parser_ctx.cell_open? # rubocop:disable Style/GuardClause
parser_ctx.close_cell true unless table_reader.has_more_lines?
else
table_reader.skip_blank_lines || break
diff --git a/lib/asciidoctor/path_resolver.rb b/lib/asciidoctor/path_resolver.rb
index 3e620775..1e526286 100644
--- a/lib/asciidoctor/path_resolver.rb
+++ b/lib/asciidoctor/path_resolver.rb
@@ -378,7 +378,7 @@ class PathResolver
end
if target_segments.empty?
- if start.nil_or_empty?
+ if start.nil_or_empty? # rubocop:disable Style/GuardClause
return jail || @working_dir
elsif root? start
return expand_path start unless jail
diff --git a/lib/asciidoctor/substitutors.rb b/lib/asciidoctor/substitutors.rb
index 458c3ab9..ffa20bc5 100644
--- a/lib/asciidoctor/substitutors.rb
+++ b/lib/asciidoctor/substitutors.rb
@@ -785,7 +785,7 @@ module Substitutors
else
fragment = refid
end
- else
+ else # rubocop:disable Lint/DuplicateBranch
fragment = refid
end
@@ -917,7 +917,7 @@ module Substitutors
#
# Returns the converted String text
def sub_callouts text
- callout_rx = (attr? 'line-comment') ? CalloutSourceRxMap[attr 'line-comment'] : CalloutSourceRx
+ callout_rx = (attr? 'line-comment') ? CalloutSourceRxMap[attr 'line-comment'] : CalloutSourceRx # rubocop:disable Naming/MethodName
autonum = 0
text.gsub callout_rx do
# honor the escape
@@ -1351,7 +1351,7 @@ module Substitutors
callout_marks = {}
autonum = lineno = 0
last_lineno = nil
- callout_rx = (attr? 'line-comment') ? CalloutExtractRxMap[attr 'line-comment'] : CalloutExtractRx
+ callout_rx = (attr? 'line-comment') ? CalloutExtractRxMap[attr 'line-comment'] : CalloutExtractRx # rubocop:disable Naming/MethodName
# extract callout marks, indexed by line number
source = (source.split LF, -1).map do |line|
lineno += 1
@@ -1452,8 +1452,8 @@ module Substitutors
# Internal: Substitute replacement text for matched location
#
# returns The String text with the replacement characters substituted
- def do_replacement m, replacement, restore
- if (captured = m[0]).include? RS
+ def do_replacement match, replacement, restore
+ if (captured = match[0]).include? RS
# we have to use sub since we aren't sure it's the first char
captured.sub RS, ''
else
@@ -1461,9 +1461,9 @@ module Substitutors
when :none
replacement
when :bounding
- m[1] + replacement + m[2]
+ match[1] + replacement + match[2]
else # :leading
- m[1] + replacement
+ match[1] + replacement
end
end
end
diff --git a/lib/asciidoctor/syntax_highlighter/pygments.rb b/lib/asciidoctor/syntax_highlighter/pygments.rb
index 1fbb347a..936bbb97 100644
--- a/lib/asciidoctor/syntax_highlighter/pygments.rb
+++ b/lib/asciidoctor/syntax_highlighter/pygments.rb
@@ -138,7 +138,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
LinenoSpanTagCs = '<span class="lineno">\1 </span>'
PreTagCs = '<pre>\1</pre>'
StyledLinenoColumnStartTagsRx = /<td><div class="linenodiv" style="[^"]+?"><pre style="[^"]+?">/
- StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>)
+ StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>) # rubocop:disable Lint/MixedRegexpCaptureTypes
WRAPPER_CLASS = 'lineno' # doesn't appear in output; Pygments appends "table" to this value to make nested table class
# NOTE <pre> has style attribute when pygments-css=style
# NOTE <div> has trailing newline when pygments-linenums-mode=table
diff --git a/lib/asciidoctor/table.rb b/lib/asciidoctor/table.rb
index 42bf2712..f55bfefa 100644
--- a/lib/asciidoctor/table.rb
+++ b/lib/asciidoctor/table.rb
@@ -533,7 +533,7 @@ class Table::ParserContext
#
# returns true if the buffer has unclosed quotes, false if it doesn't or it
# isn't quoted data
- def buffer_has_unclosed_quotes? append = nil, q = '"'
+ def buffer_has_unclosed_quotes? append = nil, q = '"' # rubocop:disable Naming/MethodParameterName
if (record = append ? (@buffer + append).strip : @buffer.strip) == q
true
elsif record.start_with? q
diff --git a/tasks/rubocop.rake b/tasks/rubocop.rake
new file mode 100644
index 00000000..4560af88
--- /dev/null
+++ b/tasks/rubocop.rake
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+begin
+ require 'rubocop/rake_task'
+ RuboCop::RakeTask.new :lint do |t|
+ #t.patterns = %w(lib/**/*.rb Rakefile Gemfile tasks/*.rake)
+ t.patterns = %w(lib/**/*.rb test/*.rb features/*.rb Rakefile Gemfile tasks/*.rake)
+ end
+rescue LoadError => e
+ task :lint do
+ raise 'Failed to load lint task.
+Install required gems using: bundle --path=.bundle/gems
+Then, invoke Rake using: bundle exec rake', cause: e
+ end
+end
diff --git a/test/api_test.rb b/test/api_test.rb
index 72581e1b..c504897a 100644
--- a/test/api_test.rb
+++ b/test/api_test.rb
@@ -178,7 +178,7 @@ context 'API' do
test 'should accept attributes as array' do
# NOTE there's a tab character before idseparator
- doc = Asciidoctor.load('text', attributes: %w(toc sectnums source-highlighter=coderay idprefix idseparator=-))
+ doc = Asciidoctor.load('text', attributes: %w(toc sectnums source-highlighter=coderay idprefix idseparator=-)) # rubocop:disable Layout/SpaceInsideArrayPercentLiteral
assert_kind_of Hash, doc.attributes
assert doc.attr?('toc')
assert_equal '', doc.attr('toc')
diff --git a/test/extensions_test.rb b/test/extensions_test.rb
index 8b7a8e9e..6d22d238 100644
--- a/test/extensions_test.rb
+++ b/test/extensions_test.rb
@@ -809,7 +809,7 @@ context 'Extensions' do
end
end
- prefer (tree_processor do
+ prefer (tree_processor do # rubocop:disable Lint/ParenthesesAsGroupedExpression
process do |doc|
doc << (create_paragraph doc, 'a', {})
nil
@@ -926,7 +926,7 @@ context 'Extensions' do
block :eval do |processor|
processor.on_context :literal
processor.process do |parent, reader, _attrs|
- create_paragraph parent, (eval reader.read_lines[0]), {}
+ create_paragraph parent, (eval reader.read_lines[0]), {} # rubocop:disable Security/Eval
end
end
end
diff --git a/test/invoker_test.rb b/test/invoker_test.rb
index b9858d3c..75350181 100644
--- a/test/invoker_test.rb
+++ b/test/invoker_test.rb
@@ -174,7 +174,7 @@ context 'Invoker' do
end
warnings = err.string
end
- assert_equal false, $VERBOSE
+ assert_equal false, $VERBOSE # rubocop:disable Minitest/RefuteFalse
refute_empty warnings
ensure
$VERBOSE = old_verbose
diff --git a/test/logger_test.rb b/test/logger_test.rb
index 58399875..bc03689e 100644
--- a/test/logger_test.rb
+++ b/test/logger_test.rb
@@ -148,7 +148,7 @@ context 'Logger' do
test 'including Logging gives instance methods on module access to logging infrastructure' do
module SampleModuleA
include Asciidoctor::Logging
- def get_logger
+ def retrieve_logger
logger
end
end
@@ -156,42 +156,42 @@ context 'Logger' do
class SampleClassA
include SampleModuleA
end
- assert_same Asciidoctor::LoggerManager.logger, SampleClassA.new.get_logger
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassA.new.retrieve_logger
assert SampleClassA.public_method_defined? :logger
end
test 'including Logging gives static methods on module access to logging infrastructure' do
module SampleModuleB
include Asciidoctor::Logging
- def self.get_logger
+ def self.retrieve_logger
logger
end
end
- assert_same Asciidoctor::LoggerManager.logger, SampleModuleB.get_logger
+ assert_same Asciidoctor::LoggerManager.logger, SampleModuleB.retrieve_logger
end
test 'including Logging gives instance methods on class access to logging infrastructure' do
class SampleClassC
include Asciidoctor::Logging
- def get_logger
+ def retrieve_logger
logger
end
end
- assert_same Asciidoctor::LoggerManager.logger, SampleClassC.new.get_logger
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassC.new.retrieve_logger
assert SampleClassC.public_method_defined? :logger
end
test 'including Logging gives static methods on class access to logging infrastructure' do
class SampleClassD
include Asciidoctor::Logging
- def self.get_logger
+ def self.retrieve_logger
logger
end
end
- assert_same Asciidoctor::LoggerManager.logger, SampleClassD.get_logger
+ assert_same Asciidoctor::LoggerManager.logger, SampleClassD.retrieve_logger
end
test 'can create an auto-formatting message with context' do
diff --git a/test/test_helper.rb b/test/test_helper.rb
index b59ef861..ca0baf6a 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -197,7 +197,7 @@ class Minitest::Test
Nokogiri::HTML::DocumentFragment.parse content
elsif $1.start_with? 'html'
Nokogiri::HTML::Document.parse content
- else
+ else # rubocop:disable Lint/DuplicateBranch
Nokogiri::XML::Document.parse content
end
end