The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Dependencies::Searcher - Search for modules used or required by a distribution and build a report that can be used as Carton cpanfile .

SYNOPSIS

    use Dependencies::Searcher;

    my $searcher = Dependencies::Searcher->new();
    my @elements = $searcher->get_files();
    my @uses = $searcher->get_modules($path, "use");
    my @uniq_modules = $searcher->uniq(@uses);

    $searcher->dissociate(@uniq_modules);

    $searcher->generate_report($searcher->non_core_modules);

    # Prints to cpanfile
    # requires 'Data::Printer', '0.35';
    # requires Moose, '2.0602';
    # requires IPC::Cmd;
    # requires Module::Version;
    # ...

DESCRIPTION

Maybe you don't want to have to list all the dependencies of your Perl application by hand and want an automated way to build it. Maybe you forgot to do it for a long time ago. Or just during a short period. Anyway, you've add lots of CPAN modules. Carton is here to help you manage dependencies between your development environment and production, but how to keep track of the list of modules you will pass to Carton?

Event if it is a no brainer to keep track of this list by adding it by hand, it can be much better not to have to do it.

You will need a tool that will check for any requires or use in your module package, and report it into a file that could be used as an input Carton cpanfile. Any duplicated entry will be removed and modules versions will be checked and made available. Core modules will be ommited because you don't need to install them (except in some special case, see dissociate() documentation).

This project has begun because it has happened to me, and I don't want to search for modules to install by hand, I just want to run a simple script that update the list in a convenient way. It was much more longer to write the module than to search by hand so I wish it could be useful for you now.

This module is made to search dependencies for installed distributions, it is not supposed to manage anything else.

WHY ISN'T IT JUST ANOTHER MODULE::SCANDEPS ?

Module::ScanDeps is a bi-dimentional recursive scanner: it features dependencies and directories recursivity.

Dependencies::Searcher only found direct dependencies, not dependencies of dependencies, it scans recursively directories but not dependencies..

These direct dependencies are passed to the Perl toolchain (cpanminus) that will take care of any recursive dependencies.

SUBROUTINES/METHODS

get_files()

get_files() returns an array containing which file or directories has been found in the current root distribution directory. We suppose it can find dependancies in 3 different places :

  • files in lib/ directory, recursively

  • Makefile.PL

  • script/ directory, i.e. if we use a Catalyst application

  • maybe it should look in t/ directory (todo)

If the lib/ directory don't exist, the program die because we consider we are not into a plain old Perl Module.

This is work in progress, if you know other places where we can find stuff, please report a bug.

get_modules("pattern", @elements)

You must pass a pattern to search for, and the elements (files or directories) where you want to search (array of strings from get_files()).

These patterns should be ^use or ^require.

Then, Ack will be used to retrieve modules names into lines containing patterns and return them into an array (containing also some dirt). See Dependencies::Searcher::AckRequester for more informations.

merge_dependencies(@modules, @modules)

Simple helper method that will merge use and require arrays if you search for both. Return an uniq array. It got a little caveat, see CAVEATS.

make_it_real(@modules)

Move dependencies lines from an array to an another unless it is considered as a special case : minimal Perl versions, use autodie, use warnings. These stuff has to be removed. Return a real modules array (real interresting modules).

clean_everything(@modules)

After removing irrelevant stuff, we need to clean what is leaving and is considered as being crap (not strictly <CName::Of::Module>) but needs some cleaning. We are going to remove everything but the module name (even version numbers).

This code section is well commented (because it is regex-based) so, please refer to it directly.

It returns an array of clean modules.

uniq(@modules)

Make each array element uniq, because one dependency can be found many times. Return an array of unique modules.

dissociate(@modules)

Dissociate core / non-core modules using the awesome Module::Corelist::is_core method, that search in the current Perl version if the module is from Perl core or not. Note that results can be different according to the environment.

More, you can have two versions of the same module installed on your environment (even if you use local::lib when you install a recent version of a file that has been integrated into Perl core (this version hasn't necessary been merged into core).

So dissociate() checks both and compares it, to be sure that the found core module is the "integrated" version, not a fresh one that you have installed yourself. If it is fresh, the module is considered as a non-core.

This method don't return anything, but it stores found dependencies on the two core_modules and non_core_modules Moose attributes arrays.

generate_report()

Generate the cpanfile for Carton, based on data contained into core_modules and non_core_modules attributes, with optionnal version number (if version number can't be found, dependency name is print alone).

Generate a hash containing the modules could be achieved. Someday.

Log::Minimal::PRINT override

Just override the way Log::Minimal is used. See LOGGING AND DEBUGGING for more informations.

LOGGING AND DEBUGGING

This module has a very convenient logging system that use Log::Minimal and File::Stamped to write to a file that you will find in the directory where local applications should store their internal data for the current user. This is totally portable (Thanks to Nikolay Mishin (mishin)). For exemple, on a Debian-like OS :

    ~/.local/share/dependencies-searcher.[y-M-d].out

To debug and use these logs :

    $ tail -vf ~/local/share/dependencies-searcher.[y-M-d].out

For more information on how to configure log level, read Log::Minimal documentation.

For a simple exemple on how to use it, see this blog post http://bit.ly/1lJwyX7

CAVEATS

Low Win32 / Cygwin support

This module was'nt supposed to run under Win32 / Cygwin environments because it was using non portable code with slashes. I hope this gets better since it has been rewritten using Path::Class but it still need some testing.

It also us-e Ack as a hack through a system command even if it was not supposed to be used like that. Yes, this is dirty. Yes, I plan to change things, even if Ack do the stuff proudly this way.

Thanks to cpantesters.org community reports, things should go better and better.

Fun : some are able to do it using a one-liner

Command Line Magic (@climagic) tweeted 4:17 PM on lun., nov. 25, 2013

    # Not perfect, but gives you a start on the Perl modules in use.
    grep -rh ^use --include="*.pl" --include="*.pm" . | sort | uniq -c

See original Tweet https://twitter.com/climagic/status/404992356513902592

BUGS

Please report any bugs or feature requests to bug-dependencies-searcher at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Dependencies-Searcher. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

TODOs

Most of the time, todos and features are on Github and Questub. See https://github.com/smonff/dependencies-searcher/issues

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Dependencies::Searcher

You can also look for information at:

    See https://github.com/smonff/dependencies-searcher/

AUTHOR

smonff, <smonff at gmail.com>

CONTRIBUTORS

  • Nikolay Mishin (mishin) helps to make it more cross-platform

  • Alexandr Ciornii (chorny) advises on version numbers

ACKNOWLEDGEMENTS

See also :

  • https://metacpan.org/module/Perl::PrereqScanner

  • http://stackoverflow.com/questions/17771725/

  • https://metacpan.org/module/Dist::Zilla::Plugin::AutoPrereqs

LICENSE AND COPYRIGHT

Copyright 2013 smonff.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.