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 ? '-' : '--';
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",
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 )