Pinto-Remote-SelfContained

 view release on metacpan or  search on metacpan

lib/Pinto/Remote/SelfContained.pm  view on Meta::CPAN

        name => $action_name,
        args => $action_args,
        root => $self->root,
        username => $self->username,
        password => $self->password,
        chrome => $self->chrome,
        httptiny => $self->httptiny,
    );
}

sub run_streaming {
    my ($self, $streaming_callback, $action_name, @args) = @_;

    my $action = $self->make_action($action_name, @args);

    $action->execute($streaming_callback);;
}

sub load_class_for_action {
    my ($self, %args) = @_;

    my $action_name = $args{name}
        or croak('Must specify an action name');

    my $class  = __PACKAGE__ . "::Action::\u$action_name";
    use_package_optimistically($class);

lib/Pinto/Remote/SelfContained/Action.pm  view on Meta::CPAN

has name => (is => 'ro', isa => Str, required => 1);
has root => (is => 'ro', isa => Uri, coerce => 1, required => 1);
has args => (is => 'ro', isa => HashRef, default => sub { {} });

has username => (is => 'ro', isa => Username, required => 1);
has password => (is => 'ro', isa => Maybe[Str], required => 1);

has error => (is => 'rw');

sub execute {
    my ($self, $streaming_callback) = @_;

    my $request = $self->_make_request;
    my $response = $self->_send_request($request, $streaming_callback);

    return $self->_make_result($response);
}

sub _make_result {
    my ($self, $response) = @_;

    return Pinto::Remote::SelfContained::Result->new
        if $response->{success};

lib/Pinto/Remote/SelfContained/Action.pm  view on Meta::CPAN


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

    my $action_args = $self->args;

    return { name => 'action', data => encode_json($action_args) };
}

sub _send_request {
    my ($self, $request, $streaming_callback) = @_;

    $request //= $self->_make_request;

    my $status = 0;
    my $buffer = '';
    my $callback = sub { $self->_response_callback( $streaming_callback, \$status, \$buffer, @_ ) };
    my $response = $self->httptiny->request( $request->as_request_items($callback) );

    $self->chrome->progress_done;

    return $response;
}

sub _response_callback {
    my ($self, $streaming_callback, $status_ref, $buffer_ref, $new_data, $partial_result) = @_;

    $partial_result->{content} .= $new_data;
    $$buffer_ref .= $new_data;

    while ($$buffer_ref =~ s/\A (.*) \n//x) {
        my $line = $1;
        if ($line eq '## Status: ok') {
            $$status_ref = 1;
        }
        elsif ($line eq '## -- ##') {

lib/Pinto/Remote/SelfContained/Action.pm  view on Meta::CPAN

        }
        elsif ($line eq '## . ##') {
            # Progress message
            $self->chrome->show_progress;
        }
        elsif ($line =~ m{^## (.*)}) {
            # Diagnostic message; emit as warning
            $self->chrome->diag("$1");
        }
        else {
            # Other: emit as text, and send to any streaming callback
            $self->chrome->show($line);
            $streaming_callback->($line) if $streaming_callback;
        }
    }
}

1;

__END__

=pod

lib/Pinto/Remote/SelfContained/Action/Install.pm  view on Meta::CPAN

    my $attrs = $class->$orig(@rest);

    # Intercept attributes from the action "args" hash
    $attrs->{do_pull} = delete $attrs->{args}{do_pull} // 0;
    $attrs->{cpanm_options} = delete $attrs->{args}{cpanm_options} // {};

    return $attrs;
};

around execute => sub {
    my (undef, $self, $streaming_callback) = @_;

    if ($self->do_pull) {
        my $request = $self->_make_request('pull');
        my $response = $self->_send_request($request, $streaming_callback);
        croak('Failed to pull packages') if !$response->{success};
    }

    # Wire cpanm to our repo
    my @opts = ('--mirror', $self->mirror_uri, '--mirror-only');

    # Process other cpanm options
    my $cpanm_options = $self->cpanm_options;
    for my $opt (sort keys %$cpanm_options) {
        my $dash = length $opt == 1 ? '-' : '--';

t/action.t  view on Meta::CPAN

            protocol => 'HTTP/1.1',
            status => 200,
            reason => 'OK',
            headers => { 'Content-type' => 'application/vnd.pinto.v1+text' },
            content => $body,
        },
        'parts of response are correct',
    );
};

subtest 'streaming' => sub {
    my @body = (
        'DATA-GOES-HERE',
        '## DIAG-MSG-HERE',
        'ANOTHER-DATA-LINE',
        '## Status: ok',
    );
    my $body = join '', map "$_\n", @body;
    my $chrome = T::Chrome->new;
    my $httptiny = T::HTTPTiny->new([join('', (
        "HTTP/1.1 200 OK\r\n",

t/action.t  view on Meta::CPAN

    my $action = Pinto::Remote::SelfContained::Action->new(
        username => 'fred',
        password => undef,
        root => 'http://example.com',
        chrome => $chrome,
        httptiny => $httptiny,
        name => 'list',
    );

    my @lines;
    my $streaming_callback = sub { push @lines, [@_] };
    my $response = $action->_send_request(undef, $streaming_callback);
    is_deeply(\@lines, [ map [$_], @body[0, 2] ], 'streamed response');
};

had_no_warnings();
done_testing();



( run in 0.246 second using v1.01-cache-2.11-cpan-4d50c553e7e )