PAX
view release on metacpan or search on metacpan
lib/PAX/StandaloneRuntime.pm view on Meta::CPAN
}
return File::Spec->catfile('virtual', 'entrypoint.pl');
}
sub _run_entrypoint {
my ($entrypoint) = @_;
if ($entrypoint =~ /\.service\.json\z/) {
return _run_service_dispatch_unit($entrypoint);
}
if ($entrypoint =~ /\.cli-router\.json\z/) {
return _run_cli_router_unit($entrypoint);
}
if ($entrypoint =~ /\.dispatch\.json\z/) {
return _run_dispatch_script_unit($entrypoint);
}
if ($entrypoint =~ /\.script\.json\z/) {
return _run_script_unit($entrypoint);
}
my $rv = do $entrypoint;
die $@ if $@;
die "failed to load $entrypoint: $!" if !defined($rv) && $!;
return $rv;
}
sub _run_service_dispatch_unit {
my ($entrypoint) = @_;
open my $fh, '<', $entrypoint or die "cannot read service dispatch unit $entrypoint: $!";
local $/;
my $record = _runtime_json_decode(<$fh>);
my $cmd = shift(@ARGV);
$cmd = 'version' if !defined($cmd) || $cmd eq '';
if ($cmd eq 'version') {
print(($record->{version} // '0.0.0') . "\n");
exit 0;
}
if ($cmd eq 'serve') {
(my $app_module_path = ($record->{app_module} // '')) =~ s{::}{/}g;
$app_module_path .= '.pm' if $app_module_path ne '';
(my $server_module_path = ($record->{server_module} // '')) =~ s{::}{/}g;
$server_module_path .= '.pm' if $server_module_path ne '';
_load_compiled_require($app_module_path) || require $app_module_path;
require $server_module_path;
my $host = '127.0.0.1';
my $port = 5000;
while (@ARGV) {
my $arg = shift @ARGV;
if ($arg eq '--host') {
$host = shift @ARGV // die "--host requires a value\n";
next;
}
if ($arg eq '--port') {
$port = shift @ARGV // die "--port requires a value\n";
next;
}
die "unexpected argument: $arg\n";
}
my $asset_root = $ENV{PAX_EMBEDDED_ASSET_ROOT}
|| File::Spec->catdir(dirname(_virtual_entrypoint_path($entrypoint)), '..', 'share');
my $builder_method = $record->{builder_method} || 'build_psgi_app';
my $app_module = $record->{app_module} || die "service dispatch missing app module\n";
my $server_module = $record->{server_module} || die "service dispatch missing server module\n";
my $app = $app_module->$builder_method(asset_root => $asset_root);
my $server = $server_module->new;
$server->run($app, {
host => $host,
port => $port,
listen => ["$host:$port"],
workers => 1,
});
return 0;
}
die "unknown command: $cmd\n";
}
sub _run_cli_router_unit {
my ($entrypoint) = @_;
open my $fh, '<', $entrypoint or die "cannot read cli router unit $entrypoint: $!";
local $/;
my $record = _runtime_json_decode(<$fh>);
my $path = _virtual_entrypoint_path($entrypoint);
my $bootstrap = $record->{bootstrap_source};
if (defined $bootstrap && $bootstrap ne '') {
my $wrapped = "package main;\n#line 1 \"$path\"\n" . $bootstrap;
my $rv = eval $wrapped;
die $@ if $@;
}
my $cmd = shift @ARGV || '';
_code_for('main::_load_runtime_env')->() if _code_for('main::_load_runtime_env');
_code_for('main::_prime_command_result_env')->($cmd, @ARGV)
if $cmd ne '' && _code_for('main::_prime_command_result_env');
if ($cmd eq '') {
main::pod2usage(
-exitval => 1,
-verbose => 99,
-sections => [qw(NAME SYNOPSIS)],
);
}
elsif ($cmd eq 'help' || $cmd eq '--help' || $cmd eq '-h') {
main::pod2usage(
-exitval => 0,
-verbose => 99,
);
}
if ($cmd eq 'version') {
my $version_module = $record->{version_module} || die "cli router missing version module\n";
_load_package_by_module_name($version_module);
no strict 'refs';
print ${$version_module . '::VERSION'}, "\n";
exit 0;
}
if (my $helper_path = _code_for('main::_builtin_helper_path')->($cmd)) {
if (my $helper_name = _direct_standalone_helper_name_from_path($helper_path)) {
lib/PAX/StandaloneRuntime.pm view on Meta::CPAN
if ($cmd ne '') {
my $suggest_class = $record->{suggest_class} || die "cli router missing suggest class\n";
print STDERR $suggest_class->new()->unknown_command_message($cmd);
}
main::pod2usage(
-exitval => 1,
-verbose => 99,
-sections => [qw(NAME SYNOPSIS)],
);
}
sub _run_dispatch_script_unit {
my ($entrypoint) = @_;
open my $fh, '<', $entrypoint or die "cannot read dispatch script unit $entrypoint: $!";
local $/;
my $record = _runtime_json_decode(<$fh>);
my $path = _virtual_entrypoint_path($entrypoint);
my $bootstrap = $record->{bootstrap_source};
if (defined $bootstrap && $bootstrap ne '') {
my $wrapped = "package main;\n#line 1 \"$path\"\n" . $bootstrap;
my $rv = eval $wrapped;
die $@ if $@;
}
my $cmd = shift(@ARGV);
if (($record->{command_default_mode} // '') eq 'defined_or') {
$cmd = $record->{command_default} if !defined $cmd;
} else {
$cmd = $record->{command_default} if !defined($cmd) || $cmd eq '';
}
for my $entry (@{ $record->{actions} // [] }) {
next if ($entry->{command} // '') ne (defined $cmd ? $cmd : '');
return _run_dispatch_action($entry->{action}, $cmd);
}
if (my $unknown = $record->{unknown_action}) {
return _run_dispatch_action($unknown, $cmd);
}
die "no dispatch action for command " . (defined $cmd ? $cmd : '(undef)');
}
sub _run_dispatch_action {
my ($action, $cmd) = @_;
my $op = $action->{op} // die 'dispatch action op missing';
if ($op eq 'print_call') {
my $cv = _code_for($action->{target}) or die "missing dispatch target $action->{target}";
my $value = $cv->(@{ $action->{args} // [] });
print $value;
print "\n" if $action->{newline};
exit($action->{exit_code} // 0);
}
if ($op eq 'print_required_global') {
my $module = $action->{require_module} // die 'dispatch require module missing';
_load_package_by_module_name($module);
no strict 'refs';
my $value = ${ $action->{symbol} };
print $value;
print "\n" if $action->{newline};
exit($action->{exit_code} // 0);
}
if ($op eq 'print_embedded_asset') {
my $root = $ENV{PAX_EMBEDDED_ASSET_ROOT} // '';
my $logical = $action->{logical_path} // die 'dispatch asset logical path missing';
my $path = $root ? File::Spec->catfile($root, split m{/}, $logical) : '';
if (!$path || !-f $path) {
print STDERR "missing asset\n";
exit 3;
}
open my $fh, '<', $path or die $!;
local $/;
my $content = <$fh>;
close $fh;
print $content;
exit 0;
}
if ($op eq 'stderr_interpolate_cmd') {
print STDERR ($action->{prefix} // '') . (defined $cmd ? $cmd : '') . ($action->{suffix} // '');
exit($action->{exit_code} // 0);
}
die "unsupported dispatch action op: $op";
}
sub _run_script_unit {
my ($entrypoint) = @_;
open my $fh, '<', $entrypoint or die "cannot read script unit $entrypoint: $!";
local $/;
my $record = _runtime_json_decode(<$fh>);
my $source = $record->{script_source} // _script_source_from_code_units($entrypoint)
// _source_path_to_script_source($entrypoint)
// _script_source_from_residual_payload($entrypoint);
die "script source missing for $entrypoint" if !defined $source;
die "script source is empty for $entrypoint" if $source eq '';
$source = _apply_compiled_script_subs($source, $record->{compiled_subs} // []);
my $path = _virtual_entrypoint_path($entrypoint);
my $wrapped = "package main;\n#line 1 \"$path\"\n" . $source;
my $rv = eval $wrapped;
die $@ if $@;
return 0 if !defined($rv);
if (my $invocation = $record->{entry_invocation}) {
my $op = $invocation->{op} // '';
if ($op eq 'call_main_argv_and_exit') {
my $cv = _code_for('main::main') or die "script unit $path missing main";
exit(($cv->(@ARGV) // 0));
}
die "unsupported script entry invocation op: $op";
}
return $rv;
}
sub _script_source_from_code_units {
my ($entrypoint) = @_;
my $state = _state();
my $unit = _find_code_unit_for_entrypoint($entrypoint);
return if !$unit;
return $unit->{script_source} if defined $unit->{script_source};
my $bytes = $unit->{bytes};
return if !defined $bytes;
my $decoded = eval { _runtime_json_decode($bytes) };
return $decoded->{script_source} if ref($decoded) eq 'HASH' && defined $decoded->{script_source};
return $bytes;
}
( run in 0.777 second using v1.01-cache-2.11-cpan-71847e10f99 )