perrin has asked for the wisdom of the Perl Monks concerning the following question:

Does anyone have a snippet of code which, given a CPAN distribution name, will download the latest version of it from a CPAN site? I know CPAN.pm does this, but I'm not sure it is exposed through the API. I just want to download it, not install it.
  • Comment on code to grab the latest version of a module from CPAN?

Replies are listed 'Best First'.
•Re: code to grab the lates version of a module from CPAN?
by merlyn (Sage) on Mar 06, 2004 at 00:12 UTC
Re: code to grab the lates version of a module from CPAN?
by adrianh (Chancellor) on Mar 06, 2004 at 00:19 UTC

    If you don't mind CPANPLUS:

    CPANPLUS::Backend->new->fetch( modules => ['Name::Of::Module'], fetchdir => '/directory/where/you/want/it', );
Re: code to grab the latest version of a module from CPAN?
by atcroft (Abbot) on Mar 06, 2004 at 05:20 UTC

    Both of the replies above are good, and I would go with them first; however, I decided to toy with your question, and created the following script. If nothing else, it might give you something to play with.

    A few notes regarding the code:

    • Pass in your favorite mirror, or change line 192016 to your favorite mirror site for CPAN, to be nice to the primary CPAN repository.
    • The script uses several modules not in the core, such as Sort::Versions for sorting files by version number.
    • The script downloads the find-ls.gz file in the indices directory, and processes it to determine the newest version of each file.
    • Filenames from the find-ls.gz file are handled manually, rather than by a module, so that is one potential improvement that could be made. The script doesn't make allowances for symlinks, however. (See UPDATE below.)
    • $directory_match allows you to process only some directories-in the case below, only the modules/ subtree. $file_match allows you to only get files with specific patterns, such as only those ending in .tar.gz and .tgz.
    • $target_path is the directory to store the files under.
    • You can set $agent_id as you like.
    • The script uses the mirror() function from the LWP module, so files will not be downloaded if you already have them. The script does not, however, attempt to remove the old version you may have if a newer one is out.
    • While it seems to work for me, I can't guarantee it-but you already knew this.

    Update: 06 Mar 2004: Thanks to leira's suggestions, modified the code above to use the File::Spec module for dealing with the filenames. Still may be room for improvement with it, but getting there.

    Update: 06 Mar 2004: Fixed $target_path to handle relative locations (with thanks to castaway for suggesting a module that could handle ~).

    Update: 15 Mar 2004: Fixed apparent error in mirror statement when using relative paths. Changed several places where paths were assembled manually to use File::Spec->catpath().

    Update: 02 May 2004: Changed $cpan_site_root 's default value to point to the CPAN Multiplexer (http://www.perl.com/CPAN/).

Re: code to grab the latest version of a module from CPAN?
by hsmyers (Canon) on Mar 07, 2004 at 16:59 UTC
    #!/usr/bin/perl # -- use strict; use warnings; use diagnostics; use CPAN; CPAN::Shell->install($ARGV[0]);

    --hsm

    "Never try to teach a pig to sing...it wastes your time and it annoys the pig."

      "I just want to download it, not install it." said the OP.

      CPAN::Shell->get('My::Module') (untested) should download and extract into your .cpan directory - wherever that may be. AFAIK CPAN doesn't expose anything with any more control.

      Doesn't that install it? I specifically want to simply download it, and not install it.

        I haven't used this module - just saw it on the CPAN updated modules list.

        Not sure if you want to untar the files as well as download them but this looks pretty close:

        uncpan - Utility to get and untar CPAN files.
        http://search.cpan.org/~qjzhou/uncpan-1.01/uncpan