#!/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/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 $(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 format('D'); $this->body = ['weekday' => $weekday]; return $this; } } EOF ) # テストコード mkdir -p tests/Resource/App $(cat << 'EOF' > tests/Resource/App/WeekdayTest.php 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 src/Resource/App/Weekday.php format('D'); $this->body = ['weekday' => $weekday]; return $this; } } EOF ) # テストコード mkdir -p tests/Resource/App $(cat << 'EOF' > tests/Resource/App/WeekdayTest.php 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 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 route('/weekday', '/weekday/{year}/{month}/{day}'); EOF ) # ここまではOK php bin/app.php get /weekday/1981/09/08 # MyLoggerInterface $(cat << 'EOF' > src/MyLoggerInterface.php src/Resource/App/Weekday.php format('D'); $this->body = [ 'weekday' => $weekday ]; $this->logger->log("$year-$month-$day {$weekday}"); return $this; } } EOF ) # MyLogger実装 $(cat << 'EOF' > src/MyLogger.php 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 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