Skip to content

pawjy/perl-promised-command

Repository files navigation

NAME

Promised::Command - Run a command

SYNOPSIS

use Promised::Command;

$cmd = Promised::Command->new (['ls', '-a', '/']);
$cmd->run->then (sub {
  return $cmd->wait;
})->then (sub {
  my $result = $_[0];
  if ($result->exit_code == 0) {
    warn "done";
  } else {
    warn "failed";
  }
});

DESCRIPTION

The Promised::Command class provides a Promise-returning command execution interface.

METHODS

Following methods are available:

$cmd = Promised::Command->new ($args)

Create a new command object. The argument must be an array reference containing a command (zeroth item) and zero or more arguments (first or later items).

$promise = $cmd->run

Start the execution of the command. It returns a Promise, which is resolved with a result object when the execution is started.

This method cannot be invoked multiple times.

$promise = $cmd->wait

Return a Promise, which is resolved with a result object once the execution of the command has finished.

This method can be invoked before the run's promise is resolved, but it must be invoked after the run method is invoked. This method always returns the same promise.

The promise is resolved with a result object whose is_success method returns true even when the exit code of the command is non-zero. Note also that failure to execute the command (e.g. command-not-found error) is also result in resolving the promise with a successful result object whose exit code is non-zero.

If the command has terminated by an uncaught signal, the promise is rejected with a result object whose is_error method returns true.

$boolean = $cmd->create_process_group
$cmd->create_process_group ($boolean)

Get or set whether a new process group should be created for the command (by setpgrp) or not.

This method must be invoked before the run method is invoked. If this method is not invoked, the same process group as the main process is used.

$cmd->wd ($string)
$string = $cmd->wd

Get or set the current working directory for the command as a (system-dependent byte) string.

This method must be invoked before the run method is invoked. If this method is not invoked, the current directory is left unchanged (i.e. same as that of the main process).

$hashref = $cmd->envs

Return the environment variables for the command as a reference to the hash of environment name/value byte string pairs.

If a value is specified in the hash, an environment variable is set. Otherwise, if an undef value is explicitly specified in the hash, the environment variable, if any, is unset. Otherwise, any environment variable of the main process is left unchanged. This method must be invoked before the run method is invoked.

$stream = $cmd->get_stdin_stream
$cmd->stdin (SCALARREF)

Specify how the standard input is handled.

If the get_stdin_stream is invoked, a WritableStream object that is a writable stream of the input is returned. Any written value (i.e. the argument too the write method of the writer) must be an ArrayBufferView (such as DataView and TypedArray::Uint8Array). If the stream is aborted, the input is closed as soon as possible (which means not all data might be written, though it does not affect the execution of the child process).

If a scalar reference is specified to the stdin method, the referenced scalar value is written as the input. The referenced value must be a byte string.

Only one of these methods must be invoked at most once. These methods must be invoked before the run method is invoked.

If these methods are not invoked, the input's handling is left unchanged (i.e. same as the standard input of the main process).

$stream = $cmd->get_stdout_stream
$cmd->stdout (SCALARREF)
$cmd->stdout (CODE)
$stream = $cmd->get_stderr_stream
$cmd->stderr (SCALARREF)
$cmd->stderr (CODE)

Specify how the standard output or the standard error output is handled.

If the get_stdout_stream or get_stderr_stream method is invoked, a ReadableStream object that is a readable byte stream of the output is returned. If the stream is canceled, any remaining data are silently discarded (which does not affect the child process).

If a scalar reference is specified to the stdout or stderr method, the output is set to the referenced scalar value.

If a code reference is specified to the stdout or stderr method, the code is invoked with a chunk as the argument whenever the chunk is available, and with an undef as the argument when the end of the output is reached.

Only one of these methods must be invoked at most once for each of standard output and standard error output. These methods must be invoked before the run method is invoked.

If these methods are not invoked, the output's handling is left unchanged (i.e. same as the standard output or the standard error output of the main process).

$pid = $cmd->pid

