App-Ikachan
view release on metacpan or search on metacpan
inc/Module/CPANfile.pm view on Meta::CPAN
sub _dump {
my $str = shift;
require Data::Dumper;
chomp(my $value = Data::Dumper->new([$str])->Terse(1)->Dump);
$value;
}
sub to_string {
my($self, $include_empty) = @_;
my $prereqs = $self->{result}{spec};
my $code = '';
$code .= $self->_dump_prereqs($self->{result}{spec}, $include_empty);
for my $feature (values %{$self->{result}{features}}) {
$code .= sprintf "feature %s, %s => sub {\n", _dump($feature->{identifier}), _dump($feature->{description});
$code .= $self->_dump_prereqs($feature->{spec}, $include_empty, 4);
$code .= "}\n\n";
}
$code =~ s/\n+$/\n/s;
$code;
}
sub _dump_prereqs {
my($self, $prereqs, $include_empty, $base_indent) = @_;
my $code = '';
for my $phase (qw(runtime configure build test develop)) {
my $indent = $phase eq 'runtime' ? '' : ' ';
$indent = (' ' x ($base_indent || 0)) . $indent;
my($phase_code, $requirements);
$phase_code .= "on $phase => sub {\n" unless $phase eq 'runtime';
for my $type (qw(requires recommends suggests conflicts)) {
for my $mod (sort keys %{$prereqs->{$phase}{$type}}) {
my $ver = $prereqs->{$phase}{$type}{$mod};
$phase_code .= $ver eq '0'
? "${indent}$type '$mod';\n"
: "${indent}$type '$mod', '$ver';\n";
$requirements++;
}
}
$phase_code .= "\n" unless $requirements;
$phase_code .= "};\n" unless $phase eq 'runtime';
$code .= $phase_code . "\n" if $requirements or $include_empty;
}
$code =~ s/\n+$/\n/s;
$code;
}
package Module::CPANfile::Environment;
use strict;
use Carp ();
my @bindings = qw(
on requires recommends suggests conflicts
feature
osname
configure_requires build_requires test_requires author_requires
);
my $file_id = 1;
sub import {
my($class, $result_ref) = @_;
my $pkg = caller;
$$result_ref = Module::CPANfile::Result->new;
for my $binding (@bindings) {
no strict 'refs';
*{"$pkg\::$binding"} = sub { $$result_ref->$binding(@_) };
}
}
sub parse {
my $file = shift;
my $code = do {
open my $fh, "<", $file or die "$file: $!";
join '', <$fh>;
};
my($res, $err);
{
local $@;
$res = eval sprintf <<EVAL, $file_id++;
package Module::CPANfile::Sandbox%d;
no warnings;
my \$_result;
BEGIN { import Module::CPANfile::Environment \\\$_result };
# line 1 "$file"
$code;
\$_result;
EVAL
$err = $@;
}
if ($err) { die "Parsing $file failed: $err" };
return $res;
}
package Module::CPANfile::Result;
use strict;
sub from_prereqs {
my($class, $spec) = @_;
bless {
phase => 'runtime',
spec => $spec,
}, $class;
}
sub new {
bless {
phase => 'runtime', # default phase
features => {},
feature => undef,
spec => {},
}, shift;
}
sub on {
my($self, $phase, $code) = @_;
local $self->{phase} = $phase;
$code->()
}
( run in 1.955 second using v1.01-cache-2.11-cpan-2398b32b56e )