From 890ddc320fc48345b7ff6018f471e5b5722a5ad5 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 15 Jun 2024 14:35:09 +0200 Subject: [PATCH 1/5] setup mkdocs --- .github/workflows/documentation.yml | 27 +++++ .gitignore | 1 + Makefile | 6 + docs/assets/favicon.png | Bin 0 -> 2319 bytes docs/assets/fonts/MonaspaceNeon-Regular.woff | Bin 0 -> 47308 bytes docs/assets/logo.svg | 24 ++++ docs/assets/stylesheets/extra.css | 113 +++++++++++++++++++ mkdocs.yml | 90 +++++++++++++++ 8 files changed, 261 insertions(+) create mode 100644 .github/workflows/documentation.yml create mode 100644 Makefile create mode 100644 docs/assets/favicon.png create mode 100644 docs/assets/fonts/MonaspaceNeon-Regular.woff create mode 100644 docs/assets/logo.svg create mode 100644 docs/assets/stylesheets/extra.css create mode 100644 mkdocs.yml diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..793fb64 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,27 @@ +name: Documentation +on: + push: + branches: [main] +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install mkdocs-material + - run: mkdocs gh-deploy --force diff --git a/.gitignore b/.gitignore index 987e2a2..a696500 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ composer.lock vendor +.cache diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6b5c6f1 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +# This command is intended to be run on your computer +serve-doc: + docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material + +build-doc: + docker run --rm -it -v ${PWD}:/docs squidfunk/mkdocs-material build diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..08dee3a38bab0f4b6161a9ea6c575a347daaa737 GIT binary patch literal 2319 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

