diff --git a/.cache/.gitkeep b/.cache/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/.gitattributes b/.gitattributes
index 6b37862..dfb1fdc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -13,3 +13,7 @@
/docker-compose.yml export-ignore
/infection.json.dist export-ignore
/psalm.xml export-ignore
+
+*.php text=auto eol=lf
+*.sh text=auto eol=lf
+/run text=auto eol=lf
diff --git a/.idea/php.xml b/.idea/php.xml
index 4cfc551..1c3c423 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -13,6 +13,10 @@
+
+
+
+
diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml
index 4f8104c..84ebdd2 100644
--- a/.idea/phpunit.xml
+++ b/.idea/phpunit.xml
@@ -4,6 +4,7 @@
diff --git a/composer.json b/composer.json
index 83d668c..614863c 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "codenamephp/deploymentchecks.async",
- "description": "",
+ "description": "Package that let's you run the deployment checks in parallel.",
"type": "library",
"license": "Apache-2.0",
"authors": [
@@ -10,7 +10,9 @@
}
],
"require": {
- "php": "^8.2"
+ "php": "^8.2",
+ "codenamephp/deploymentchecks.base": "*",
+ "spatie/async": "^1.5"
},
"autoload": {
"psr-4": {
diff --git a/docker/application/Dockerfile b/docker/application/Dockerfile
index 9fc630c..db7acbc 100644
--- a/docker/application/Dockerfile
+++ b/docker/application/Dockerfile
@@ -1,4 +1,4 @@
-FROM webdevops/php-dev:8.1
+FROM webdevops/php-dev:8.2
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
COPY --from=phario/phive:0.15.2 /usr/local/bin/phive /usr/local/bin/phive
diff --git a/run b/run
new file mode 100755
index 0000000..54bd5d9
--- /dev/null
+++ b/run
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+#
+# Copyright 2023 Bastian Schwarz .
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+docker compose exec -it -u application application bash -c "$*"
diff --git a/src/Check/Factory/FromCheck/FromCheckFactoryInterface.php b/src/Check/Factory/FromCheck/FromCheckFactoryInterface.php
new file mode 100644
index 0000000..2a88361
--- /dev/null
+++ b/src/Check/Factory/FromCheck/FromCheckFactoryInterface.php
@@ -0,0 +1,30 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Check\Factory\FromCheck;
+
+use de\codenamephp\deploymentchecks\async\Check\ParallelCheckInterface;
+use de\codenamephp\deploymentchecks\base\Check\CheckInterface;
+
+/**
+ * Interface to create parallel checks from a regular check on the fly
+ */
+interface FromCheckFactoryInterface
+{
+
+ public function build(CheckInterface $check): ParallelCheckInterface;
+}
diff --git a/src/Check/Factory/FromCheck/WithErrorHandlerFactory.php b/src/Check/Factory/FromCheck/WithErrorHandlerFactory.php
new file mode 100644
index 0000000..326d8f0
--- /dev/null
+++ b/src/Check/Factory/FromCheck/WithErrorHandlerFactory.php
@@ -0,0 +1,46 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Check\Factory\FromCheck;
+
+use de\codenamephp\deploymentchecks\async\Check\ParallelCheckInterface;
+use de\codenamephp\deploymentchecks\async\Check\ParallelCheckWithErrorHandler;
+use de\codenamephp\deploymentchecks\async\ErrorHandler\ErrorHandlerInterface;
+use de\codenamephp\deploymentchecks\async\ErrorHandler\RethrowException;
+use de\codenamephp\deploymentchecks\async\SuccessHandler\AddToResultCollection;
+use de\codenamephp\deploymentchecks\async\SuccessHandler\SuccessHandlerInterface;
+use de\codenamephp\deploymentchecks\base\Check\CheckInterface;
+
+/**
+ * Factory to create ParallelCheckWithErrorHandler instances
+ *
+ * @psalm-api
+ */
+final class WithErrorHandlerFactory implements FromCheckFactoryInterface
+{
+ public function __construct(
+ public SuccessHandlerInterface $successHandler = new AddToResultCollection(),
+ public ErrorHandlerInterface $errorHandler = new RethrowException(),
+ ) {}
+
+ public function build(CheckInterface $check): ParallelCheckInterface
+ {
+ return new ParallelCheckWithErrorHandler($check, $this->successHandler, $this->errorHandler);
+ }
+
+
+}
diff --git a/src/Check/ParallelCheckInterface.php b/src/Check/ParallelCheckInterface.php
new file mode 100644
index 0000000..b17a792
--- /dev/null
+++ b/src/Check/ParallelCheckInterface.php
@@ -0,0 +1,42 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Check;
+
+use de\codenamephp\deploymentchecks\async\SuccessHandler\SuccessHandlerInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\ResultInterface;
+
+/**
+ * Interface for checks that can be used in parallel using the async pool
+ */
+interface ParallelCheckInterface
+{
+
+ /**
+ * Since the async pool only accepts callables, this method is used to invoke the check and return the result
+ *
+ * @return ResultInterface
+ */
+ public function __invoke(): ResultInterface;
+
+ /**
+ * Gets the success handler that is used to handle the result if the check was successful
+ *
+ * @return SuccessHandlerInterface
+ */
+ public function successHandler(): SuccessHandlerInterface;
+}
diff --git a/src/Check/ParallelCheckWithErrorHandler.php b/src/Check/ParallelCheckWithErrorHandler.php
new file mode 100644
index 0000000..3b05878
--- /dev/null
+++ b/src/Check/ParallelCheckWithErrorHandler.php
@@ -0,0 +1,59 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Check;
+
+use de\codenamephp\deploymentchecks\async\ErrorHandler\ErrorHandlerInterface;
+use de\codenamephp\deploymentchecks\async\ErrorHandler\RethrowException;
+use de\codenamephp\deploymentchecks\async\SuccessHandler\AddToResultCollection;
+use de\codenamephp\deploymentchecks\async\SuccessHandler\SuccessHandlerInterface;
+use de\codenamephp\deploymentchecks\base\Check\CheckInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\ResultInterface;
+
+/**
+ * Basically a wrapper around a check that implements the ParallelCheckInterface and WithErrorHandlerInterface. The spatie async pool expects a callable so this
+ * class implements that interface and just calls the check. The check itself is passed in the constructor and the success and error handler are optional.
+ *
+ * The default AsyncCheckCollection will use this check to run the checks in parallel. It will use the success and error handler as quasi callbacks to handle the result
+ * of the check.
+ *
+ * The default success handler will add the result to the result collection and the default error handler will rethrow the exception.
+ */
+final readonly class ParallelCheckWithErrorHandler implements ParallelCheckInterface, WithErrorHandlerInterface
+{
+
+ public function __construct(
+ public CheckInterface $check,
+ public SuccessHandlerInterface $successHandler = new AddToResultCollection(),
+ public ErrorHandlerInterface $errorHandler = new RethrowException(),
+ ) {}
+
+ public function __invoke(): ResultInterface
+ {
+ return $this->check->run();
+ }
+
+ public function successHandler(): SuccessHandlerInterface
+ {
+ return $this->successHandler;
+ }
+
+ public function errorHandler(): ErrorHandlerInterface
+ {
+ return $this->errorHandler;
+ }
+}
diff --git a/src/Check/WithErrorHandlerInterface.php b/src/Check/WithErrorHandlerInterface.php
new file mode 100644
index 0000000..653068d
--- /dev/null
+++ b/src/Check/WithErrorHandlerInterface.php
@@ -0,0 +1,29 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Check;
+
+use de\codenamephp\deploymentchecks\async\ErrorHandler\ErrorHandlerInterface;
+
+/**
+ * Interface for parallel checks that want to define a custom error handler
+ */
+interface WithErrorHandlerInterface
+{
+
+ public function errorHandler(): ErrorHandlerInterface;
+}
diff --git a/src/Collection/AsyncCheckCollection.php b/src/Collection/AsyncCheckCollection.php
new file mode 100644
index 0000000..9ad9b93
--- /dev/null
+++ b/src/Collection/AsyncCheckCollection.php
@@ -0,0 +1,61 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\Collection;
+
+use de\codenamephp\deploymentchecks\async\Check\Factory\FromCheck\FromCheckFactoryInterface;
+use de\codenamephp\deploymentchecks\async\Check\WithErrorHandlerInterface;
+use de\codenamephp\deploymentchecks\base\Check\CheckInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\Collection\ResultCollectionInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\ResultInterface;
+use Spatie\Async\Pool;
+use Throwable;
+
+/**
+ * @psalm-api
+ */
+final readonly class AsyncCheckCollection implements CheckInterface
+{
+
+ /**
+ * @var array
+ */
+ public array $checks;
+
+ public function __construct(
+ public Pool $pool,
+ public ResultCollectionInterface $resultCollection,
+ public FromCheckFactoryInterface $fromCheckFactory,
+ CheckInterface ...$checks)
+ {
+ $this->checks = $checks;
+ }
+
+ public function run(): ResultInterface
+ {
+ foreach ($this->checks as $check) {
+ $parallelCheck = $this->fromCheckFactory->build($check);
+ $runnable = $this->pool
+ ->add($parallelCheck)
+ ->then(fn(ResultInterface $output) => $parallelCheck->successHandler()->handle($this->resultCollection, $output));
+ if ($parallelCheck instanceof WithErrorHandlerInterface) $runnable->catch(fn(Throwable $exception): mixed => $parallelCheck->errorHandler()->handle($this->resultCollection, $exception));
+ }
+ $this->pool->wait();
+ return $this->resultCollection;
+ }
+}
diff --git a/src/ErrorHandler/ErrorHandlerInterface.php b/src/ErrorHandler/ErrorHandlerInterface.php
new file mode 100644
index 0000000..1fb6af0
--- /dev/null
+++ b/src/ErrorHandler/ErrorHandlerInterface.php
@@ -0,0 +1,30 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\ErrorHandler;
+
+use de\codenamephp\deploymentchecks\base\Check\Result\Collection\ResultCollectionInterface;
+use Throwable;
+
+/**
+ * Interface for a simple error handler. It expects the result collection build in the async collection and the exception that was thrown.
+ */
+interface ErrorHandlerInterface
+{
+
+ public function handle(ResultCollectionInterface $resultCollection, Throwable $exception): mixed;
+}
diff --git a/src/ErrorHandler/RethrowException.php b/src/ErrorHandler/RethrowException.php
new file mode 100644
index 0000000..8ea2ed7
--- /dev/null
+++ b/src/ErrorHandler/RethrowException.php
@@ -0,0 +1,34 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\ErrorHandler;
+
+use de\codenamephp\deploymentchecks\base\Check\Result\Collection\ResultCollectionInterface;
+use Throwable;
+
+/**
+ * Just rethrows the exception
+ */
+final class RethrowException implements ErrorHandlerInterface
+{
+
+ public function handle(ResultCollectionInterface $resultCollection, Throwable $exception): mixed
+ {
+ throw $exception;
+ }
+
+}
diff --git a/src/SuccessHandler/AddToResultCollection.php b/src/SuccessHandler/AddToResultCollection.php
new file mode 100644
index 0000000..abcb2b6
--- /dev/null
+++ b/src/SuccessHandler/AddToResultCollection.php
@@ -0,0 +1,34 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\SuccessHandler;
+
+use de\codenamephp\deploymentchecks\base\Check\Result\Collection\ResultCollectionInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\ResultInterface;
+
+/**
+ * Just adds the result to the collection
+ */
+final class AddToResultCollection implements SuccessHandlerInterface
+{
+
+ public function handle(ResultCollectionInterface $resultCollection, ResultInterface $result): ResultInterface
+ {
+ $resultCollection->add($result);
+ return $result;
+ }
+}
diff --git a/src/SuccessHandler/SuccessHandlerInterface.php b/src/SuccessHandler/SuccessHandlerInterface.php
new file mode 100644
index 0000000..c8a5b1d
--- /dev/null
+++ b/src/SuccessHandler/SuccessHandlerInterface.php
@@ -0,0 +1,30 @@
+.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace de\codenamephp\deploymentchecks\async\SuccessHandler;
+
+use de\codenamephp\deploymentchecks\base\Check\Result\Collection\ResultCollectionInterface;
+use de\codenamephp\deploymentchecks\base\Check\Result\ResultInterface;
+
+/**
+ * Interface for parallel checks that want to define a custom success handler
+ */
+interface SuccessHandlerInterface
+{
+
+ public function handle(ResultCollectionInterface $resultCollection, ResultInterface $result): ResultInterface;
+}