App-UpdateCPANfile

 view release on metacpan or  search on metacpan

lib/App/UpdateCPANfile.pm  view on Meta::CPAN

package App::UpdateCPANfile;
use 5.010001;
use strict;
use warnings;
use Module::CPANfile;
use Module::CPANfile::Writer;
use App::UpdateCPANfile::CPANfileSnapshotParser;
use App::UpdateCPANfile::PackageDetails;
use App::UpdateCPANfile::Change;
use Module::CoreList;
use List::Util qw(shuffle);

our $VERSION = "1.1.1";

sub new {
    my ($class, $path, $snapshot_path, $options) = @_;
    bless {
        path => $path,
        snapshot_path => $snapshot_path,
        options => $options,
    }, $class;
}

sub path {
    $_[0]->{path} // 'cpanfile';
}

sub snapshot_path {
    $_[0]->{snapshot_path} // 'cpanfile.snapshot';
}

sub options {
    $_[0]->{options} // {};
}

sub parser {
    my ($self) = @_;

    $self->{parser} //= Module::CPANfile->load($self->path);
}

sub writer {
    my ($self) = @_;

    $self->{writer} //= Module::CPANfile::Writer->new($self->path);
}

sub package_details {
    my ($self) = @_;

    $self->{package_details} //= App::UpdateCPANfile::PackageDetails->new;
}

sub pin_dependencies {
    my ($self) = @_;
    my $changeset = $self->create_pin_dependencies_changeset;
    $self->_save_changes_to_file($changeset);
    return $changeset;
}

sub update_dependencies {
    my ($self) = @_;
    my $changeset = $self->create_update_dependencies_changeset;
    my $writer = $self->writer;
    $self->_save_changes_to_file($changeset);
    return $changeset;
}

sub create_pin_dependencies_changeset {
    my ($self) = @_;

    my $distributions = App::UpdateCPANfile::CPANfileSnapshotParser->scan_deps($self->snapshot_path);

    my $prereqs = $self->parser->prereqs;
    my $added_dependencies = [];

    my $all_phases = {};
    for my $phase ($prereqs->phases) {
        for my $type ($prereqs->types_in($phase)) {
            $all_phases->{$type}++;
        }
    }

    # If arguments are omitted, it defaults to "runtime", "build" and "test" for phases and "requires" and "recommends" for types.
    my $requirements = $prereqs->merged_requirements([$self->parser->prereqs->phases], [keys %$all_phases]);

    for my $module (sort $requirements->required_modules) {
        next if $self->_is_perl($module);
        my $required_version = $requirements->requirements_for_module($module);
        my $installed_module = $self->_find_installed_module($distributions, $module);
        my $installed_version = defined $installed_module && $installed_module->version_for($module);
        next if $self->_is_core_module($module, $installed_version);
        if (defined $installed_module && defined $installed_version && (! defined $required_version || $required_version ne "== $installed_version") && ($installed_version ne 'undef')) {
            push @$added_dependencies, App::UpdateCPANfile::Change->new(package_name => $module, version => $installed_version, path => $installed_module->pathname);
        }

    }

    return $self->_apply_filter($added_dependencies);
}

sub create_update_dependencies_changeset {
    my ($self) = @_;

    my $prereqs = $self->parser->prereqs;

    my $all_phases = {};
    for my $phase ($prereqs->phases) {
        for my $type ($prereqs->types_in($phase)) {
            $all_phases->{$type}++;
        }
    }

    # If arguments are omitted, it defaults to "runtime", "build" and "test" for phases and "requires" and "recommends" for types.
    my $requirements = $prereqs->merged_requirements([$self->parser->prereqs->phases], [keys %$all_phases]);

    my $added_dependencies = [];

    for my $module (sort $requirements->required_modules) {
        my $required_version = $requirements->requirements_for_module($module);
        next if $self->_is_perl($module, $required_version);



( run in 0.744 second using v1.01-cache-2.11-cpan-9581c071862 )