# This file is used for running Perl::Critic on Perl::Tidy modules.  Many of
# the policies are excellent starting points for new code, but important
# exceptions often exist which make it impossible to use them as rigid rules.

# I have found the '## no critic' method for locally deactivating specific
# policies to be far too troublesome to use.  So policies without fine tuning
# controls have to either be 'on' or 'off'.

# Some useful links:
# https://metacpan.org/dist/Perl-Critic/view/lib/Perl/Critic/PolicySummary.pod
# https://metacpan.org/pod/Perl::Critic::PolicySummary
# https://manpages.ubuntu.com/manpages/xenial/man1/perlcritic.1p.html
# https://perlmaven.com/perl-critic

# Example command to run a single policy on single module:
# perlcritic --single-policy Subroutines::ProhibitSubroutinePrototypes Module.pm

# severity = 1 gives the most strict checking.
severity = 1

verbose = %f: [%p] %m at line %l, column %c.\n

#---------------------------------------------------
# Policies to be skipped or adjusted for severity=4:
#---------------------------------------------------

# Tidy.pm exports 'perltidy'. Changing this could break existing scripts.
[-Modules::ProhibitAutomaticExportation]

# Make an exception for very short time-critical subs.
[Subroutines::RequireArgUnpacking]
short_subroutine_statements = 2

# Disagree: The advantages of 'use constant' greatly outweigh the few
# disadvantages.  Perl::Tidy relies heavily on constants
#  -for efficient and robust coding of array indexes,
#  -for avoiding autovivication issues if hashes were used instead,
#  -and for eliminating debug code during compilation.
[-ValuesAndExpressions::ProhibitConstantPragma]

# Disagree: adding quotes on here doc terminators causes needless "line noise"
# in the source code.  Almost always the default works.  Besides, my editor
# uses color to make it clear if interpolation is in effect.
[-ValuesAndExpressions::RequireQuotedHeredocTerminator]

# Perlcritic doesn't seem to see that @ARGV in Perl::Tidy actually **is**
# localized.  Localization of @ARGV could be avoided by calling
# GetOptionsFromArray instead of GetOptions, but that is not available before
# perl 5.10, and we want to continue supporting Perl 5.8. So we have to skip
# this for now.  When the time comes to make perl 5.10 the earliest version
# supported, this restriction can be deleted
[-Variables::RequireLocalizedPunctuationVars]

# Set the line limit a bit higher for sub 'backup_method_copy' in Perl::Tidy.pm
# which has about 25 lines between open and close, largely comments.
[InputOutput::RequireBriefOpen]
lines=30

# Perltidy modules IOScalar.pm and IOScalarArray.pm provide a print function,
# but I had to turn this off because the 'allow' option does not seem to work
[-Subroutines::ProhibitBuiltinHomonyms]
# allow=print

#---------------------------------------------------
# Policies to be skipped or adjusted for severity=3:
#---------------------------------------------------

# AUTOLOAD is used in perltidy to help find and debug programming errors rather
# than doing autoloading.  This is very useful, so we have to skip this.
[-ClassHierarchies::ProhibitAutoloading]

# This policy is useful in locating complex code which might benefit from
# simplification.  But it has been deactivated here because the mccabe
# number is not a good measure of complexity of a sub which contains a number
# of anonymous subs. A more useful number is the value 'mccabe2' which can
# be optained with: perltidy -dbs file.pl >file.csv. For example, sub
# 'scan_hash_keys' in perltidy has mccabe1=302 but mccabe2=130.
[-Subroutines::ProhibitExcessComplexity]
# max_mccabe=310

# This policy can be very helpful for locating complex code, but sometimes
# deep nests are the best option, especially in error handling and debug
# coding. So a large value is used here.
# sub Formatter::count_list_elements currently needs 10, several others need 9
[ControlStructures::ProhibitDeepNests]
max_nests=10

# Agree that cascading elses are best avoided, but in reality there are a lot
# of cases where they cannot be avoided.
[-ControlStructures::ProhibitCascadingIfElse]

# This is a good general policy but the default max of 5 args is not always
# possible in time-critical subs. One sub in perltidy has 11 args.
[Subroutines::ProhibitManyArgs]
max_arguments = 11
skip_object = 1

