App-perlimports

 view release on metacpan or  search on metacpan

script/perlimports  view on Meta::CPAN

#!perl

use strict;
use warnings;

use App::perlimports::CLI ();
use Try::Tiny qw( catch try );

my $exit_code = 0;
try {
    $exit_code = App::perlimports::CLI->new->run;
}
catch {
    print STDERR $_;
    $exit_code = 1;
};

exit($exit_code);

# PODNAME: perlimports
# ABSTRACT: A command line utility for cleaning up imports in your Perl code

__END__

=pod

=encoding UTF-8

=head1 NAME

perlimports - A command line utility for cleaning up imports in your Perl code

=head1 VERSION

version 0.000060

=head1 SYNOPSIS

Create a config file called C<perlimports.toml> at the top level of your
application or repository:

    perlimports --create-config-file perlimports.toml

You can also have a config file with a leading C<.>.

    perlimports --create-config-file .perlimports.toml

For system-wide defaults, you can create a file in C<$XDG_HOME>. Something like:

    perlimports --create-config-file ~/.config/perlimports/perlimports.toml

After you have set up the config file to your liking, you can do away with most
command line switches, other than C<-i>, C<--lint> or C<--read-stdin>.

Now, let's update a file in place. (Make sure you can revert the file if you
need to, as C<perlimports> will not make a backup.)

    perlimports -i foo.pl

Lint a file:

    perlimports --lint foo.pl

In-place edits on directories:

    perlimports -i lib t xt

script/perlimports  view on Meta::CPAN

The code above makes it immediately obvious where C<GET> originates, which in
turn makes it easier for us to look up its documentation. It has the added
bonus of also not importing C<HEAD>, C<PUT> or any of the other functions which
L<HTTP::Request::Common> exports by default. So, those functions cannot
unwittingly be used later in the code. This makes for more understandable code
for present day you, future you and any others tasked with reading your code at
some future point.

Keep in mind that this simple act can save much time for developers who are not
intimately familiar with Perl and the default exports of many CPAN modules.

=item Are we even using all of these imports?

Imagine the following import statement

    use HTTP::Status qw(
        is_cacheable_by_default
        is_client_error
        is_error
        is_info
        is_redirect
        is_server_error
        is_success
        status_message
    );

followed by 3,000 lines of code. How do you know if all of these functions are
actually being used? Were they ever used? You can grep all of these function
names manually or you can remove them by trial and error to see what breaks.
This is a doable solution, but it does not scale well to scripts and modules
with many imports or to large code bases with many imports. Having an
unmaintained list of imports is preferable to implicit imports, but it would be
helpful to automate maintaining this list.

L<perlimports> can, in many situations, clean up your import statements and
automate this maintenance burden away. This makes it easier for you to write
clean code, which is easier to understand.

=item Are we even using all of these modules?

In cases where code is implicitly importing from modules or where explicit
imports are not being curated, it can be hard to discover which modules are no
longer being used in a script, module or even a code base. Removing unused
modules from code can lead to gains in performance and decrease in consumption
of resources. Removing entire modules from your code base can decrease the
number of dependencies which you need to manage and decrease friction in your
your deployment process.

C<perlimports> can remove unused modules for you, making dependency management
much easier.

=item Enforcing a consistent style

Having a messy list of module imports makes your code harder to read. Imagine
this:

    use Cpanel::JSON::XS;
    use Database::Migrator::Types qw( HashRef ArrayRef Object Str Bool Maybe CodeRef FileHandle RegexpRef );
    use List::AllUtils qw( uniq any );
    use LWP::UserAgent    q{};
    use Try::Tiny qw/ catch     try /;
    use WWW::Mechanize  q<>;

L<perlimports> turns the above list into:

    use Cpanel::JSON::XS ();
    use Database::Migrator::Types qw(
        ArrayRef
        Bool
        CodeRef
        FileHandle
        HashRef
        Maybe
        Object
        RegexpRef
        Str
    );
    use List::AllUtils qw( any uniq );
    use LWP::UserAgent ();
    use Try::Tiny qw( catch try);
    use WWW::Mechanize ();

Where possible, L<perlimports> will enforce a consistent style of parentheses
and will also sort your imports and break up long lines. As mentioned above, if
some imports are no longer in use, C<perlimports> will helpfully remove these
for you.

=item Import tags

Import tags may obscure where symbols are coming from. While import tags
provide a useful shorthand, they can contribute to code complexity by obscuring
the origin of imported symbols. Consider:

    use HTTP::Status qw(:constants :is status_message);

The above line imports the C<status_message()> function as well *some other
things* via C<:constants> and C<:is>. What exactly are these things? We'll need
to read the documentation to know for sure.

C<perlimports> can audit your code and expand the line above to list the
symbols which you are actually importing. So, the line above might now look
something like:

    use HTTP::Status qw(
        HTTP_ACCEPTED
        HTTP_BAD_REQUEST
        HTTP_CONTINUE
        HTTP_I_AM_A_TEAPOT
        HTTP_MOVED_PERMANENTLY
        HTTP_NO_CODE
        HTTP_NOT_FOUND
        HTTP_OK
        HTTP_PAYLOAD_TOO_LARGE
        HTTP_PERMANENT_REDIRECT
        HTTP_RANGE_NOT_SATISFIABLE
        HTTP_REQUEST_ENTITY_TOO_LARGE
        HTTP_REQUEST_RANGE_NOT_SATISFIABLE
        HTTP_REQUEST_URI_TOO_LARGE
        HTTP_TOO_EARLY
        HTTP_UNORDERED_COLLECTION
        HTTP_URI_TOO_LONG
        is_cacheable_by_default
        is_client_error
        is_error
        is_info
        is_redirect
        is_server_error
        is_success
        status_message
    );

This is more verbose, but grepping your code will now reveal to you where
something like C<is_cacheable_by_default> gets defined. You have increased the
lines of code, but you have also reduced complexity.

=back

=head1 COMMAND LINE PARAMETERS

=head2 --create-config-file



( run in 0.478 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )