# Configuration for perlcritic source code analysis.  -*- conf -*-
#
# Many of the Perl::Critic policies are excellent starting points for new code
# so as to directly enforce conventional, easier to read and modern constructs.
# However, as most of the Perl INN code base predates the use of Perl::Critic,
# and given that the policies are mostly just style and not about actual bugs,
# many exclusions are listed in this configuration file.
#
# The idea is to progressively treat the violations while modernizing or
# modifying parts of existing Perl code, and to write new code following most
# of these best practices.  Some exceptions will naturally keep existing as
# Perl::Critic is not intended to be used as rigid rules, and fully complying
# to all the policies is probably not practical (and even sometimes in conflict
# with the Perl::Tidy reformatter).
#
# Existing code is kept untouched, and has just been quickly reviewed when
# excluding the policies below to ensure there were not any real bugs to fix.
#
# Some useful links:
#     https://metacpan.org/pod/Perl::Critic::Community
#     https://metacpan.org/pod/Perl::Critic::PolicySummary
#     https://metacpan.org/pod/Perl::Critic::Pulp
#     https://perlmaven.com/perl-critic

# Check all the policies.
severity = 1

# Custom output.
verbose = %f:%l:%c: [%p] %m, near '%r' (%e, Severity: %s)\n

# Perl::Critic::Freenode has been renamed upstream to Perl::Critic::Community
# but some systems may still have both installed.  The related tests would then
# be run twice and report issues for yet excluded policies in the community
# theme.
exclude = Freenode::

# Uncomment to only apply policies explicitly listed below as enabled.
# It is easier for tests than using the --single-policy flag.
#only = 1

# Uncomment to ignore "## no critic" annotations in the source code.
#force = 1


##################################
# Configuration of some policies #
##################################

# Prefer the use of qw() to declare a list of one-word literals.
[CodeLayout::ProhibitQuotedWordLists]
min_elements = 1
strict = 1

# tunefeed and innreport declare specific sorting functions.
[Community::DollarAB]
extra_pair_functions = by_hierarchy DateCompare

# INN requires at least Perl 5.6.0.
# An optional Perl module (INN::ovsqlite_client) needs 5.8.0 though.
[Compatibility::PerlMinimumVersionAndWhy]
above_version = 5.006

# INN requires at least Perl 5.12.0 to generate documentation from POD due to
# the use of L<> links with URL and text, Perl 5.10.0 due to the =encoding
# command, and Perl 5.8.0 due to L<> links to URL.  Most of the documentation
# can be generated with Perl 5.6.0 though.
[Compatibility::PodMinimumVersion]
above_version = 5.012

# We still have some qx() calls.
[InputOutput::ProhibitBacktickOperators]
only_in_void_context = 1

# innreport_inn.pm has long regex lines.
[RegularExpressions::RequireExtendedFormatting]
minimum_regex_length_to_complain_about = 62

# Shlock provides a lock function.
[Subroutines::ProhibitBuiltinHomonyms]
allow = lock


###################################
# Excluded policies of severity 5 #
###################################

# If there were only one currently excluded policy to enforce, it would be this
# one.  We have lots of calls to open in its one or two-argument legacy form.
# These calls should be secured.  At the same time, we should also get rid of
# the legacy syntax of bareword file handles.
[-InputOutput::ProhibitTwoArgOpen]

# The following policies are mostly related to style.  The current code works
# fine.  Enforcing them is of low priority, but patches are naturally welcome
# if someone wishes to work on them.  (Note that the code should remain
# compatible with Perl 5.8.0 and its core modules.)
[-BuiltinFunctions::ProhibitStringyEval]
[-ControlStructures::ProhibitMutatingListFunctions]
[-InputOutput::ProhibitBarewordDirHandles]
[-InputOutput::ProhibitBarewordFileHandles]
[-InputOutput::ProhibitInteractiveTest]

# Package declarations are correct: innshellvars.pl declares itself as the inn
# package for legacy reasons, and Config.pm is generated at configure time from
# Config.pm.in.
[-Modules::RequireFilenameMatchesPackage]

# Subroutine prototypes do not harm, and are even valuable hints used by some
# Perl::Tidy checks.
[-Subroutines::ProhibitSubroutinePrototypes]

# The majority of our Perl scripts already has strictures enabled.
# Only a few ones still lack it (innshellvars.pl, testListener.pl, some contrib
# scripts and some samples of Perl hooks).
# At some point, they should be added and the scripts tested with them.
[-TestingAndDebugging::ProhibitNoStrict]
[-TestingAndDebugging::RequireUseStrict]


###################################
# Excluded policies of severity 4 #
###################################

# The majority of our Perl scripts already has warnings enabled.
# Only a few ones still lack it (buildconfig, innreport, innshellvars.pl,
# testListener.pl, some contrib scripts and some samples of Perl hooks).
# At some point, they should be added and the scripts tested with them.
[-Community::StrictWarnings]
[-TestingAndDebugging::RequireUseWarnings]

# The following policies are mostly related to style.  Enforcing them is of low
# priority, but patches are naturally welcome if someone wishes to work on
# them.  Maybe the BarewordFilehandles and WhileDiamondDefaultAssignment
# policies would be the most useful to tackle.
[-Community::AmpersandSubCalls]
[-Community::BarewordFilehandles]
[-Community::WhileDiamondDefaultAssignment]
[-InputOutput::ProhibitExplicitStdin]
[-InputOutput::ProhibitOneArgSelect]
[-InputOutput::RequireBriefOpen]
[-Modules::RequireExplicitPackage]
[-Subroutines::RequireArgUnpacking]
[-Subroutines::RequireFinalReturn]
[-ValuesAndExpressions::ProhibitConstantPragma]
[-Variables::ProhibitMatchVars]
[-Variables::RequireLocalizedPunctuationVars]