[-ClassHierarchies::ProhibitExplicitISA]

# There is one complex regex in Tokenizer.pm for scanning numbers. It is
# well commented and easy to read, and any changes would make it harder
# to read. But rather than deactivate this policy, I have adjusted the
# maximum number of characters to let this regex pass.
[RegularExpressions::ProhibitComplexRegexes]
max_characters=250

# A problem with ReqireExtendedFormatting is that it makes things needlessly
# complex when matching things like line feeds and carriage returns.
[-RegularExpressions::RequireExtendedFormatting]

#---------------------------------------------------
# Policies to be skipped or adjusted for severity=2:
#---------------------------------------------------

# Disagree. In fact, following this policy caused a parsing error in Perl
# version 5.14 at file test operators.  So skip this because it can cause
# loss of code robustness.
[-BuiltinFunctions::ProhibitUselessTopic]

# These would be okay for most new code, but do not change any debugged regular
# expressions without good reason.  It is too easy to introduce a subtle error.
[-RegularExpressions::RequireDotMatchAnything]
[-RegularExpressions::RequireLineBoundaryMatching]

# This is another one of those rules which often works but not always. Is '#'
# really harder to read than q{#}?  And in tokenization code it is often
# necessary to work with symbols like '{' '}' '<' and so on.  So we would need
# q<{> q<}> q{<} and so on, which is hard on the eyes. Also, sometimes
# perlcritic is inconsistent regarding this rule because sometimes wants to
# apply this rule to hash keys, and sometimes not.
[-ValuesAndExpressions::ProhibitNoisyQuotes]

# postfix 'if' is okay if it highlights control flow
# postfix 'unless' is likewise okay if simple and without negative terms
# postfix 'for' is useful for initializing hashes:
#      $hash{$_} = 1 for @list;
[ControlStructures::ProhibitPostfixControls]
allow = for if unless

# This is a good in general but has to be turned off here because there are
# many cases where a number has been explained in a comment or is obvious.
[-ValuesAndExpressions::ProhibitMagicNumbers]
# allowed_values = -2 -1 0 1 2

#---------------------------------------------------
# Policies to be skipped or adjusted for severity=1:
#---------------------------------------------------

# This is a good starting rule, but occasional capitalization can be quite
# effective or appropriate for marking a special variable, so we have to ignore
# it as a general rule:
[-NamingConventions::Capitalization]

# PerlCritic should not suggest this policy for complex sorts because it can
# change program behavior when a stable sort has been assumed.  And it does not
# even make sense for sorts on multiple keys, like this one which got flagged
# in Perl::Tidy
#        @candidates =
#          sort { $b->[1] <=> $a->[1] || $a->[0] <=> $b->[0] } @candidates;
# Changing the first part requires changing the second part, so either way
# you have a comparison of the form $b->[*] <=> $a->[*]. So skip this.
[-BuiltinFunctions::ProhibitReverseSortBlock]

# There are too many of these in perltidy to change, and they seem fine
# and not worth the effort of changing.
[-RegularExpressions::ProhibitEscapedMetacharacters]

# As the documentation says, this policy is not for everyone
[-RegularExpressions::ProhibitEnumeratedClasses]

# Disagree. Double quotes are easier to read than single quotes and
# allow a uniform style for quotes.  My editor has color coding which indicates
# interpolation. Double quotes do not increase processing time by any
# measurable amount.  Using them as default simplfies making editing changes.
# So skip this:
[-ValuesAndExpressions::ProhibitInterpolationOfLiterals]

# Allowing this policy would require adding a whole lot of needless backslash
# characters, thereby making things much harder to read.
[-ValuesAndExpressions::RequireInterpolationOfMetachars]

# Disagree: parens can add clarity and may even be essential, for example in
# ternary expressions. There is little to be gained by omitting them.
[-CodeLayout::ProhibitParensWithBuiltins]

# Exclude 'print' statements, which are mainly used for debug statements
# and error reporting.
[InputOutput::RequireCheckedSyscalls]
exclude_functions = print

# Use a perltidyrc which does some warning checks
[CodeLayout::RequireTidyCode]
perltidyrc = perltidyrc
