Running Perl::Critic with perl wrapper

  • Andy Throgmorton


    I am currently using EPIC to write Perl scripts, and am using a wrapper (that I created) to execute the scripts.  The wrapper (a simple bash script) allows me to create and export environment variables and provide additional command line options to the scripts I develop.  I am able to run and debug the scripts just fine, as well as format my code using perltidy.

    However, I am unable to run the integrated Perl::Critic module with this wrapper.  After tinkering with EPIC's preferences and my wrapper, I discovered that the output of Perl::Critic is confined to only my script, and is not being passed back to EPIC.  That is, EPIC calls my wrapper, which executes the perlcritic command (with all the options specified); the output from perlcritic goes to STDOUT within my wrapper, rather than the STDOUT that EPIC is listening for.  Thus, EPIC throws the following error:

    !ENTRY org.epic.perleditor 2 0 2011-08-22 13:55:39.808
    !MESSAGE Perl::Critic violations.length == 0, output change?

    Is there a way to redirect the output from my wrapper for the desired result?  Or, perhaps a different solution?


  • Jan Ploski

    Jan Ploski - 2011-08-22

    1. I went to Preferences > Perl EPIC > Perl::Critic, chose Custom location, entered /tmp/
    2. was like so

    /usr/bin/perlcritic $*

    …and it all worked as expected. I suspect that your assumption that STDOUT/STDERR are not being forwarded is incorrect. Theoretically such suppression is possible, but the executed child process would have to do some weird things, which perlcritic most surely doesn't. More likely you aren't invoking perlcritic at all or aren't passing the arguments correctly down to it.

  • Andy Throgmorton

    That's interesting that your solution works as-is.  I've tried that many times now, and am still not getting it to work correctly. 

    The only possible differences I see in our environments are the bash shell and perl distributions.  Which version of bash and perl are you using?  Also, my perl installation and perlcritic are mounted on a different volume.  That's all that I can think of.  The arguments are being passed correctly - if I print $* when it runs, I see all the args, and if I pipe all STDOUT to a file, I get the data returned from perlcritic (a long string, delimited by | and ~).

  • Andy Throgmorton

    Also, have you tried running the perl executable through a wrapper?  So, rather than using /usr/bin/perl, I'm using a wrapper at that level.  That's why I was curious about the suppressed output.  Let me know if you have any questions :)

  • Jan Ploski

    Jan Ploski - 2011-08-24

    Ok, I could reproduce your problem now. The trouble is that one of the arguments passed down to perlcritic includes a line break (\n), which gets lost when you use $* as shown above. It only seemed to work for me because the test script I used resulted in just one perlcritic message. When it produces more messages, the expected line separators are missing from the output, and so EPIC cannot process it.

    This invocation is wrong (and happens in the naive approach):

    /usr/bin/perlcritic -verbose "%f~|~%s~|~%l~|~%c~|~%m~|~%e~|~%p"

    This is what you want to have:

    /usr/bin/perlcritic -verbose "%f~|~%s~|~%l~|~%c~|~%m~|~%e~|~%p\\n"

    So you will have to do some preprocessing of arguments in your wrapper script to add the missing \n to the pattern argument. The expected output from perlcritic to EPIC must consist of lines, each line containing 7 fields separated by ~|~

    Whether or not you use a wrapper for the Perl interpreter is not relevant.

  • Andy Throgmorton

    Yes, that indeed solves my problem - I should've thought to check for newlines.  Thank you very much, Jan!


Log in to post a comment.