m)-Jo-MAPW+|=Jl-g@ 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg new file mode 100644 index 0000000..6a5d322 --- /dev/null +++ b/docs/assets/logo.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css new file mode 100644 index 0000000..e4aa2d4 --- /dev/null +++ b/docs/assets/stylesheets/extra.css @@ -0,0 +1,113 @@ +@font-face { + font-family: "Monaspace Neon"; + font-weight: normal; + font-style: normal; + src: url("../fonts/MonaspaceNeon-Regular.woff"); +} + +:root { + --md-code-font: "Monaspace Neon"; +} + +:root { + --light-md-code-hl-number-color: #f76d47; + --light-md-code-hl-function-color: #6384b9; + --light-md-code-hl-operator-color: #39adb5; + --light-md-code-hl-constant-color: #7c4dff; + --light-md-code-hl-string-color: #9fc06f; + --light-md-code-hl-punctuation-color: #39adb5; + --light-md-code-hl-keyword-color: #7c4dff; + --light-md-code-hl-variable-color: #80cbc4; + --light-md-code-hl-comment-color: #ccd7da; + --light-md-code-bg-color: #fafafa; + --light-md-code-fg-color: #ffb62c; + --light-md-code-hl-variable-color: #6384b9; + --dark-md-code-hl-number-color: #f78c6c; + --dark-md-code-hl-function-color: #82aaff; + --dark-md-code-hl-operator-color: #89ddff; + --dark-md-code-hl-constant-color: #c792ea; + --dark-md-code-hl-string-color: #c3e88d; + --dark-md-code-hl-punctuation-color: #89ddff; + --dark-md-code-hl-keyword-color: #c792ea; + --dark-md-code-hl-variable-color: #e8f9f9; + --dark-md-code-hl-comment-color: #546e7a; + --dark-md-code-bg-color: #263238; + --dark-md-code-fg-color: #ffcb6b; + --dark-md-code-hl-variable-color: #82aaff; +} + +@media (prefers-color-scheme: light) { + .language-php > * { + --md-code-hl-number-color: var(--light-md-code-hl-number-color); + --md-code-hl-function-color: var(--light-md-code-hl-function-color); + --md-code-hl-operator-color: var(--light-md-code-hl-operator-color); + --md-code-hl-constant-color: var(--light-md-code-hl-constant-color); + --md-code-hl-string-color: var(--light-md-code-hl-string-color); + --md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color); + --md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color); + --md-code-hl-variable-color: var(--light-md-code-hl-variable-color); + --md-code-hl-comment-color: var(--light-md-code-hl-comment-color); + --md-code-bg-color: var(--light-md-code-bg-color); + --md-code-fg-color: var(--light-md-code-fg-color); + } + + .language-php .na { + --md-code-hl-variable-color: var(--light-md-code-hl-variable-color); + } +} + +[data-md-color-media="(prefers-color-scheme: light)"] .language-php > * { + --md-code-hl-number-color: var(--light-md-code-hl-number-color); + --md-code-hl-function-color: var(--light-md-code-hl-function-color); + --md-code-hl-operator-color: var(--light-md-code-hl-operator-color); + --md-code-hl-constant-color: var(--light-md-code-hl-constant-color); + --md-code-hl-string-color: var(--light-md-code-hl-string-color); + --md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color); + --md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color); + --md-code-hl-variable-color: var(--light-md-code-hl-variable-color); + --md-code-hl-comment-color: var(--light-md-code-hl-comment-color); + --md-code-bg-color: var(--light-md-code-bg-color); + --md-code-fg-color: var(--light-md-code-fg-color); +} + +[data-md-color-media="(prefers-color-scheme: light)"] .language-php .na { + --md-code-hl-variable-color: var(--light-md-code-hl-variable-color); +} + +@media (prefers-color-scheme: dark) { + .language-php > * { + --md-code-hl-number-color: var(--dark-md-code-hl-number-color); + --md-code-hl-function-color: var(--dark-md-code-hl-function-color); + --md-code-hl-operator-color: var(--dark-md-code-hl-operator-color); + --md-code-hl-constant-color: var(--dark-md-code-hl-constant-color); + --md-code-hl-string-color: var(--dark-md-code-hl-string-color); + --md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color); + --md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color); + --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color); + --md-code-hl-comment-color: var(--dark-md-code-hl-comment-color); + --md-code-bg-color: var(--dark-md-code-bg-color); + --md-code-fg-color: var(--dark-md-code-fg-color); + } + + .language-php .na { + --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color); + } +} + +[data-md-color-media="(prefers-color-scheme: dark)"] .language-php > * { + --md-code-hl-number-color: var(--dark-md-code-hl-number-color); + --md-code-hl-function-color: var(--dark-md-code-hl-function-color); + --md-code-hl-operator-color: var(--dark-md-code-hl-operator-color); + --md-code-hl-constant-color: var(--dark-md-code-hl-constant-color); + --md-code-hl-string-color: var(--dark-md-code-hl-string-color); + --md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color); + --md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color); + --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color); + --md-code-hl-comment-color: var(--dark-md-code-hl-comment-color); + --md-code-bg-color: var(--dark-md-code-bg-color); + --md-code-fg-color: var(--dark-md-code-fg-color); +} + +[data-md-color-media="(prefers-color-scheme: dark)"] .language-php .na { + --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color); +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..f7d1dfa --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,90 @@ +site_name: Innmind/Framework +repo_name: Innmind/Framework + +nav: + - Getting Started: README.md + +theme: + name: material + logo: assets/logo.svg + favicon: assets/favicon.png + font: false + features: + - content.code.copy + - content.code.annotate + - navigation.tracking + - navigation.tabs + - navigation.tabs.sticky + - navigation.sections + - navigation.expand + - navigation.indexes + - navigation.top + - navigation.footer + - search.suggest + - search.highlight + - content.action.edit + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + primary: blue + accent: deep orange + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + primary: blue + accent: deep orange + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + primary: blue + accent: deep orange + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + extend_pygments_lang: + - name: php + lang: php + options: + startinline: true + - pymdownx.inlinehilite + - pymdownx.snippets + - attr_list + - md_in_html + - pymdownx.superfences + - abbr + - admonition + - pymdownx.details: + - pymdownx.tabbed: + alternate_style: true + - toc: + permalink: true + - footnotes + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + +extra_css: + - assets/stylesheets/extra.css + +plugins: + - search + - privacy + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/Innmind/immutable + - icon: fontawesome/brands/x-twitter + link: https://twitter.com/Baptouuuu From 6d81a6f00a2ba98f357cd37a62e99ca32bdb0fae Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 15 Jun 2024 14:35:56 +0200 Subject: [PATCH 2/5] rename readme to index --- docs/{README.md => index.md} | 0 mkdocs.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{README.md => index.md} (100%) diff --git a/docs/README.md b/docs/index.md similarity index 100% rename from docs/README.md rename to docs/index.md diff --git a/mkdocs.yml b/mkdocs.yml index f7d1dfa..c5e8362 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: Innmind/Framework repo_name: Innmind/Framework nav: - - Getting Started: README.md + - Getting Started: index.md theme: name: material From d0ac42e8ac909bdfdeb9b18ff3271297013dafb1 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 15 Jun 2024 14:37:07 +0200 Subject: [PATCH 3/5] add navigation --- mkdocs.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index c5e8362..a8dbb2b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,17 @@ repo_name: Innmind/Framework nav: - Getting Started: index.md + - Use cases: + - Build an HTTP app: http.md + - Build a CLI app: cli.md + - Services: services.md + - Middlewares: middlewares.md + - Build an app that runs through HTTP and CLI: http-and-cli.md + - Testing: testing.md + - Add variables to the environment: environment.md + - Decorate the operating system: operating-system.md + - Experimental features: + - Using an async http server: experimental/async-server.md theme: name: material From b50de2d311ac57547669b38053ce2751d39a715a Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 15 Jun 2024 14:54:15 +0200 Subject: [PATCH 4/5] styling --- docs/cli.md | 18 ++++++--- docs/environment.md | 10 +++-- docs/experimental/async-server.md | 12 +++--- docs/http-and-cli.md | 11 ++++-- docs/http.md | 63 ++++++++++++++++++++----------- docs/index.md | 21 ++++------- docs/middlewares.md | 14 ++++--- docs/services.md | 21 +++++++---- docs/testing.md | 4 +- 9 files changed, 107 insertions(+), 67 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index fcf02b0..40f61bf 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -2,7 +2,7 @@ The first of any CLI app is to create an `entrypoint.php` that you'll call with the `php` command. -```php +```php title="entrypoint.php" with(Publish::one($message)->to('some-exchange')) ->run($console) ->match( - static fn($console) => $console->output(Str::of("Message published\n")), - static fn() => $console->error(Str::of("Something went wrong\n")), + static fn($console) => $console->output( + Str::of("Message published\n"), + ), + static fn() => $console->error( + Str::of("Something went wrong\n"), + ), ); } @@ -91,8 +95,12 @@ new class extends Cli { ->with(Get::of('some-queue')) ->run($console) ->match( - static fn($console) => $console->output(Str::of("One message pulled from queue\n")), - static fn() => $console->error(Str::of("Something went wrong\n")), + static fn($console) => $console->output( + Str::of("One message pulled from queue\n"), + ), + static fn() => $console->error( + Str::of("Something went wrong\n"), + ), ); } diff --git a/docs/environment.md b/docs/environment.md index 7a322d2..53058fa 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -13,10 +13,12 @@ use Innmind\Framework\{ new class extends Http|Cli { protected function configure(Application $app): Application { - return $app->mapEnvironment(static fn(Environment $env) => $env->with( - 'MY_VARIABLE_NAME', - "and it's value", - )); + return $app->mapEnvironment( + static fn(Environment $env) => $env->with( + 'MY_VARIABLE_NAME', + "and it's value", + ), + ); } }; ``` diff --git a/docs/experimental/async-server.md b/docs/experimental/async-server.md index 65e690b..5258470 100644 --- a/docs/experimental/async-server.md +++ b/docs/experimental/async-server.md @@ -2,8 +2,8 @@ The framework comes with an HTTP server entirely built in PHP allowing you to serve your app without extra dependencies in ther earlist stages of your project. -> [!NOTE] -> This feature is optional, to use it you must before run `composer require innmind/async-http-server`. +!!! note "" + This feature is optional, to use it you must before run `composer require innmind/async-http-server`. To use it is similar to the standard [http](../http.md) handler, the first difference is the namespace of the main entrypoint: @@ -30,8 +30,8 @@ Note the namespace is `Main\Async\Http` instead of `Main\Http`. The other differ All the configuration of the `Application` object is identical to the other contexts. -> [!NOTE] ->The server currently does have limitations, streamed requests (via `Transfer-Encoding`) are not supported and multipart requests are not parsed. +!!! note "" + The server currently does have limitations, streamed requests (via `Transfer-Encoding`) are not supported and multipart requests are not parsed. -> [!WARNING] -> This server was built to showcase in a conference talk the ability to switch between synchronous code and asynchronous code without changing the app code. Do **NOT** use this server in production. +!!! warning "" + This server was built to showcase in a conference talk the ability to switch between synchronous code and asynchronous code without changing the app code. Do **NOT** use this server in production. diff --git a/docs/http-and-cli.md b/docs/http-and-cli.md index 091efa0..eb2c17b 100644 --- a/docs/http-and-cli.md +++ b/docs/http-and-cli.md @@ -23,10 +23,12 @@ final class Kernel implements Middleware return $app ->service( 'images', - static fn($_, OperatingSystem $os) => $os->filesystem()->mount(Path::of('somewhere/on/the/filesystem/')), + static fn($_, OperatingSystem $os) => $os + ->filesystem() + ->mount(Path::of('somewhere/on/the/filesystem/')), ) ->service('amqp', /* see services topic */) - ->service('upload', static fn(Container $container) => new UploadHandler( // imaginary class + ->service('upload', static fn(Container $container) => new UploadHandler( //(1) $container('images'), $container('amqp'), )) @@ -35,7 +37,7 @@ final class Kernel implements Middleware Route::literal('POST /upload')->handle(Service::of($container, 'upload')), ), ) - ->command(static fn(Container $container) => new ThumbnailWorker( // imaginary class + ->command(static fn(Container $container) => new ThumbnailWorker( //(2) $container('images'), $container('amqp'), )); @@ -43,6 +45,9 @@ final class Kernel implements Middleware } ``` +1. imaginary class +2. imaginary class + Then you can use this middleware like this: ```php diff --git a/docs/http.md b/docs/http.md index e65878a..cfa86ed 100644 --- a/docs/http.md +++ b/docs/http.md @@ -80,7 +80,10 @@ new class extends Http { ), )) ->add(Route::literal('GET /{name}')->handle( - static fn(ServerRequest $request, Variables $variables) => Response::of( + static fn( + ServerRequest $request, + Variables $variables, + ) => Response::of( StatusCode::ok, $request->protocolVersion(), null, @@ -163,18 +166,27 @@ new class extends Http { protected function configure(Application $app): Application { return $app - ->route('GET /', static fn(ServerRequest $request) => Response::of( - StatusCode::ok, - $request->protocolVersion(), - null, - Content::ofString('Hello world!'), - )) - ->route('GET /{name}', static fn(ServerRequest $request, Variables $variables) => Response::of( - StatusCode::ok, - $request->protocolVersion(), - null, - Content::ofString("Hello {$variables->get('name')}!"), - )); + ->route( + 'GET /', + static fn(ServerRequest $request) => Response::of( + StatusCode::ok, + $request->protocolVersion(), + null, + Content::ofString('Hello world!'), + ), + ) + ->route( + 'GET /{name}', + static fn( + ServerRequest $request, + Variables $variables, + ) => Response::of( + StatusCode::ok, + $request->protocolVersion(), + null, + Content::ofString("Hello {$variables->get('name')}!"), + ), + ); } }; ``` @@ -224,8 +236,10 @@ new class extends Http { ->service( 'hello-name', static fn() => new class { - public function __invoke(ServerRequest $request, Variables $variables): Response - { + public function __invoke( + ServerRequest $request, + Variables $variables, + ): Response { return Response::of( StatusCode::ok, $request->protocolVersion(), @@ -236,8 +250,11 @@ new class extends Http { } ) ->appendRoutes( - static fn(Routes $routes, Container $container) => $routes - ->add(Route::literal('GET /')->handle(Service::of($container, 'hello-word'))), + static fn(Routes $routes, Container $container) => $routes->add( + Route::literal('GET /')->handle( + Service::of($container, 'hello-word'), + ), + ), ) ->route('GET /{name}', To::service('hello-name')); } @@ -246,8 +263,8 @@ new class extends Http { Here the services are invokable anonymous classes to conform to the callable expected for a `Route` but you can create dedicated classes for each one. -> [!NOTE] -> Head to the [services topic](services.md) for a more in-depth look of what's possible. +!!! note "" + Head to the [services topic](services.md) for a more in-depth look of what's possible. ## Executing code on any route @@ -303,8 +320,8 @@ This example will refuse any request that doesn't have an `Authorization` header You can have multiple calls to `mapRequestHandler` to compose behaviours like an onion. -> [!NOTE] -> the default request handler is the inner router of the framework, this means that you can completely change the default behaviour of the framework by returning a new request handler that never uses the default one. +!!! note "" + The default request handler is the inner router of the framework, this means that you can completely change the default behaviour of the framework by returning a new request handler that never uses the default one. ## Handling unknown routes @@ -330,9 +347,11 @@ new class extends Http { StatusCode::notFound, $request->protocolVersion(), null, - Content::ofString('Page Not Found!'), // or return something more elaborated such as html + Content::ofString('Page Not Found!'), //(1) ), ); } }; ``` + +1. or return something more elaborated such as html diff --git a/docs/index.md b/docs/index.md index c2fa23d..eb4f8e4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,18 +1,11 @@ +--- +hide: + - navigation + - toc +--- + # Framework The philosophy behind this framework is to have a minimalist foundation to be able to build simple apps but can also accomodate for more complex applications through composition (of the configuration, commands, request handlers and more). -Another important design is to expose to you the input to handle and an abstraction of the operating system it runs on so you only need to focus on WHAT your app needs to do and NOT HOW. - -These topics will guide you through the simplest cases to more complex ones: -- [Build an HTTP app](http.md) -- [Build a CLI app](cli.md) -- [Services](services.md) -- [Middlewares](middlewares.md) -- [Build an app that runs through HTTP and CLI](http-and-cli.md) -- [Testing](testing.md) -- [Add variables to the environment](environment.md) -- [Decorate the operating system](operating-system.md) - -Experimental features: -- [Using an async http server](experimental/async-server.md) +Another important design is to expose to you the input to handle and an abstraction of the operating system it runs on so you only need to focus on _what_ your app needs to do and _not how_. diff --git a/docs/middlewares.md b/docs/middlewares.md index 3f3ed92..b88417e 100644 --- a/docs/middlewares.md +++ b/docs/middlewares.md @@ -2,8 +2,8 @@ Middlewares are a way to regroup all the configuration you've seen in other topics under a name. This means that you can either group part of your own application undeer a middleware or expose a package for other to use via Packagist. -> [!NOTE] -> you can search for [`innmind/framework-middlewares` on Packagist](https://packagist.org/providers/innmind/framework-middlewares) for middlewares published by others. +!!! note "" + You can search for [`innmind/framework-middlewares` on Packagist](https://packagist.org/providers/innmind/framework-middlewares) for middlewares published by others. Let's say you have an application that sends emails you could have a middleware that looks like this: @@ -31,16 +31,18 @@ final class Emails implements Middleware return $app ->service( 'email-server' - static fn($_, $__, Environment $env) => Url::of($env->get('EMAIL_SERVER')) + static fn($_, $__, Environment $env) => Url::of( + $env->get('EMAIL_SERVER'), + ), ), ->service( $this->service, - static fn(Container $container) => new EmailClient( // imaginary class + static fn(Container $container) => new EmailClient( //(1) $container('email-server'), ), ) ->command( - static fn(Container $container) => new class($container($this->service)) implements Command { + fn(Container $container) => new class($container($this->service)) implements Command { public function __construct( private EmailClient $client, ) { @@ -63,6 +65,8 @@ final class Emails implements Middleware } ``` +1. imaginary class + And you would use it like this: ```php diff --git a/docs/services.md b/docs/services.md index 5332718..d5be1a5 100644 --- a/docs/services.md +++ b/docs/services.md @@ -47,8 +47,8 @@ enum Services implements Service } ``` -> [!TIP] -> If you publish a package you can add an `@internal` flag on the static methods to tell your users to not use the service. And when you plan to remove a service you can use the `@deprecated` flag. +!!! tip "" + If you publish a package you can add an `@internal` flag on the static methods to tell your users to not use the service. And when you plan to remove a service you can use the `@deprecated` flag. ```php use Innmind\Framework\{ @@ -79,8 +79,8 @@ new class extends Http|Cli { This example defines a single service named `amqpClient` that relies on the `OperatingSystem` in order to work. -> [!NOTE] -> this example uses [`innmind/amqp`](https://github.com/innmind/amqp) +!!! note "" + This example uses [`innmind/amqp`](https://github.com/innmind/amqp). ## Configure via environment variables @@ -104,10 +104,14 @@ new class extends Http|Cli { { return $app->service( Services::amqpClient, - static fn($_, OperatingSystem $os, Environment $env) => Factory::of($os)->make( + static fn( + $_, + OperatingSystem $os, + Environment $env + ) => Factory::of($os)->make( Transport::tcp(), - Url::of($env->get('AMQP_URL')), // this will throw if the variable is not defined - ElapsedPeriod::of($env->maybe('AMQP_TIMEOUT')->match( // in case the variable is not defined it will fallback to a 1000ms timeout + Url::of($env->get('AMQP_URL')), //(1) + ElapsedPeriod::of($env->maybe('AMQP_TIMEOUT')->match( //(2) static fn($timeout) => (int) $timeout, static fn() => 1000, )), @@ -117,6 +121,9 @@ new class extends Http|Cli { }; ``` +1. this will throw if the variable is not defined +2. in case the variable is not defined it will fallback to a `1000ms` timeout + ## Services relying on services If we continue with our AMQP example, in an application that both produces and consumes messages (with high throughput) we'll want 2 different clients. One basic client (like previous examples) for producing messages and one client where we configure the number of messages to prefetch. diff --git a/docs/testing.md b/docs/testing.md index ec57dee..c6d27d1 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -61,7 +61,9 @@ final class AppTest extends TestCase ['AMQP_URL', 'amqp://guest:guest@localhost:5672/'], ]; $os = Factory::build(); // or use mocks - $app = Application::cli($os, Environment::test($variables))->map(new Kernel); + $app = Application::cli($os, Environment::test($variables))->map( + new Kernel, + ); $environment = $app->run(InMemory::of( [], // input chunks From 0ff19cc1d467e0110e6991bf70c6e67b542cd7ce Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 15 Jun 2024 14:54:56 +0200 Subject: [PATCH 5/5] use absolute link --- docs/environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/environment.md b/docs/environment.md index 53058fa..03b1a25 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -1,6 +1,6 @@ # Add variables to the environment -The framework exposes an [`Environment`](../src/Environment.php) object with values coming from `\getenv()`. If you want to add variables and make them available to the rest of your application you can do it like this: +The framework exposes an [`Environment`](https://github.com/Innmind/framework/blob/develop/src/Environment.php) object with values coming from `\getenv()`. If you want to add variables and make them available to the rest of your application you can do it like this: ```php use Innmind\Framework\{