Return the process ID of the child process (i.e. the command's process).

This method can be invoked after the run promise is resolved. Note that there can no longer be the process with the ID or can be a different process with the ID if the command has finished.

$boolean = $cmd->running

Return whether the command is running or not.

Note that returning a true value does not mean the command is actually in active; it might be finished but not waitpided by this process yet.

$promise = $cmd->send_signal ($signal)

Send a signal to the command's process, if running.

The argument must be a string or integer representing the signal, such as INT or 2, or zero to not send any signal. See perldoc -f kill.

The method returns a Promise, which is resolved with a result object whose killed method returns the number of processed to which the signal is sent. If the command's process is no longer running, the signal is sent to no process.

$value = $cmd->propagate_signal
$cmd->propagate_signal ($value)

Get or set whether signals to this (main) process should be propagated to the child (command) process or not.

The value can be a non-reference value or an array reference of signal names or an array reference of a pair of signal names. A non-reference value is equivalent to ['INT', 'QUIT', 'TERM']. A pair of signal names represents that when the first signal is received by the main process, the second signal should be sent to the child process instead. The value represents the types of the signals to propagate. Signals specified by this method caught by the main process result in terminating the main process after the propagation.

This method must be invoked before the run method is invoked. If this method is not invoked, no signal is propagated.

If signals are to be propagated, any other signal handling should be done through Promised::Command::Signals to avoid confliction of signal handlers.

$signal = $cmd->signal_before_destruction
$cmd->signal_before_destruction ($signal)

Get or set the signal (e.g. KILL or TERM) which should be sent to the command (child) process if it is still running when the command object is destroyed (i.e. the $cmd object is destroyed without its wait method invoked). This feature is useful when the command object can be discarded by unexpected shutdown of the application (e.g. Perl runtime error) but still need to ensure that child process should be terminated.

This method must be invoked before the run method is invoked. If this method is not invoked, no signal is sent.

$seconds = $cmd->timeout
$cmd->timeout ($seconds)

Get or set the timeout from the execution of the command in seconds. If a positive number is specified, the signal specified by the timeout_signal method is sent to the command's process, if any. Otherwise no timeout is set.

This method must be invoked before the run method is invoked.

$signal = $cmd->timeout_signal
$cmd->timeout_signal ($signal)

Get or set the signal (e.g. KILL or TERM) which should be sent when the timeout seconds has elapsed before the command returns. It is set to TERM unless explicitly specified.

This method must be invoked before the run method is invoked.

$cmd->abort_signal ($asignal)

Set the abort signal (AbortSignal object from the https://github.com/wakaba/perl-promise respository; the value returned by the $abort_controller->signal method) which can be used to send a signal to terminate the process.

The signal sent when aborted is specified by the timeout_signal method.

This method must be invoked before the run method is invoked.

RESULT OBJECT

Promises are resolved with a result object, which has following methods:

$boolean = $result->is_success
$boolean = $result->is_error

Whether the operation has succeded or in error. Note that !!$result->is_success == !!!$result->is_error is always true.

$string = '' . $result

Return a short message of the result for the developer.

$int = $result->exit_code

Return the exit code of the command, if applicable, or -1 otherwise.

$int = $result->signal

Return the signal which terminates the command, if applicable.

$boolean = $result->core_dump

Return whether there is a core dump or not, if applicable.

$int = $result->killed

Return the number of process to which the signal is sent. Used by send_signal's promise.

$string = $result->message

Return a short error message for the developer, if available.

ENVIRONMENT VARIABLE

If the environment variable PROMISED_COMMAND_DEBUG is set to a true value, debug messages are printed to the standard error output.

SEE ALSO

There are related modules: Promised::Command::Signals, Promised::Command::Docker.

DEPENDENCY

The module requires Perl 5.10 or later.

The module requires Promise <https://github.com/wakaba/perl-promise> and AnyEvent::Util.

Methods get_stdin_stream, get_stdout_stream, and get_stderr_stream require the ReadableStream module from the perl-streams repository <https://github.com/manakai/perl-streams>.

AUTHOR

Wakaba <wakaba@suikawiki.org>.

HISTORY

This repository was located at <https://github.com/wakaba/perl-promised-command> until 2 February, 2022.

LICENSE

Copyright 2015-2022 Wakaba <wakaba@suikawiki.org>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Releases

No releases published

Packages

No packages published