New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[9.x] Adds Process
convenience layer 🧘🏻
#43977
base: 9.x
Are you sure you want to change the base?
Conversation
@nunomaduro loving where this is headed. |
Process
convenience layer
Process
convenience layerProcess
convenience layer Process
convenience layer Process
convenience layer 🧘🏻
add some methods to run tasks in the background or get the proccess pid. |
First of all, I just saw this PR and I really love it. Thanks for the great implementation! You showed that the Personally I think that it would be somewhat more flexible to not automatically throw the exception after executing the closure. That would allow developers to provide just a closure and handle the exception themselves, without throwing (e.g. using |
Could be that you already planned on doing this bc it's still a draft, but an interesting idea would be to add a |
|
@ralphjsmit changing the throwing logic would make it inconsistent with the Http client. I think it might be nice if it was consistent and perhaps had additional affodances to handle other cases. |
Name a better love story than @nunomaduro x artisan console |
This pull request proposes an expressive, minimal API around Symfony's Process, allowing you to quickly run processes in your Laravel application. Just like the
HTTP
facade, this pull request introduces aProcess
facade that is focused on the most common use cases, testing, and a wonderful developer experience.Running Processes
To run a process, you may use the
run
method provided by theProcess
facade. Let's examine how to run a basicls
command:The
run
method returns an instance ofIlluminate\Console\Contracts\ProcessResult
, which provides a variety of methods that may be used to inspect the process result:The
Illuminate\Console\Contracts\ProcessResult
object also implements the PHPArrayAccess
interface, allowing you to iterate over each line of the output. The output, is "exploded" via the\n
character:Accessing process's output at real-time
By default, when using the
output
method, Laravel waits for the process to be finished before giving you the entire process's output:If you wish to access the process's output at real-time, you may use a closure as second argument of the
run
method:In addition, if you with to know if the given output is from the type
stderr
orstderr
, you may use the second argument of given closure:Dumping processes
If you would like to dump the outgoing process instance before it is sent and terminate the script's execution, you may add the
dump
ordd
method to the beginning of your process definition:Options
Of course, it is common when running processes to specify multiple command arguments, configure the path, timeouts, and more.
Process Command
When running processes, you may pass an string or an array of strings as the first argument to the
run
method:Process Path
You may use the
path
method if you would like to specify the working directory / base path of the process:Process Timeout
The
timeout
method may be used to specify the maximum number of seconds to wait for a process:If the given timeout is exceeded, an instance of
Illuminate\Console\Process\Exceptions\ProcessTimedOutException
will be thrown.If you don't care about the time a process takes to run, and you would just like a process to run forever, you may use the
forever
method:Process Exceptions
If you have a process result and would like to throw an instance of
Illuminate\Console\Exceptions\ProcessFailedException
if the exit code indicates an error, you may use thethrow
,throwIf
, orthrowUnless
methods:The
throw
method returns a regular result instance if no error occurred, allowing you to chain other operations onto thethrow
method:If you would like to perform some additional logic before the exception is thrown, you may pass a closure to the
throw
,throwIf
, orthrowUnless
methods. The exception will be thrown automatically after the closure is invoked, so you do not need to re-throw the exception from within the closure:Concurrent Processes
Sometimes, you may wish to run multiple processes requests concurrently. In other words, you want several processes to be dispatched at the same time instead of issuing the processes sequentially. This can lead to substantial performance improvements when interacting with slow processes.
Thankfully, you may accomplish this using the
pool
method. The pool method accepts a closure which receives anIlluminate\Console\Process\Pool
instance, allowing you to easily addprocesses
to the process pool for dispatching:Asynchronous Processes
By default, processes are synchronous, meaning the method
run
will automatically wait for the process to be finished before returning the process's result. Yet, if you need to run processes asynchronously while performing other tasks in your code, you may use theasync
method:Macros
The Process's factory is also "macroable", meaning that you may define the macro within the boot method of your application's
App\Providers\AppServiceProvider
class:Once your macro has been configured, you may invoke it from anywhere in your application to create a pending process with the specified configuration:
Testing
The
Process
facade's fake method allows you to instruct Laravel to return stubbed / dummy results when processes are made.For example, to instruct the
Process
to return successful empty result, you may call thefake
method with no arguments:Faking specific processes
Alternatively, you may pass an array to the
fake
method. The array's keys should represent command patterns that you wish to fake and their associated results. The*
character may be used as a wildcard character. Any processes made to Process commands that have not been faked will actually be executed. You may use the Process facade'sresult
method to construct stub / fake results for these processes:If you would like to specify a fallback command pattern that will stub all unmatched commands, you may use a single
*
character:Fake callback
If you require more complicated logic to determine what results to return for certain processes, you may pass a closure to the fake method. This closure will receive an instance of
Illuminate\Console\Process
and should return a result instance. Within your closure, you may perform whatever logic is necessary to determine what type of result to return:Inspecting Processes
When faking processes, you may occasionally wish to inspect the processes in order to make sure your application is sending the correct commands. You may accomplish this by calling the
Process::assertRan
method after callingProcess::fake
.The
assertRan
method accepts a closure which will receive anIlluminate\Console\Process
instance and should return a boolean value indicating if the process matches your expectations. In order for the test to pass, at least one request must have been issued matching the given expectations:If needed, you may assert that a specific process was not ran using the
assertNotRan
method:You may use the
assertRanCount
method to assert how many processes were "ran" during the test:Or, you may use the
assertNothingRan
method to assert that no processes were ran during the test: