NAME
Dependencies::Searcher - Search recursively dependencies used in a module's directory and build a report that can be used as a 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
# 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, recursivelyMakefile.PL
script/
directory, i.e. if we use a Catalyst applicationmaybe 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.
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/
RT: CPAN's request tracker (report bugs here)
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Dependencies-Searcher
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
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
Brian D. Foy's Module::Extract::Use
Was the main inspiration for this one. First, I want to use it for my needs but it was not recursive...
-
What modules shipped with versions of perl. I use it extensively to detect if the module is from Perl Core or not.
Andy Lester's Ack
I've use it as the main source for the module. It was pure Perl so I've choose it, even if Ack is not meant for being used programatically, this use do the job.
See also :
https://metacpan.org/module/Perl::PrereqScanner
http://stackoverflow.com/questions/17771725/
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.