The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

# Copyright 2012-2013, Paul Johnson (paul@pjcj.net)

# This software is free.  It is licensed under the same terms as Perl itself.

# The latest version of this software should be available from my homepage:
# http://www.pjcj.net

use strict;
use warnings;

my $modules = <<EOM;

    # Stuff for Devel::Cover
    # Devel::Cover
    .
    Parallel::Iterator
    Test::Pod::Coverage
    PPI::HTML

    # My stuff
    Gedcom
    Shell::Source

    # Stuff with interest for Devel::Cover
    NetAddr::IP

    # There's going to be repetition down here

    # Dual-lived core modules
    Archive::Extract
    Archive::Tar
    Attribute::Handlers
    autodie
    AutoLoader
    autouse
    base
    B::Debug
    bignum
    B::Lint
    Carp
    CGI
    Compress::Raw::Bzip2
    Compress::Raw::Zlib
    Config::Perl::V
    constant
    CPAN
    CPAN::Meta
    CPAN::Meta::Requirements
    CPAN::Meta::YAML
    CPANPLUS
    CPANPLUS::Dist::Build
    Data::Dumper
    DB_File
    Devel::PPPort
    Devel::SelfStubber
    Digest
    Digest::MD5
    Digest::SHA
    Dumpvalue
    Encode
    encoding::warnings
    Env
    Exporter
    ExtUtils::CBuilder
    ExtUtils::Command
    ExtUtils::Constant
    ExtUtils::Install
    ExtUtils::MakeMaker
    ExtUtils::Manifest
    ExtUtils::ParseXS
    File::CheckTree
    File::Fetch
    File::Path
    File::Temp
    Filter::Simple
    Filter::Util::Call
    Getopt::Long
    HTTP::Tiny
    I18N::Collate
    I18N::LangTags
    if
    IO
    IO-Compress
    IO::Zlib
    IPC::Cmd
    IPC::SysV
    JSON::PP
    lib
    libnet
    Locale-Codes
    Locale::Maketext
    Locale::Maketext::Simple
    Log::Message
    Log::Message::Simple
    Math::BigInt
    Math::BigInt::FastCalc
    Math::BigRat
    Math::Complex
    Memoize
    MIME::Base64
    Module::Build
    Module::CoreList
    Module::Load
    Module::Load::Conditional
    Module::Loaded
    Module::Metadata
    Module::Pluggable
    Net::Ping
    NEXT
    Object::Accessor
    Package::Constants
    Params::Check
    parent
    Parse::CPAN::Meta
    PathTools
    perlfaq
    PerlIO::via::QuotedPrint
    Perl::OSType
    Pod::Checker
    Pod::Escapes
    Pod::LaTeX
    podlators
    Pod::Parser
    Pod::Perldoc
    Pod::Simple
    Pod::Usage
    Safe
    Scalar-List-Utils
    Search::Dict
    SelfLoader
    Socket
    Storable
    Sys::Syslog
    Term::ANSIColor
    Term::Cap
    Term::Complete
    Term::ReadLine
    Term::UI
    Test
    Test::Harness
    Test::Simple
    Text::Abbrev
    Text::Balanced
    Text::ParseWords
    Text::Soundex
    Text-Tabs+Wrap
    Thread::Queue
    threads
    Thread::Semaphore
    threads::shared
    Tie::File
    Tie::RefHash
    Time::HiRes
    Time::Local
    Time::Piece
    Unicode::Collate
    Unicode::Normalize
    version
    Win32
    Win32API::File
    XSLoader

    # Modules with many dependencies
    Task::Kensho
    Task::Plack
    Task::Catalyst
    Task::Dancer
    Mojolicious
    Task::Moose
    Task::Dist::Zilla
    Task::CPAN::SmokeBox
    Task::Perl::Critic
    Task::Toolchain::Test
    Task::Template::Benchmark
    MojoMojo
    Jifty
    Bot::BasicBot
    Dist::Zilla

    # Modules with many dependents
    Exporter
    Text::Tabs
    Test::Harness
    Pod::Escapes
    Pod::Simple
    IO
    Getopt::Long
    Pod::Parser
    ExtUtils::MakeMaker
    Test::Simple
    ExtUtils::Manifest
    constant
    Test
    Data::Dumper
    File::Temp
    ExtUtils::Install
    Text::ParseWords
    ExtUtils::CBuilder
    ExtUtils::ParseXS
    Module::Build
    File::Path
    XSLoader
    MIME::Base64
    Digest
    Digest::MD5
    Sub::Uplevel
    URI
    Test::Exception
    HTML::Tagset
    HTML::Parser
    Compress::Raw::Zlib
    Compress::Raw::Bzip2
    Storable
    base
    List::MoreUtils
    Params::Util
    Task::Weaken
    Sub::Install
    Data::OptList
    Sub::Exporter
    Test::Tester
    Test::NoWarnings
    Attribute::Handlers
    Class::Accessor
    Algorithm::C3
    Class::C3
    Sub::Name
    MRO::Compat
    Time::HiRes
    Params::Validate
    Try::Tiny
    Scope::Guard
    Package::Stash
    version
    Tree::DAG_Node
    Test::Warn
    Devel::GlobalDestruction
    Class::MOP
    Moose
    Class::Data::Inheritable
    Test::Deep
    Carp::Clan
    Module::Pluggable
    Variable::Magic
    B::Hooks::EndOfScope
    Sub::Identify
    namespace::clean
    Time::Local
    DBI
    Text::Balanced
    Class::Inspector
    Test::Pod
    Encode
    Path::Class
    Digest::SHA1
    FCGI
    CGI
    MooseX::Types
    XML::NamespaceSupport
    XML::SAX
    Class::Singleton
    Clone
    DateTime::TimeZone
    DateTime::Locale
    YAML
    DateTime
    namespace::autoclean
    IO::String
    Algorithm::Diff
    File::Slurp
    Devel::StackTrace

    # Modules which should not fail
    IO
    List::MoreUtils
    Test::Harness
    ExtUtils::MakeMaker
    File::Path
    XML::Parser
    Test::Simple
    HTML::Tree
    Storable
    Net::IP
    DB_File
    XML::LibXML
    Time::HiRes
    Exporter
    Pod::Escapes
    ExtUtils::ParseXS
    Module::Build
    Pod::Parser
    Data::Dumper
    ExtUtils::Install
    IO::Tty
    XML::SAX
    Class::ErrorHandler
    URI
    HTML::Template
    Compress::Raw::Zlib
    Net::DNS
    Test::Pod::Coverage
    XSLoader
    version
    URI::Fetch
    Pod::Simple
    constant
    Test
    File::Temp
    Cache::Cache
    Feed::Find
    HTML::Tagset
    ExtUtils::PkgConfig
    Devel::GlobalDestruction
    PadWalker
    Sub::Name
    Encode
    Test::Base
    Class::DBI::Plugin::Type
    Sub::Identify
    Sub::Uplevel
    Params::Validate
    POE
    Class::Singleton
    Proc::ProcessTable
    Compress::Raw::Bzip2
    Class::MOP
    HTTP::Server::Simple
    Sub::Exporter
    Fuse
    File::HomeDir
    Bot::BasicBot
    # URI::Find::Simple
    base
    # GD
    WWW::Mechanize
    Test::Most
    Sys::Syslog
    File::Slurp
    Tree::DAG_Node
    FCGI
    Params::Util
    Devel::Peek
    DateTime::Format::Mail
    Spiffy
    HTML::TableExtract
    DBD::SQLite
    Class::Accessor::Chained
    DBIx::ContextualFetch
    Test::Tester
    Variable::Magic
    AppConfig
    Class::Accessor
    Want
    XML::Simple
    IO::All
    Number::Format
    Term::ReadKey
    DBI
    Test::Exception
    Data::DPath
    Config::INI::Serializer
    Class::MethodMaker
    PDF::FDF::Simple
    TAP::DOM

    # Web stuff
    Authen::Passphrase::BlowfishCrypt
    Carp::Always::Color
    App::cpanoutdated
    Dancer
    Dancer::Logger::Log4perl
    Dancer::Plugin::Auth::Twitter
    Dancer::Plugin::Database
    Dancer::Plugin::DBIC
    Data::Printer
    DBD::SQLite
    DBIx::Class::Schema::Loader
    DBIx::Class::TimeStamp
    DBIx::Log4perl
    Exporter::Lite
    Log::Log4perl
    JSON
    Module::Refresh
    Moose
    MooseX::Declare
    MooseX::StrictConstructor
    MooseX::Types::DateTime::MoreCoercions
    Plack::Middleware::Debug
    Plack::Middleware::Debug::Dancer::Version
    Plack::Middleware::ReverseProxy
    Plack::Middleware::Debug::Dancer::TemplateVariables
    SQL::Translator
    Starman
    Template
    Test::More
    YAML

    # Maths stuff
    Math::ODE
    Math::MatrixReal

    # Other stuff
    Image::PNG
    Games::Bingo
    Method::Signatures
    Data::Random
    Debuggit

EOM

my @opts = @ARGV;

my @modules = grep /\S/, grep !/^ +#/, split /\n/, $modules;
s/^ +//, s/ +$// for @modules;
my %m; @modules = grep !$m{$_}++, @modules;

for my $mod (sort @modules)
{
    system "cpanm @opts $mod";
}