###################################
# Excluded policies of severity 3 #
###################################

# The following policies may be worthwhile enforcing as they may uncover
# unnoticed issues.
[-InputOutput::RequireCheckedOpen]
[-RegularExpressions::ProhibitCaptureWithoutTest]
[-ValuesAndExpressions::ProhibitMismatchedOperators]
[-Variables::RequireInitializationForLocalVars]

# Switching to "use Exporter 5.57 qw(import)" would require Perl 5.8.3,
# and "use parent qw(Exporter)" would require Perl 5.10.1.  So let's just
# keep manipulating @ISA.
[-ClassHierarchies::ProhibitExplicitISA]

# Similar to policies of higher severity (InputOutput::ProhibitTwoArgOpen and
# Subroutines::ProhibitSubroutinePrototypes).
[-Community::OpenArgs]
[-Community::Prototypes]

# Perl 5.14.0 fixed the underlying issue (preserving the value of $@ even if
# destructors run at exit from the eval block).
[-ErrorHandling::RequireCheckingReturnValueOfEval]

# The following policies are mostly related to style.
[-BuiltinFunctions::ProhibitComplexMappings]
[-BuiltinFunctions::ProhibitVoidMap]
[-ControlStructures::ProhibitCascadingIfElse]
[-ControlStructures::ProhibitDeepNests]
[-ErrorHandling::RequireCarping]
[-InputOutput::ProhibitJoinedReadline]
[-Modules::ProhibitExcessMainComplexity]
[-NamingConventions::ProhibitAmbiguousNames]
[-RegularExpressions::ProhibitComplexRegexes]
[-RegularExpressions::ProhibitUnusedCapture]
[-Subroutines::ProhibitExcessComplexity]
[-Subroutines::ProhibitManyArgs]
[-ValuesAndExpressions::ProhibitComplexVersion]
[-ValuesAndExpressions::ProhibitFiletest_f]
[-ValuesAndExpressions::ProhibitImplicitNewlines]
[-ValuesAndExpressions::RequireNumericVersion]
[-Variables::ProhibitPackageVars]


###################################
# Excluded policies of severity 2 #
###################################

# This policy may be worthwhile enforcing when Perl 5.10.0 is the minimum
# required version for INN as List::Util is not shipped as a core module in
# previous versions.
# Anyway, it won't drastically optimize the speed of programs!
[-BuiltinFunctions::ProhibitBooleanGrep]

# perltidy already takes care of it.  Besides, there are false positives in
# innreport.
[-CodeLayout::RequireFinalSemicolon]

# perltidy takes care of the preferred formatting with regards to trailing
# commas.  Its -dwic flag omits the comma if there is a single argument so that
# the call will be collapsed to a single line if it will fit whereas this
# policy always wants it.
[-CodeLayout::RequireTrailingCommaAtNewline]

# Getopt::Std is still used and fits our needs.
[-Community::PreferredAlternatives]

# The following policies are mostly related to style.
[-BuiltinFunctions::ProhibitUselessTopic]
[-ControlStructures::ProhibitCStyleForLoops]
[-ControlStructures::ProhibitPostfixControls]
[-ControlStructures::ProhibitUnlessBlocks]
[-Documentation::RequirePodSections]
[-InputOutput::RequireCheckedClose]
[-Miscellanea::ProhibitTies]
[-Modules::RequireVersionVar]
[-References::ProhibitDoubleSigils]
[-RegularExpressions::ProhibitFixedStringMatches]
[-RegularExpressions::ProhibitUselessTopic]
[-RegularExpressions::RequireDotMatchAnything]
[-RegularExpressions::RequireLineBoundaryMatching]
[-Subroutines::ProhibitAmpersandSigils]
[-ValuesAndExpressions::ProhibitEmptyQuotes]
[-ValuesAndExpressions::ProhibitEscapedCharacters]
[-ValuesAndExpressions::ProhibitMagicNumbers]
[-ValuesAndExpressions::ProhibitNoisyQuotes]
[-ValuesAndExpressions::RequireConstantVersion]
[-ValuesAndExpressions::RequireNumberSeparators]
[-Variables::ProhibitPunctuationVars]


###################################
# Excluded policies of severity 1 #
###################################

# Maybe to look at after InputOutput::RequireCheckedOpen is enforced.
[-InputOutput::RequireCheckedSyscalls]

# May be worthwhile enforcing to improve readability.
[-RegularExpressions::ProhibitUnusualDelimiters]
[-RegularExpressions::RequireBracesForMultiline]

# Style not followed as we prefer to homogenize with C code.
[-CodeLayout::ProhibitParensWithBuiltins]

# Already handled by the maintainers of INN.  Unknown flags from recent
# versions of perltidy may be reported by this policy, so we exclude it.
[-CodeLayout::RequireTidyCode]

# This policy conflicts with Subroutines::ProhibitExplicitReturnUndef.
[-Community::EmptyReturn]

# We often use enumerated classes for ASCII characters or hexadecimal numbers.
[-RegularExpressions::ProhibitEnumeratedClasses]

# False positives for BEGIN blocks.
# https://github.com/gugod/Perl-Critic-TooMuchCode/issues/40
[-TooMuchCode::ProhibitDuplicateSub]

# The following policies are mostly related to style.
[-InputOutput::RequireBracedFileHandleWithPrint]
[-NamingConventions::Capitalization]
[-RegularExpressions::ProhibitEscapedMetacharacters]
[-TooMuchCode::ProhibitDuplicateLiteral]
[-TooMuchCode::ProhibitLargeBlock]
[-ValuesAndExpressions::ProhibitInterpolationOfLiterals]
[-ValuesAndExpressions::RequireInterpolationOfMetachars]
