Skip to content

Instantly share code, notes, and snippets.

@yuki777
Last active September 17, 2021 06:51
Show Gist options
  • Select an option

  • Save yuki777/2f16f59f637a348bcd87da7ddfc47284 to your computer and use it in GitHub Desktop.

Select an option

Save yuki777/2f16f59f637a348bcd87da7ddfc47284 to your computer and use it in GitHub Desktop.

Revisions

  1. yuki777 revised this gist Sep 17, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/549ccc74ad0377b7e4e191f0b4abb3f97925a073/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/8f37b33ab0708c4325ab83df44b9d5dc6baac93e/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  2. yuki777 revised this gist Sep 17, 2021. 1 changed file with 4 additions and 106 deletions.
    110 changes: 4 additions & 106 deletions bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,117 +7,15 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9268620944113d73b27bc191a403035903593612/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/549ccc74ad0377b7e4e191f0b4abb3f97925a073/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
    cd /tmp/MyVendor.Weekday

    # composer.jsonを変更して https://github.com/koriym/BEAR.Package/tree/scan-binding-update を使う
    rm -rf composer.lock vendor
    $(cat << 'EOF' > composer.json
    {
    "name": "my-vendor/weekday",
    "type": "project",
    "license": "proprietary",
    "description": "",
    "repositories": [
    {
    "type": "vcs",
    "url": "https://github.com/koriym/BEAR.package"
    }
    ],
    "require": {
    "php": "^8.0.0",
    "ext-json": "*",
    "bear/aura-router-module": "^2.0",
    "bear/dotenv": "^1.0",
    "bear/package": "dev-scan-binding-update as 1.10",
    "bear/resource": "^1.15",
    "bear/sunday": "^1.5",
    "ray/aop": "^2.10",
    "ray/di": "^2.11"
    },
    "require-dev": {
    "bear/api-doc": "1.x-dev",
    "bear/devtools": "^0.1",
    "bamarni/composer-bin-plugin": "^1.4",
    "phpunit/phpunit": "^9.5",
    "roave/security-advisories": "dev-master"
    },
    "autoload": {
    "psr-4": {
    "MyVendor\\Weekday\\": "src/"
    }
    },
    "autoload-dev": {
    "psr-4": {
    "MyVendor\\Weekday\\": "tests/"
    }
    },
    "scripts": {
    "post-update-cmd": "@setup",
    "post-install-cmd": "@composer bin all install --ansi",
    "setup": "php bin/setup.php",
    "compile": "./vendor/bin/bear.compile 'MyVendor\\Weekday' prod-app ./",
    "doc": "./vendor/bin/apidoc",
    "test": "./vendor/bin/phpunit",
    "coverage": "php -dzend_extension=xdebug.so -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage",
    "pcov": "php -dextension=pcov.so -d pcov.enabled=1 ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage --coverage-clover=coverage.xml",
    "cs": "./vendor/bin/phpcs",
    "cs-fix": "./vendor/bin/phpcbf src tests",
    "metrics": "./vendor/bin/phpmetrics --report-html=build/metrics --exclude=Exception src",
    "clean": [
    "./vendor/bin/phpstan clear-result-cache",
    "./vendor/bin/psalm --clear-cache",
    "rm -rf ./var/tmp/*.php"
    ],
    "sa": [
    "./vendor/bin/phpstan analyse -c phpstan.neon",
    "psalm --show-info=true"
    ],
    "tests": [
    "@cs",
    "@sa",
    "@test"
    ],
    "build": [
    "@clean",
    "@cs",
    "@sa",
    "@pcov",
    "@compile",
    "@metrics"
    ],
    "serve": "php -dzend_extension=xdebug.so -S 127.0.0.1:8080 -t public",
    "app": "php bin/app.php",
    "page": "php bin/page.php"
    },
    "scripts-descriptions": {
    "setup": "Setup the project",
    "compile": "Compile scripts for the production",
    "doc": "Generate API document",
    "test": "Run unit tests",
    "tests": "Run tests and quality checks",
    "coverage": "Generate test coverage report",
    "pcov": "Generate test coverage report (pcov)",
    "cs": "Checks the coding standard",
    "cs-fix": "Fix the coding standard",
    "sa": "Run static analysis",
    "metrics": "Build metrics report",
    "clean": "Clear cache files",
    "serve": "Start built-in server",
    "app": "Request app resource",
    "page": "Request page resource"
    },
    "config": {
    "sort-packages": true,
    "process-timeout": 0
    }
    }
    EOF
    )
    composer install
    composer config repositories.koriym/BEAR.package vcs https://github.com/koriym/BEAR.package
    composer require "bear/package":"dev-scan-binding-update as 1.10.9" --update-with-all-dependencies

    # リソース
    mkdir -p src/Resource/App/
    @@ -382,4 +280,4 @@ php bin/app.php get /weekday/2011/05/23

    # test => OK
    # rm -fr var/tmp
    # php bin/app.php get /weekday/2011/05/23
    # php bin/app.php get /weekday/2011/05/23
  3. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/549ccc74ad0377b7e4e191f0b4abb3f97925a073/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9268620944113d73b27bc191a403035903593612/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  4. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -117,7 +117,7 @@ $(cat << 'EOF' > composer.json
    }
    EOF
    )

    composer install

    # リソース
    mkdir -p src/Resource/App/
  5. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/96f8a11cf00f2c8cf6f8affa686ddbaf344b4e2b/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/549ccc74ad0377b7e4e191f0b4abb3f97925a073/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  6. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@ set -eux
    cd /tmp/MyVendor.Weekday

    # composer.jsonを変更して https://github.com/koriym/BEAR.Package/tree/scan-binding-update を使う
    rm -f composer.lock vendor
    rm -rf composer.lock vendor
    $(cat << 'EOF' > composer.json
    {
    "name": "my-vendor/weekday",
  7. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9e57efe9e0dca7a9ab203b359ab2bc97beef6677/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/96f8a11cf00f2c8cf6f8affa686ddbaf344b4e2b/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  8. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9e57efe9e0dca7a9ab203b359ab2bc97beef6677/bear-sunday-tutorial1-php8-v2.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9e57efe9e0dca7a9ab203b359ab2bc97beef6677/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  9. yuki777 revised this gist Sep 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/df38a01423ba9b4b49fc8e590905f9fc5c3f56f4/bear-sunday-tutorial1-php8-v2.bash
    # https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/9e57efe9e0dca7a9ab203b359ab2bc97beef6677/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
  10. yuki777 revised this gist Sep 10, 2021. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,9 @@ set -eux
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/df38a01423ba9b4b49fc8e590905f9fc5c3f56f4/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # 移動する
    cd /tmp/MyVendor.Weekday

    # composer.jsonを変更して https://github.com/koriym/BEAR.Package/tree/scan-binding-update を使う
    rm -f composer.lock vendor
    $(cat << 'EOF' > composer.json
  11. yuki777 revised this gist Sep 10, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -7,8 +7,8 @@ set -eux
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/87026e08a85b7fdbb9d9745215a1f53c/raw/1fe9db02fe35cf8681aa03c65b9dda4123339903/bear-sunday-tutorial1-php8.bash
    # /bin/bash ./bear-sunday-tutorial1-php8.bash
    # wget https://gist.github.com/yuki777/2f16f59f637a348bcd87da7ddfc47284/raw/df38a01423ba9b4b49fc8e590905f9fc5c3f56f4/bear-sunday-tutorial1-php8-v2.bash
    # /bin/bash ./bear-sunday-tutorial1-php8-v2.bash

    # composer.jsonを変更して https://github.com/koriym/BEAR.Package/tree/scan-binding-update を使う
    rm -f composer.lock vendor
  12. yuki777 created this gist Sep 10, 2021.
    382 changes: 382 additions & 0 deletions bear-sunday-tutorial1-php8-v2.bash
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,382 @@
    #!/bin/bash

    set -eux

    ## Usage:
    # cd /tmp
    # composer create-project bear/skeleton MyVendor.Weekday
    # What is the vendor name ? MyVendor
    # What is the project name ? Weekday
    # wget https://gist.github.com/yuki777/87026e08a85b7fdbb9d9745215a1f53c/raw/1fe9db02fe35cf8681aa03c65b9dda4123339903/bear-sunday-tutorial1-php8.bash
    # /bin/bash ./bear-sunday-tutorial1-php8.bash

    # composer.jsonを変更して https://github.com/koriym/BEAR.Package/tree/scan-binding-update を使う
    rm -f composer.lock vendor
    $(cat << 'EOF' > composer.json
    {
    "name": "my-vendor/weekday",
    "type": "project",
    "license": "proprietary",
    "description": "",
    "repositories": [
    {
    "type": "vcs",
    "url": "https://github.com/koriym/BEAR.package"
    }
    ],
    "require": {
    "php": "^8.0.0",
    "ext-json": "*",
    "bear/aura-router-module": "^2.0",
    "bear/dotenv": "^1.0",
    "bear/package": "dev-scan-binding-update as 1.10",
    "bear/resource": "^1.15",
    "bear/sunday": "^1.5",
    "ray/aop": "^2.10",
    "ray/di": "^2.11"
    },
    "require-dev": {
    "bear/api-doc": "1.x-dev",
    "bear/devtools": "^0.1",
    "bamarni/composer-bin-plugin": "^1.4",
    "phpunit/phpunit": "^9.5",
    "roave/security-advisories": "dev-master"
    },
    "autoload": {
    "psr-4": {
    "MyVendor\\Weekday\\": "src/"
    }
    },
    "autoload-dev": {
    "psr-4": {
    "MyVendor\\Weekday\\": "tests/"
    }
    },
    "scripts": {
    "post-update-cmd": "@setup",
    "post-install-cmd": "@composer bin all install --ansi",
    "setup": "php bin/setup.php",
    "compile": "./vendor/bin/bear.compile 'MyVendor\\Weekday' prod-app ./",
    "doc": "./vendor/bin/apidoc",
    "test": "./vendor/bin/phpunit",
    "coverage": "php -dzend_extension=xdebug.so -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage",
    "pcov": "php -dextension=pcov.so -d pcov.enabled=1 ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage --coverage-clover=coverage.xml",
    "cs": "./vendor/bin/phpcs",
    "cs-fix": "./vendor/bin/phpcbf src tests",
    "metrics": "./vendor/bin/phpmetrics --report-html=build/metrics --exclude=Exception src",
    "clean": [
    "./vendor/bin/phpstan clear-result-cache",
    "./vendor/bin/psalm --clear-cache",
    "rm -rf ./var/tmp/*.php"
    ],
    "sa": [
    "./vendor/bin/phpstan analyse -c phpstan.neon",
    "psalm --show-info=true"
    ],
    "tests": [
    "@cs",
    "@sa",
    "@test"
    ],
    "build": [
    "@clean",
    "@cs",
    "@sa",
    "@pcov",
    "@compile",
    "@metrics"
    ],
    "serve": "php -dzend_extension=xdebug.so -S 127.0.0.1:8080 -t public",
    "app": "php bin/app.php",
    "page": "php bin/page.php"
    },
    "scripts-descriptions": {
    "setup": "Setup the project",
    "compile": "Compile scripts for the production",
    "doc": "Generate API document",
    "test": "Run unit tests",
    "tests": "Run tests and quality checks",
    "coverage": "Generate test coverage report",
    "pcov": "Generate test coverage report (pcov)",
    "cs": "Checks the coding standard",
    "cs-fix": "Fix the coding standard",
    "sa": "Run static analysis",
    "metrics": "Build metrics report",
    "clean": "Clear cache files",
    "serve": "Start built-in server",
    "app": "Request app resource",
    "page": "Request page resource"
    },
    "config": {
    "sort-packages": true,
    "process-timeout": 0
    }
    }
    EOF
    )


    # リソース
    mkdir -p src/Resource/App/
    $(cat << 'EOF' > src/Resource/App/Weekday.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Resource\App;
    use BEAR\Resource\ResourceObject;
    use DateTimeImmutable;
    class Weekday extends ResourceObject
    {
    public function onGet(int $year, int $month, int $day): static
    {
    $dateTime =DateTimeImmutable::createFromFormat('Y-m-d', "$year-$month-$day");
    $weekday = $dateTime->format('D');
    $this->body = ['weekday' => $weekday];
    return $this;
    }
    }
    EOF
    )


    # テストコード
    mkdir -p tests/Resource/App
    $(cat << 'EOF' > tests/Resource/App/WeekdayTest.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Resource\App;
    use BEAR\Resource\ResourceInterface;
    use MyVendor\Weekday\Injector;
    use PHPUnit\Framework\TestCase;
    class WeekdayTest extends TestCase
    {
    private ResourceInterface $resource;
    protected function setUp(): void
    {
    $injector = Injector::getInstance('app');
    $this->resource = $injector->getInstance(ResourceInterface::class);
    }
    public function testOnGet(): void
    {
    $ro = $this->resource->get('app://self/weekday', ['year' => '2001', 'month' => '1', 'day' => '1']);
    $this->assertSame(200, $ro->code);
    $this->assertSame('Mon', $ro->body['weekday']);
    }
    }
    EOF
    )


    # 例外作成
    mkdir -p src/Exception
    $(cat << 'EOF' > src/Exception/InvalidDateTime.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Exception;
    use RuntimeException;
    class InvalidDateTime extends RuntimeException
    {
    }
    EOF
    )


    # App/Weekday
    $(cat << 'EOF' > src/Resource/App/Weekday.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Resource\App;
    use BEAR\Resource\ResourceObject;
    use DateTimeImmutable;
    use MyVendor\Weekday\Exception\InvalidDateTime;
    class Weekday extends ResourceObject
    {
    public function onGet(int $year, int $month, int $day): static
    {
    $dateTime = DateTimeImmutable::createFromFormat('Y-m-d', "$year-$month-$day");
    if (! $dateTime instanceof DateTimeImmutable) {
    throw new InvalidDateTime("$year-$month-$day");
    }
    $weekday = $dateTime->format('D');
    $this->body = ['weekday' => $weekday];
    return $this;
    }
    }
    EOF
    )


    # テストコード
    mkdir -p tests/Resource/App
    $(cat << 'EOF' > tests/Resource/App/WeekdayTest.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Resource\App;
    use BEAR\Resource\ResourceInterface;
    use MyVendor\Weekday\Injector;
    use PHPUnit\Framework\TestCase;
    class WeekdayTest extends TestCase
    {
    private ResourceInterface $resource;
    protected function setUp(): void
    {
    $injector = Injector::getInstance('app');
    $this->resource = $injector->getInstance(ResourceInterface::class);
    }
    public function testOnGet(): void
    {
    $ro = $this->resource->get('app://self/weekday', ['year' => '2001', 'month' => '1', 'day' => '1']);
    $this->assertSame(200, $ro->code);
    $this->assertSame('Mon', $ro->body['weekday']);
    }
    public function tesInvalidDateTime(): void
    {
    $this->expectException(InvalidDateTime::class);
    $this->resource->get('app://self/weekday', ['year' => '-1', 'month' => '1', 'day' => '1']);
    }
    }
    EOF
    )


    # Install aura router
    composer require bear/aura-router-module:'^2.0'


    # App module
    $(cat << 'EOF' > src/Module/AppModule.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Module;
    use BEAR\Dotenv\Dotenv;
    use BEAR\Package\AbstractAppModule;
    use BEAR\Package\PackageModule;
    use BEAR\Package\Provide\Router\AuraRouterModule;
    use function dirname;
    class AppModule extends AbstractAppModule
    {
    protected function configure(): void
    {
    (new Dotenv())->load(dirname(__DIR__, 2));
    $appDir = $this->appMeta->appDir;
    $this->install(new AuraRouterModule($appDir . '/var/conf/aura.route.php'));
    $this->install(new PackageModule());
    }
    }
    EOF
    )


    # router file
    mkdir -p var/conf
    $(cat << 'EOF' > var/conf/aura.route.php
    <?php
    /**
    * @see http://bearsunday.github.io/manuals/1.0/ja/router.html
    * @var \Aura\Router\Map $map
    */
    $map->route('/weekday', '/weekday/{year}/{month}/{day}');
    EOF
    )


    # ここまではOK
    php bin/app.php get /weekday/1981/09/08


    # MyLoggerInterface
    $(cat << 'EOF' > src/MyLoggerInterface.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday;
    interface MyLoggerInterface
    {
    public function log(string $message): void;
    }
    EOF
    )


    # リソース
    mkdir -p src/Resource/App/
    $(cat << 'EOF' > src/Resource/App/Weekday.php
    <?php
    namespace MyVendor\Weekday\Resource\App;
    use BEAR\Resource\ResourceObject;
    use MyVendor\Weekday\MyLoggerInterface;
    class Weekday extends ResourceObject
    {
    public function __construct(public MyLoggerInterface $logger)
    {
    }
    public function onGet(int $year, int $month, int $day) : ResourceObject
    {
    $weekday = \DateTime::createFromFormat('Y-m-d', "$year-$month-$day")->format('D');
    $this->body = [
    'weekday' => $weekday
    ];
    $this->logger->log("$year-$month-$day {$weekday}");
    return $this;
    }
    }
    EOF
    )


    # MyLogger実装
    $(cat << 'EOF' > src/MyLogger.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday;
    use BEAR\AppMeta\AbstractAppMeta;
    use function error_log;
    use const PHP_EOL;
    class MyLogger implements MyLoggerInterface
    {
    private string $logFile;
    public function __construct(AbstractAppMeta $meta)
    {
    $this->logFile = $meta->logDir . '/weekday.log';
    }
    public function log(string $message): void
    {
    error_log($message . PHP_EOL, 3, $this->logFile);
    }
    }
    EOF
    )


    # App module
    $(cat << 'EOF' > src/Module/AppModule.php
    <?php
    declare(strict_types=1);
    namespace MyVendor\Weekday\Module;
    use BEAR\Dotenv\Dotenv;
    use BEAR\Package\AbstractAppModule;
    use BEAR\Package\PackageModule;
    use BEAR\Package\Provide\Router\AuraRouterModule;
    use MyVendor\Weekday\MyLogger;
    use MyVendor\Weekday\MyLoggerInterface;
    use function dirname;
    class AppModule extends AbstractAppModule
    {
    protected function configure(): void
    {
    (new Dotenv())->load(dirname(__DIR__, 2));
    $appDir = $this->appMeta->appDir;
    $this->install(new AuraRouterModule($appDir . '/var/conf/aura.route.php'));
    $this->bind(MyLoggerInterface::class)->to(MyLogger::class);
    $this->install(new PackageModule());
    }
    }
    EOF
    )


    # test => error
    php bin/app.php get /weekday/2011/05/23


    # test => OK
    # rm -fr var/tmp
    # php bin/app.php get /weekday/2011/05/23