r54159 - // /lib/ /lib/Apt/ /script/ /t/ /tmp/
jozef-guest at users.alioth.debian.org
jozef-guest at users.alioth.debian.org
Fri Mar 12 11:00:52 UTC 2010
Author: jozef-guest
Date: Fri Mar 12 10:59:46 2010
New Revision: 54159
URL: http://svn.debian.org/wsvn/?sc=1&rev=54159
Log:
initial apt-pm
Added:
.gitignore
Build.PL
Changes
MANIFEST
MANIFEST.SKIP
META.yml
README
lib/
lib/Apt/
lib/Apt/PM.pm
script/
script/apt-pm (with props)
t/
t/00_compile.t
t/01_Apt-PM.t
t/PerlPackages.bz2 (with props)
t/PerlPackages2.bz2 (with props)
t/distribution.t
t/fixme.t
t/pod-coverage.t
t/pod-spell.t
t/pod.t
tmp/
Added: .gitignore
URL: http://svn.debian.org/wsvn/.gitignore?rev=54159&op=file
==============================================================================
--- .gitignore (added)
+++ .gitignore Fri Mar 12 10:59:46 2010
@@ -1,0 +1,13 @@
+/Makefile
+/blib
+/pm_to_blib
+/META.yml
+/MYMETA.yml
+/Makefile.PL
+/Build
+/_build
+/*.tar.gz
+/MANIFEST.bak
+/cover_db
+/tmp/*
+/Apt-PM-*
Added: Build.PL
URL: http://svn.debian.org/wsvn/Build.PL?rev=54159&op=file
==============================================================================
--- Build.PL (added)
+++ Build.PL Fri Mar 12 10:59:46 2010
@@ -1,0 +1,51 @@
+use strict;
+use warnings;
+use Module::Build;
+
+use 5.010;
+
+my $builder = Module::Build->new(
+ module_name => 'Apt::PM',
+ license => 'perl',
+ dist_author => 'Jozef Kutej <jkutej at cpan.org>',
+ dist_version_from => 'lib/Apt/PM.pm',
+
+ build_requires => {
+ 'Test::More' => 0,
+ 'Test::Differences' => 0,
+ 'Test::Exception' => 0,
+ },
+ requires => {
+ 'Moose' => 0,
+ 'IO::Uncompress::Bunzip2' => 0,
+ 'IO::Any' => 0,
+ 'Parse::Deb::Control' => 0.03,
+ 'Dpkg::Version' => 0,
+ 'AptPkg::Config' => 0,
+ 'LWP::Simple' => 0,
+ 'Carp' => 0,
+ 'JSON::Util' => 0.04, # atomic writes
+ 'Getopt::Long' => 0,
+ 'Pod::Usage' => 0,
+ 'List::MoreUtils' => 0,
+ 'CPAN::Version' => 0,
+ 'Storable' => 0,
+ 'CPAN' => 0,
+ 'File::is' => 0,
+ },
+ script_files => [
+ 'script/apt-pm',
+ ],
+ add_to_cleanup => [ 'Apt-PM-*' ],
+ create_readme => 1,
+ sign => 1,
+ meta_merge => {
+ resources => {
+ repository => 'http://svn.debian.org/viewsvn/pkg-perl/trunk/apt-pm/',
+ bugtracker => 'http://bugs.debian.org/',
+ },
+ keywords => [ qw/ debian perl modules search / ],
+ },
+);
+
+$builder->create_build_script();
Added: Changes
URL: http://svn.debian.org/wsvn/Changes?rev=54159&op=file
==============================================================================
--- Changes (added)
+++ Changes Fri Mar 12 10:59:46 2010
@@ -1,0 +1,4 @@
+Revision history for Apt-PM
+
+0.01 12 Mar 2010
+ * First version, released on an unsuspecting world.
Added: MANIFEST
URL: http://svn.debian.org/wsvn/MANIFEST?rev=54159&op=file
==============================================================================
--- MANIFEST (added)
+++ MANIFEST Fri Mar 12 10:59:46 2010
@@ -1,0 +1,16 @@
+Build.PL
+Changes
+lib/Apt/PM.pm
+MANIFEST This list of files
+META.yml
+README
+script/apt-pm
+t/00_compile.t
+t/01_Apt-PM.t
+t/distribution.t
+t/fixme.t
+t/PerlPackages.bz2
+t/PerlPackages2.bz2
+t/pod-coverage.t
+t/pod-spell.t
+t/pod.t
Added: MANIFEST.SKIP
URL: http://svn.debian.org/wsvn/MANIFEST.SKIP?rev=54159&op=file
==============================================================================
--- MANIFEST.SKIP (added)
+++ MANIFEST.SKIP Fri Mar 12 10:59:46 2010
@@ -1,0 +1,35 @@
+# Avoid version control files.
+\bRCS\b
+\bCVS\b
+,v$
+\B\.svn\b
+^\.git
+\.cvsignore
+\.svnignore
+
+# Avoid Makemaker generated and utility files.
+^Makefile$
+\bblib
+\bMakeMaker-\d
+\bpm_to_blib$
+\bblibdirs$
+^MANIFEST\.(SKIP|bak)$
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build
+\bcover_db
+
+# Avoid temp and backup files.
+~$
+\.tmp$
+\.old$
+\.bak$
+\#$
+\b\.#
+
+^tmp/
+.*\.tar\.gz
+^MYMETA.yml$
+^Apt-PM-
+
Added: META.yml
URL: http://svn.debian.org/wsvn/META.yml?rev=54159&op=file
==============================================================================
--- META.yml (added)
+++ META.yml Fri Mar 12 10:59:46 2010
@@ -1,0 +1,47 @@
+---
+abstract: 'locate Perl Modules in Debian repositories'
+author:
+ - 'Jozef Kutej <jkutej at cpan.org>'
+build_requires:
+ Test::Differences: 0
+ Test::Exception: 0
+ Test::More: 0
+configure_requires:
+ Module::Build: 0.36
+generated_by: 'Module::Build version 0.3603'
+keywords:
+ - debian
+ - perl
+ - modules
+ - search
+license: perl
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: 1.4
+name: Apt-PM
+provides:
+ Apt::PM:
+ file: lib/Apt/PM.pm
+ version: 0.01
+requires:
+ AptPkg::Config: 0
+ CPAN: 0
+ CPAN::Version: 0
+ Carp: 0
+ Dpkg::Version: 0
+ File::is: 0
+ Getopt::Long: 0
+ IO::Any: 0
+ IO::Uncompress::Bunzip2: 0
+ JSON::Util: 0.04
+ LWP::Simple: 0
+ List::MoreUtils: 0
+ Moose: 0
+ Parse::Deb::Control: 0.03
+ Pod::Usage: 0
+ Storable: 0
+resources:
+ bugtracker: http://bugs.debian.org/
+ license: http://dev.perl.org/licenses/
+ repository: http://svn.debian.org/viewsvn/pkg-perl/trunk/apt-pm/
+version: 0.01
Added: README
URL: http://svn.debian.org/wsvn/README?rev=54159&op=file
==============================================================================
--- README (added)
+++ README Fri Mar 12 10:59:46 2010
@@ -1,0 +1,140 @@
+NAME
+ Apt::PM - locate Perl Modules in Debian repositories
+
+SYNOPSIS
+ Cmd-line:
+
+ apt-pm update
+ apt-pm find Moose
+
+ # print out all dependencies of an unpacked distribution that are packaged for Debian
+ perl -MApt::PM -MModule::Depends -le \
+ '$apm=Apt::PM->new();$md=Module::Depends->new->dist_dir(".")->find_modules; %r=(%{$md->requires},%{$md->build_requires}); while (($m, $v) = each %r) { $f=$apm->find($m, $v); print $f->{"min"}->{"package"} if $f->{"min"} }' \
+ | sort \
+ | uniq \
+ | xargs echo apt-get install
+ # print out all dependencies of an unpacked distribution that are not packaged for Debian
+ perl -MApt::PM -MModule::Depends -le \
+ '$apm=Apt::PM->new();$md=Module::Depends->new->dist_dir(".")->find_modules; %r=(%{$md->requires},%{$md->build_requires}); while (($m, $v) = each %r) { $f=$apm->find($m, $v); print $m, " ", $v if not $f->{"min"} }'
+
+ Module:
+
+ my $aptpm = Apt::PM->new(sources => [ 'PerlPackages.bz2' ])
+ $aptpm->update;
+ my %moose_locations = $aptpm->find('Moose');
+
+USAGE
+ COMMAND-LINE USAGE
+ Add sources for Debian releases and components. Here is the complete
+ list that can be reduced just to the wanted ones:
+
+ cat >> /etc/apt/sources.list << __END__
+ # for apt-pm
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ etch main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ lenny main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ sid main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ squeeze main contrib non-free
+ __END__
+
+ Fetch the indexes:
+
+ apt-pm update
+
+ Look for the CPAN modules:
+
+ $ apt-pm find Moose::Meta::Attribute
+ libmoose-perl_0.98-1_i386: Moose::Meta::Attribute 0.98
+ libmoose-perl_0.54-1_all: Moose::Meta::Attribute 0.54
+ libmoose-perl_0.17-1_all: Moose::Meta::Attribute 0.08
+
+ Look for the non-CPAN modules:
+
+ apt-pm find Purple
+ # libpurple0_2.4.3-4lenny5_i386: Purple 0.01
+
+ apt-pm find Dpkg::Version
+ # dpkg-dev_1.14.28_all: Dpkg::Version 0
+
+METHODS
+ new()
+ Object constructor.
+
+ PROPERTIES
+ sources
+ `isa => 'ArrayRef'' of files that will be read to construct the
+ lookup. By default it is filled with files from
+ /var/cache/apt/apt-pm/.
+
+ cachedir
+ Is the folder where indexes cache files will be stored. Default is
+ /var/cache/apt/apt-pm/deb/.
+
+ repo_type
+ `deb|deb-src'
+
+ find($module_name, [$min_version])
+ Returns hash with Perl versions as key and hash value having Debian
+ version and package name. Example:
+
+ {
+ '0.94' => {
+ 'version' => '0.94-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ '0.97' => {
+ 'version' => '0.97-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ '0.54' => {
+ 'version' => '0.54-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ };
+
+ If `$min_version' is set, returns `min' and `max' keys. `max' has always
+ the highest version:
+
+ 'max' => {
+ 'version' => '0.97-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+
+ `min' is changing depending on `$min_version'. Examples:
+
+ $min_version = '0.01';
+ 'min' => {
+ 'version' => '0.54-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ $min_version = '0.93';
+ 'min' => {
+ 'version' => '0.94-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ $min_version = '1.00';
+ 'min' => undef,
+
+ update
+ Scans the /etc/apt/sources.list and /etc/apt/sources.list.d/*.list
+ repositories for PerlPackages.bz2 and prepares them to be used for find.
+ All PerlPackages.bz2 are stored to /var/cache/apt/apt-pm/.
+
+ clean
+ Remove all files fom cache dir.
+
+AUTHOR
+ jozef at kutej.net, `<jkutej at cpan.org>'
+
+LICENSE AND COPYRIGHT
+ 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.
+
Added: lib/Apt/PM.pm
URL: http://svn.debian.org/wsvn/lib/Apt/PM.pm?rev=54159&op=file
==============================================================================
--- lib/Apt/PM.pm (added)
+++ lib/Apt/PM.pm Fri Mar 12 10:59:46 2010
@@ -1,0 +1,430 @@
+package Apt::PM;
+
+=head1 NAME
+
+Apt::PM - locate Perl Modules in Debian repositories
+
+=head1 SYNOPSIS
+
+Cmd-line:
+
+ apt-pm update
+ apt-pm find Moose
+
+ # print out all dependencies of an unpacked distribution that are packaged for Debian
+ perl -MApt::PM -MModule::Depends -le \
+ '$apm=Apt::PM->new();$md=Module::Depends->new->dist_dir(".")->find_modules; %r=(%{$md->requires},%{$md->build_requires}); while (($m, $v) = each %r) { $f=$apm->find($m, $v); print $f->{"min"}->{"package"} if $f->{"min"} }' \
+ | sort \
+ | uniq \
+ | xargs echo apt-get install
+ # print out all dependencies of an unpacked distribution that are not packaged for Debian
+ perl -MApt::PM -MModule::Depends -le \
+ '$apm=Apt::PM->new();$md=Module::Depends->new->dist_dir(".")->find_modules; %r=(%{$md->requires},%{$md->build_requires}); while (($m, $v) = each %r) { $f=$apm->find($m, $v); print $m, " ", $v if not $f->{"min"} }'
+
+
+Module:
+
+ my $aptpm = Apt::PM->new(sources => [ 'PerlPackages.bz2' ])
+ $aptpm->update;
+ my %moose_locations = $aptpm->find('Moose');
+
+=head1 USAGE
+
+=head2 COMMAND-LINE USAGE
+
+Add sources for Debian releases and components. Here is the complete list
+that can be reduced just to the wanted ones:
+
+ cat >> /etc/apt/sources.list << __END__
+ # for apt-pm
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ etch main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ lenny main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ sid main contrib non-free
+ deb http://pkg-perl.alioth.debian.org/~jozef-guest/pmindex/ squeeze main contrib non-free
+ __END__
+
+Fetch the indexes:
+
+ apt-pm update
+
+Look for the CPAN modules:
+
+ $ apt-pm find Moose::Meta::Attribute
+ libmoose-perl_0.98-1_i386: Moose::Meta::Attribute 0.98
+ libmoose-perl_0.54-1_all: Moose::Meta::Attribute 0.54
+ libmoose-perl_0.17-1_all: Moose::Meta::Attribute 0.08
+
+Look for the non-CPAN modules:
+
+ apt-pm find Purple
+ # libpurple0_2.4.3-4lenny5_i386: Purple 0.01
+
+ apt-pm find Dpkg::Version
+ # dpkg-dev_1.14.28_all: Dpkg::Version 0
+
+=cut
+
+use warnings;
+use strict;
+
+our $VERSION = '0.01';
+
+use 5.010;
+
+use Moose;
+use IO::Uncompress::Bunzip2 qw(bunzip2 $Bunzip2Error) ;
+use IO::Any;
+use Parse::Deb::Control 0.03;
+use Dpkg::Version 'version_compare';
+use AptPkg::Config '$_config';
+use LWP::Simple 'mirror', 'RC_OK';
+use Carp 'croak';
+use JSON::Util;
+use CPAN::Version;
+use Storable 'dclone';
+use List::MoreUtils 'uniq';
+use File::is;
+use CPAN::Version;
+
+
+
+has 'sources' => (is => 'rw', isa => 'ArrayRef', lazy => 1, default => sub { [ glob($_[0]->cachedir.'/all.index') ] });
+has '_modules_index' => (is => 'rw', isa => 'HashRef', lazy => 1, default => sub { $_[0]->_create_modules_index });
+has '_apt_config' => (is => 'rw', lazy => 1, default => sub { $AptPkg::Config::_config->init; $AptPkg::Config::_config; });
+has 'cachedir' => (
+ is => 'rw',
+ lazy => 1,
+ default => sub {
+ '/var/cache/apt/apt-pm/deb'
+ .($_[0]->repo_type eq 'deb-src' ? '-src' : '' )
+ }
+);
+has 'repo_type' => (is => 'rw', lazy => 1, default => 'deb');
+
+
+=head1 METHODS
+
+=head2 new()
+
+Object constructor.
+
+=head3 PROPERTIES
+
+=over 4
+
+=item sources
+
+C<< isa => 'ArrayRef' >> of files that will be read to construct the lookup.
+By default it is filled with files from F</var/cache/apt/apt-pm/>.
+
+=item cachedir
+
+Is the folder where indexes cache files will be stored.
+Default is F</var/cache/apt/apt-pm/deb/>.
+
+=item repo_type
+
+C<deb|deb-src>
+
+=back
+
+=head2 find($module_name, [$min_version])
+
+Returns hash with Perl versions as key and hash value having Debian version
+and package name. Example:
+
+ {
+ '0.94' => {
+ 'version' => '0.94-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ '0.97' => {
+ 'version' => '0.97-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ '0.54' => {
+ 'version' => '0.54-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ };
+
+If C<$min_version> is set, returns C<min> and C<max> keys. C<max> has always
+the highest version:
+
+ 'max' => {
+ 'version' => '0.97-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+
+C<min> is changing depending on C<$min_version>. Examples:
+
+ $min_version = '0.01';
+ 'min' => {
+ 'version' => '0.54-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ $min_version = '0.93';
+ 'min' => {
+ 'version' => '0.94-1',
+ 'package' => 'libmoose-perl'
+ 'arch' => 'i386'
+ },
+ $min_version = '1.00';
+ 'min' => undef,
+
+=cut
+
+sub find {
+ my $self = shift;
+ my $module = shift;
+ my $min_version = shift;
+
+ my $versions_info = $self->_modules_index()->{$module};
+ return if not $versions_info;
+
+ # clone the info
+ $versions_info = dclone($versions_info);
+
+ # if not min then we are done
+ return $versions_info
+ if not defined $min_version;
+
+ # sort available versions and grep smaller than requested
+ my @versions =
+ sort { CPAN::Version->vcmp($a, $b) }
+ keys %{$versions_info}
+ ;
+
+ $versions_info->{'max'} = $versions_info->{$versions[-1]};
+ @versions = grep { not CPAN::Version->vlt($_, $min_version) } @versions;
+ $versions_info->{'min'} = (@versions ? $versions_info->{$versions[0]} : undef);
+
+ return $versions_info;
+}
+
+=head2 update
+
+Scans the F</etc/apt/sources.list> and F</etc/apt/sources.list.d/*.list>
+repositories for F<PerlPackages.bz2> and prepares them to be used for find.
+All F<PerlPackages.bz2> are stored to F</var/cache/apt/apt-pm/>.
+
+=cut
+
+sub update {
+ my $self = shift;
+
+ my @existing = glob($self->cachedir.'/*.bz2');
+ foreach my $url ($self->_etc_apt_sources) {
+ my $filename = $url;
+ $filename =~ s/[^a-zA-Z0-9\-\.]/_/gxms;
+ $filename = $self->cachedir.'/'.$filename;
+ @existing = grep { $_ ne $filename } @existing;
+ if (mirror($url, $filename) == RC_OK) {
+ my $json_filename = $filename; $json_filename =~ s/\.bz2$/.json/;
+ my $content;
+ my $bz_content = IO::Any->slurp($filename);
+ bunzip2 \$bz_content => \$content or die "bunzip2 failed: $Bunzip2Error\n";
+ JSON::Util->encode([$self->_parse_perlpackages_content($content)], $json_filename);
+ }
+ }
+
+ # remove no longer wanted indexes
+ foreach my $old_filename (@existing) {
+ my $json_filename = $old_filename; $json_filename =~ s/\.bz2$/.json/;
+ unlink($old_filename, $json_filename);
+ }
+
+ my $index_filename = File::Spec->catfile($self->cachedir, 'all.index');
+ my $aptpm = Apt::PM->new(
+ cachedir => $self->cachedir,
+ sources => [ glob($self->cachedir.'/*.json') ],
+ );
+ JSON::Util->encode($aptpm->_create_modules_index, [$index_filename])
+ if (not -f $index_filename) or File::is->older($index_filename, glob($self->cachedir.'/*.json'));
+}
+
+=head2 clean
+
+Remove all files fom cache dir.
+
+=cut
+
+sub clean {
+ my $self = shift;
+
+ foreach my $filename (glob($self->cachedir.'/*')) {
+ unlink($filename) or warn 'failed to remove '.$filename."\n";
+ }
+}
+
+sub _etc_apt_sources {
+ my $self = shift;
+
+ my $repo_type = $self->repo_type;
+ $repo_type = 'deb'
+ if ($repo_type ne 'deb-src');
+
+ my $apt_config = $self->_apt_config;
+ my @sources_files = (
+ $self->_apt_config->get_file('Dir::Etc::sourcelist'),
+ glob( $self->_apt_config->get_dir('Dir::Etc::sourceparts') . '/*.list' ),
+ );
+
+ my $sources_text = join(
+ "\n",
+ map {
+ eval { IO::Any->slurp($_) }
+ } @sources_files
+ );
+
+ my $arch = $apt_config->get('APT::Architecture');
+ my @urls;
+ foreach my $line (split("\n", $sources_text)) {
+ given ($line) {
+ when (/^\s*$/) {}; # skip empty lines
+ when (/^\s*#/) {}; # skip comments
+ when (/^ \s* $repo_type \s+ ([^ ]+) \s+ ([^ ]+) (?: \s+ (.+) | \/ \s*) $/xms) {
+ my ($url, $path, $components_string) = ($1, $2, $3);
+ my @components = grep { $_ } split(/\s+/, $components_string || '');
+
+ if ($url !~ m{^(:? http:// | ftp:// | file://)}xms) {
+ warn 'unsupported schema - '.$url;
+ next;
+ }
+
+ if (@components) {
+ push @urls, map {
+ $url.'dists/'.$path.'/'.$_.'/binary-'.$arch.'/PerlPackages.bz2'
+ } @components;
+ }
+ else {
+ push @urls, $url.$path.'/PerlPackages.bz2';
+ }
+ };
+ when (/^ \s* (?: deb | deb-src ) \s /xms) {}; # skip !$repo_type
+ default { warn 'unknown sources.list line - '.$line };
+ }
+ }
+
+ return uniq @urls;
+}
+
+sub _parse_perlpackages_content {
+ my $self = shift;
+ my $content = shift;
+
+ my @content_list;
+ my $idx = Parse::Deb::Control->new($content);
+ foreach my $entry ($idx->get_keys('Perl-Modules')) {
+ my %modules = _parse_perl_modules($entry->{'para'}->{'Perl-Modules'});
+
+ my %deb = (
+ 'version' => _trim($entry->{'para'}->{'Version'}),
+ 'package' => (
+ $self->repo_type eq 'deb-src'
+ ? _trim($entry->{'para'}->{'Source'}) || _trim($entry->{'para'}->{'Package'})
+ : _trim($entry->{'para'}->{'Package'})
+ ),
+ 'arch' => _trim($entry->{'para'}->{'Architecture'}),
+ );
+
+ push @content_list, { modules => \%modules, deb => \%deb };
+ }
+
+ return @content_list;
+}
+
+sub _create_modules_index {
+ my $self = shift;
+ my @sources = @{$self->sources};
+
+ return {}
+ if not @sources;
+
+ my %modules_index;
+ foreach my $src (@sources) {
+ my @content_list;
+ given ($src) {
+ when (m/\.bz2$/) {
+ my $content;
+ my $bz_content = IO::Any->slurp($src);
+ bunzip2 \$bz_content => \$content or die "bunzip2 failed: $Bunzip2Error\n";
+ @content_list = $self->_parse_perlpackages_content($content);
+ }
+ when (m/all\.index$/) {
+ return eval { JSON::Util->decode([$src]) } || {};
+ }
+ when (m/\.json$/) {
+ @content_list = @{JSON::Util->decode([$src])};
+ }
+ default { @content_list = $self->_parse_perlpackages_content(IO::Any->slurp($src)); }
+ }
+
+ foreach my $entry (@content_list) {
+ my %modules = %{$entry->{'modules'}};
+ my %deb = %{$entry->{'deb'}};
+ while (my ($module_name, $version) = each %modules) {
+ # resolve conflicts when two packages has the module with the same version
+ if (exists $modules_index{$module_name}->{$version}) {
+ my $old_version = $modules_index{$module_name}->{$version}->{'version'};
+ my $new_version = $entry->{'deb'}->{'version'};
+
+ # will not overwrite if the current package has older Debian version
+ next
+ if version_compare($old_version, $new_version) == -1;
+ }
+
+ $modules_index{$module_name}->{$version} =\%deb;
+ }
+ }
+ }
+
+ return \%modules_index;
+}
+
+sub _parse_perl_modules {
+ my $text = shift || '';
+
+ return
+ map { m/^(.+)\s+ \( \s* ([^\(]+) \s* \)/xms ? ( $1 => $2 ) : () }
+ grep { $_ } # remove empty lines
+ map { s/^\s*//; s/\s*$//; $_ } # trim
+ split("\n", $text) # split on new lines
+ ;
+}
+
+sub _trim {
+ my $text = shift;
+ croak 'too much argauments' if @_;
+
+ return if not defined $text;
+
+ $text =~ s/^\s+//xms;
+ $text =~ s/\s+$//xms;
+
+ return $text;
+}
+
+1;
+
+
+__END__
+
+=head1 AUTHOR
+
+jozef at kutej.net, C<< <jkutej at cpan.org> >>
+
+=head1 LICENSE AND COPYRIGHT
+
+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.
+
+=cut
Added: script/apt-pm
URL: http://svn.debian.org/wsvn/script/apt-pm?rev=54159&op=file
==============================================================================
--- script/apt-pm (added)
+++ script/apt-pm Fri Mar 12 10:59:46 2010
@@ -1,0 +1,103 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+apt-pm - locate Perl Modules in Debian repositories
+
+=head1 SYNOPSIS
+
+ apt-pm search Moose::Meta::Role
+ apt-pm update
+ apt-pm clean
+
+options:
+
+ --sources
+ comman separated list of index files to use for search/find
+ --deb-src
+ search in source repositories
+
+=head1 DESCRIPTION
+
+Lookup Perl package in Debian .deb files.
+
+=cut
+
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+use Pod::Usage;
+use Apt::PM 0.01;
+use List::MoreUtils 'none';
+
+exit main();
+
+sub main {
+ my $help;
+ my $sources;
+ my $search_src = 0;
+ GetOptions(
+ 'help|h' => \$help,
+ 'sources|s=s' => \$sources,
+ 'deb-src' => \$search_src,
+ ) or pod2usage;
+ pod2usage if $help;
+
+ # the switch makes no sence when sources explicitely set
+ $search_src = 0
+ if $sources;
+
+ my $cmd = shift @ARGV;
+ my $package = shift @ARGV;
+ pod2usage if not $cmd;
+ pod2usage if none { $_ eq $cmd } qw(search find update clean);
+
+ my $aptpm = Apt::PM->new();
+ my $aptpm_src = Apt::PM->new(repo_type => 'deb-src');
+ $aptpm->sources([split(',', $sources)])
+ if ($sources);
+
+ # get provides from dbedia.com
+ if ($cmd eq 'update') {
+ $aptpm->update();
+ $aptpm_src->update()
+ if not $sources;
+ }
+
+ if ($cmd eq 'clean') {
+ $aptpm->clean();
+ $aptpm_src->clean()
+ if not $sources;
+ }
+
+ $aptpm = $aptpm_src
+ if ($search_src);
+
+ # lookup the package
+ if (($cmd eq 'search') or ($cmd eq 'find')) {
+ pod2usage if not $package;
+
+ # get provides hash with packages
+ my $version_info = $aptpm->find($package);
+
+ # nothing to do if the package is not there
+ return 0 if not $version_info;
+
+ # print all available versions
+ foreach my $version (keys %{$version_info}) {
+ print $version_info->{$version}->{'package'}, '_', $version_info->{$version}->{'version'}, '_', $version_info->{$version}->{'arch'}, ': ', $package, ' ', $version, "\n";
+ }
+ }
+
+ return 0;
+}
+
+__END__
+
+=head1 SEE ALSO
+
+L<Apt::PM>
+
+=cut
Propchange: script/apt-pm
------------------------------------------------------------------------------
svn:executable =
Added: t/00_compile.t
URL: http://svn.debian.org/wsvn/t/00_compile.t?rev=54159&op=file
==============================================================================
--- t/00_compile.t (added)
+++ t/00_compile.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,9 @@
+use strict;
+use Test::More;
+
+eval "use Test::Compile 0.08";
+plan skip_all => "Test::Compile 0.08 required for testing compilation"
+ if $@;
+
+my @pmdirs = qw(lib blib sbin bin);
+all_pm_files_ok(all_pm_files(@pmdirs));
Added: t/01_Apt-PM.t
URL: http://svn.debian.org/wsvn/t/01_Apt-PM.t?rev=54159&op=file
==============================================================================
--- t/01_Apt-PM.t (added)
+++ t/01_Apt-PM.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,279 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+#use Test::More 'no_plan';
+use Test::More tests => 12;
+use Test::Differences;
+use Test::Exception;
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+BEGIN {
+ use_ok ( 'Apt::PM' ) or exit;
+}
+
+exit main();
+
+sub main {
+ INTERNAL_parse_perl_modules: {
+ my $t1 = " MM (0.001001)\n";
+ my $t2 = " \n M1 (1)\n M3 (3)\n M2 (2)\n";
+ my $t3 = " \n BackupManager::Dialog (0)\n BackupManager::Config (0)\n BackupManager::Logger (0)\n";
+
+ is_deeply(
+ { Apt::PM::_parse_perl_modules($t1) },
+ { 'MM' => '0.001001' },
+ 'parsing Perl-Modules'
+ );
+
+ is_deeply(
+ { Apt::PM::_parse_perl_modules($t2) },
+ {
+ 'M1' => '1',
+ 'M2' => '2',
+ 'M3' => '3',
+ },
+ 'parsing Perl-Modules'
+ );
+
+ is_deeply(
+ { Apt::PM::_parse_perl_modules($t3) },
+ {
+ 'BackupManager::Dialog' => '0',
+ 'BackupManager::Config' => '0',
+ 'BackupManager::Logger' => '0',
+ },
+ 'parsing Perl-Modules'
+ );
+ }
+
+ INTERNAL_modules_index: {
+ my $aptpm = Apt::PM->new(sources => [ File::Spec->catfile($Bin, 'PerlPackages.bz2') ]);
+
+ my %deb1 = (
+ 'version' => '5.230-1',
+ 'package' => 'libanyevent-perl',
+ 'arch' => 'all',
+ );
+ my %deb2 = (
+ 'version' => '0.21-1',
+ 'package' => 'libclass-c3-perl',
+ 'arch' => 'all',
+ );
+
+ eq_or_diff(
+ $aptpm->_modules_index,
+ {
+ 'Class::C3' => { '0.21' => \%deb2 },
+ 'AnyEvent::Impl::EventLib' => { '0' => \%deb1 },
+ 'AnyEvent::Strict' => { '0' => \%deb1 },
+ 'AnyEvent::CondVar' => { '0' => \%deb1 },
+ 'AnyEvent::TLS' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Qt::Io' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Tk' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Irssi' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::IOAsync' => { '0' => \%deb1 },
+ 'AnyEvent::CondVar::Base' => { '0' => \%deb1 },
+ 'AnyEvent::Util' => { '0' => \%deb1 },
+ 'AnyEvent::Base' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Qt' => { '0' => \%deb1 },
+ 'AnyEvent::Handle' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Perl' => { '0' => \%deb1 },
+ 'AnyEvent' => { '5.23' => \%deb1 },
+ 'AnyEvent::DNS' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Qt::Timer' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::EV' => { '0' => \%deb1 },
+ 'AnyEvent::Debug::shell' => { '0' => \%deb1 },
+ 'AnyEvent::Debug' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::POE' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Event' => { '0' => \%deb1 },
+ 'AE' => { '0' => \%deb1 },
+ 'AnyEvent::Socket' => { '0' => \%deb1 },
+ 'AnyEvent::Impl::Glib' => { '0' => \%deb1 }
+ },
+ 'building modules index'
+ );
+
+ my $aptpm2 = Apt::PM->new(sources => [
+ File::Spec->catfile($Bin, 'PerlPackages.bz2'),
+ File::Spec->catfile($Bin, 'PerlPackages2.bz2'),
+ ]);
+
+ my %deb3 = (
+ 'version' => '1.000-1',
+ 'package' => 'libanyevent-perl',
+ 'arch' => 'all',
+ );
+ my %deb4 = (
+ 'version' => '0.22-1',
+ 'package' => 'libclass-c3-perl',
+ 'arch' => 'all',
+ );
+ my %deb5 = (
+ 'version' => '4.00-1',
+ 'package' => 'libclass-c4-perl',
+ 'arch' => 'all',
+ );
+ my %result2 = (
+ 'Class::C3' => {
+ '0.21' => \%deb2,
+ '0.22' => \%deb4,
+ },
+ 'AnyEvent::Impl::EventLib' => { '0' => \%deb3 },
+ 'AnyEvent::Strict' => { '0' => \%deb3 },
+ 'AnyEvent::CondVar' => { '0' => \%deb3 },
+ 'AnyEvent::TLS' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Qt::Io' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Tk' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Irssi' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::IOAsync' => { '0' => \%deb3 },
+ 'AnyEvent::CondVar::Base' => { '0' => \%deb3 },
+ 'AnyEvent::Util' => { '0' => \%deb3 },
+ 'AnyEvent::Base' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Qt' => { '0' => \%deb3 },
+ 'AnyEvent::Handle' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Perl' => { '0' => \%deb3 },
+ 'AnyEvent' => {
+ '1.000' => \%deb3,
+ '5.23' => \%deb1,
+ },
+ 'AnyEvent::DNS' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Qt::Timer' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::EV' => { '0' => \%deb3 },
+ 'AnyEvent::Debug::shell' => { '0' => \%deb3 },
+ 'AnyEvent::Debug' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::POE' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Event' => { '0' => \%deb3 },
+ 'AE' => { '0' => \%deb3 },
+ 'AnyEvent::Socket' => { '0' => \%deb3 },
+ 'AnyEvent::Impl::Glib' => { '0' => \%deb3 },
+ 'Class::C4' => { '4.00' => \%deb5 },
+ );
+
+ eq_or_diff(
+ $aptpm2->_modules_index,
+ \%result2,
+ 'building combined modules index'
+ );
+
+ my $aptpm3 = Apt::PM->new(sources => [
+ File::Spec->catfile($Bin, 'PerlPackages2.bz2'),
+ File::Spec->catfile($Bin, 'PerlPackages.bz2'),
+ ]);
+ eq_or_diff(
+ $aptpm3->_modules_index,
+ \%result2,
+ 'building combiner modules index (reverse input files order)'
+ );
+ }
+
+ INTERNAL_etc_apt_sources: {
+ my $aptpm = Apt::PM->new();
+ my @web_sources;
+ lives_ok { @web_sources = $aptpm->_etc_apt_sources } 'call parsing of /etc/apt/sources';
+ note('web sources on this machine:', "\n", join("\n", @web_sources));
+ };
+
+ FIND: {
+ my $aptpm = Apt::PM->new(sources => [
+ File::Spec->catfile($Bin, 'PerlPackages.bz2'),
+ File::Spec->catfile($Bin, 'PerlPackages2.bz2'),
+ ]);
+
+ eq_or_diff(
+ $aptpm->find('AnyEvent'), {
+ '1.000' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '1.000-1'
+ },
+ '5.23' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ }
+ },
+ 'find()',
+ );
+
+ eq_or_diff(
+ $aptpm->find('AnyEvent', '0.01'), {
+ '1.000' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '1.000-1'
+ },
+ 'min' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '1.000-1'
+ },
+ '5.23' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ 'max' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ },
+ 'find(min 0.01)',
+ );
+
+ eq_or_diff(
+ $aptpm->find('AnyEvent', '1.50'), {
+ '1.000' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '1.000-1'
+ },
+ 'min' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ '5.23' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ 'max' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ },
+ 'find(min 1.50)',
+ );
+
+ eq_or_diff(
+ $aptpm->find('AnyEvent', '5.3'), {
+ '1.000' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '1.000-1'
+ },
+ '5.23' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ 'max' => {
+ arch => 'all',
+ package => 'libanyevent-perl',
+ version => '5.230-1',
+ },
+ 'min' => undef,
+ },
+ 'find(min 5.3)',
+ );
+ }
+
+ return 0;
+}
+
Added: t/PerlPackages.bz2
URL: http://svn.debian.org/wsvn/t/PerlPackages.bz2?rev=54159&op=file
==============================================================================
Binary file - no diff available.
Propchange: t/PerlPackages.bz2
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: t/PerlPackages2.bz2
URL: http://svn.debian.org/wsvn/t/PerlPackages2.bz2?rev=54159&op=file
==============================================================================
Binary file - no diff available.
Propchange: t/PerlPackages2.bz2
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: t/distribution.t
URL: http://svn.debian.org/wsvn/t/distribution.t?rev=54159&op=file
==============================================================================
--- t/distribution.t (added)
+++ t/distribution.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,4 @@
+use Test::More;
+
+eval 'use Test::Distribution not => "sig"';
+plan( skip_all => 'Test::Distribution not installed') if $@;
Added: t/fixme.t
URL: http://svn.debian.org/wsvn/t/fixme.t?rev=54159&op=file
==============================================================================
--- t/fixme.t (added)
+++ t/fixme.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,9 @@
+use strict;
+use warnings;
+use Test::More;
+
+eval "use Test::Fixme";
+plan skip_all => "requires Test::Fixme to run"
+ if $@;
+
+run_tests();
Added: t/pod-coverage.t
URL: http://svn.debian.org/wsvn/t/pod-coverage.t?rev=54159&op=file
==============================================================================
--- t/pod-coverage.t (added)
+++ t/pod-coverage.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,18 @@
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod::Coverage
+my $min_tpc = 1.08;
+eval "use Test::Pod::Coverage $min_tpc";
+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
+ if $@;
+
+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
+# but older versions don't recognize some common documentation styles
+my $min_pc = 0.18;
+eval "use Pod::Coverage $min_pc";
+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
+ if $@;
+
+all_pod_coverage_ok();
Added: t/pod-spell.t
URL: http://svn.debian.org/wsvn/t/pod-spell.t?rev=54159&op=file
==============================================================================
--- t/pod-spell.t (added)
+++ t/pod-spell.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,25 @@
+use Test::More;
+
+if (!$ENV{TEST_SPELLING}) {
+ plan skip_all =>
+ "Set the environment variable TEST_SPELLING to enable this test.";
+}
+
+eval 'use Test::Spelling;';
+
+plan skip_all => "Test::Spelling required for testing POD spelling"
+ if $@;
+
+add_stopwords(qw(
+ Jozef Kutej
+ OFC
+ API
+ JSON
+ TBD
+ html
+ RT
+ CPAN
+ AnnoCPAN
+ http
+));
+all_pod_files_spelling_ok();
Added: t/pod.t
URL: http://svn.debian.org/wsvn/t/pod.t?rev=54159&op=file
==============================================================================
--- t/pod.t (added)
+++ t/pod.t Fri Mar 12 10:59:46 2010
@@ -1,0 +1,12 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod
+my $min_tp = 1.22;
+eval "use Test::Pod $min_tp";
+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
+
+all_pod_files_ok();
More information about the Pkg-perl-cvs-commits
mailing list