Search code examples
perlperl-critic

How to run perl critic from a script with ProhibitExcessComplexity enabled?


How do I run Perl critic from a script with Subroutines::ProhibitExcessComplexity enabled ? I tried the following but it wasn't flagging complex 500+ line subroutines. I do not have a .perlcriticrc(Neither do I want one to be there)

use Perl::Critic;

run_critic('temp.pl');
exit;

sub run_critic {
    my $file   = shift;
    my $critic = Perl::Critic->new(
        -severity => 5,
        -policy   => 'Subroutines::ProhibitExcessComplexity',
        -verbose  => 5,
    );
    my @violations = $critic->critique($file);
    print @violations;
}

My Perl::Critic version is 1.116

perl -MPerl::Critic -e 'print "$Perl::Critic::VERSION\n"'
1.116

Solution

  • View the loaded Policies

    To view the policies that are actually loaded, use Perl::Critic->policies.

    policies()

    Returns a list containing references to all the Policy objects that have been loaded into this engine. Objects will be in the order that they were loaded. If you view your policies, you can see it's not being added:

    You will see your desired policy isn't added to the list:

    use strict;
    use warnings;
    
    use Perl::Critic;
    
    run_critic($0);
    exit;
    
    sub run_critic {
        my $file   = shift;
        my $critic = Perl::Critic->new(
            -severity => 5,
            -policy   => 'Subroutines::ProhibitExcessComplexity',
            -verbose  => 5,
        );
        print $critic->policies();      # View loaded Policies
    
        my @violations = $critic->critique($file);
        print @violations;
    }
    

    Outputs:

    BuiltinFunctions::ProhibitSleepViaSelect
    BuiltinFunctions::ProhibitStringyEval
    BuiltinFunctions::RequireGlobFunction
    ClassHierarchies::ProhibitOneArgBless
    ControlStructures::ProhibitMutatingListFunctions
    InputOutput::ProhibitBarewordFileHandles
    InputOutput::ProhibitInteractiveTest
    InputOutput::ProhibitTwoArgOpen
    InputOutput::RequireEncodingWithUTF8Layer
    Modules::ProhibitEvilModules
    Modules::RequireBarewordIncludes
    Modules::RequireFilenameMatchesPackage
    Subroutines::ProhibitExplicitReturnUndef       
    Subroutines::ProhibitNestedSubs
    Subroutines::ProhibitReturnSort
    Subroutines::ProhibitSubroutinePrototypes
    TestingAndDebugging::ProhibitNoStrict
    TestingAndDebugging::RequireUseStrict
    ValuesAndExpressions::ProhibitLeadingZeros
    Variables::ProhibitConditionalDeclarations
    Variables::RequireLexicalLoopIterators
    

    Proper Configuration option: -include

    The problem is that the Constructor option -policy does not exist.

    Instead you want to use -include:

    -include is a reference to a list of string @PATTERNS. Policy modules that match at least one m/$PATTERN/ixms will always be loaded, irrespective of all other settings. For example:

    Therefore fixing your constructor:

        my $critic = Perl::Critic->new(
            -severity => 5,
            -include  => 'Subroutines::ProhibitExcessComplexity',
            -verbose  => 5,
        );
    

    Outputs:

    BuiltinFunctions::ProhibitSleepViaSelect
    BuiltinFunctions::ProhibitStringyEval
    BuiltinFunctions::RequireGlobFunction
    ClassHierarchies::ProhibitOneArgBless
    ControlStructures::ProhibitMutatingListFunctions
    InputOutput::ProhibitBarewordFileHandles
    InputOutput::ProhibitInteractiveTest
    InputOutput::ProhibitTwoArgOpen
    InputOutput::RequireEncodingWithUTF8Layer
    Modules::ProhibitEvilModules
    Modules::RequireBarewordIncludes
    Modules::RequireFilenameMatchesPackage
    Subroutines::ProhibitExcessComplexity           # <--- ta da
    Subroutines::ProhibitExplicitReturnUndef
    Subroutines::ProhibitNestedSubs
    Subroutines::ProhibitReturnSort
    Subroutines::ProhibitSubroutinePrototypes
    TestingAndDebugging::ProhibitNoStrict
    TestingAndDebugging::RequireUseStrict
    ValuesAndExpressions::ProhibitLeadingZeros
    Variables::ProhibitConditionalDeclarations
    Variables::RequireLexicalLoopIterators