knuckleswtf / scribe

Generate API documentation for humans from your Laravel codebase.✍
https://scribe.knuckles.wtf/laravel/
MIT License
1.58k stars 280 forks source link

PhpParser\Lexer\Emulative::__construct(): Argument #1 ($phpVersion) must be of type ?PhpParser\PhpVersion, array given #811

Closed ArtyomDikarevWeb closed 4 months ago

ArtyomDikarevWeb commented 4 months ago

Scribe version

4.30

Your question

Well, I don't even know how to start there are two different errors, that depends on are there route in api.php or not.

First, if there aren't routes in api.php, i got this:

bdfccbe92020:/var/www/timetracker$ php artisan scribe:generate --verbose
ⓘ Extracting intro and auth Markdown files to: .scribe
✔ Extracted intro and auth Markdown files to: .scribe
ⓘ Writing HTML docs...
✔ Wrote HTML docs and assets to: public/docs/
ⓘ Generating Postman collection
✔ Wrote Postman collection to: public/docs/collection.json
ⓘ Generating OpenAPI specification
✔ Wrote OpenAPI specification to: public/docs/openapi.yaml
Checking for any pending upgrades to your config file...
Check failed with error:

   TypeError 

  PhpParser\Lexer\Emulative::__construct(): Argument #1 ($phpVersion) must be of type ?PhpParser\PhpVersion, array given, called in /var/www/timetracker/vendor/shalvah/upgrader/src/ReadsAndWritesAsts.php on line 38

  at vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php:38
     34▕ 
     35▕     /**
     36▕      * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported.
     37▕      */
  ➜  38▕     public function __construct(?PhpVersion $phpVersion = null) {
     39▕         $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
     40▕         $this->hostPhpVersion = PhpVersion::getHostVersion();
     41▕ 
     42▕         $emulators = [

  1   vendor/shalvah/upgrader/src/ReadsAndWritesAsts.php:38
      PhpParser\Lexer\Emulative::__construct([])

  2   vendor/shalvah/upgrader/src/Upgrader.php:234
      Shalvah\Upgrader\Upgrader::parseFilePreservingFormat("config/scribe.php")

  3   vendor/shalvah/upgrader/src/Upgrader.php:222
      Shalvah\Upgrader\Upgrader::getUserOldConfigFileAsAst()

  4   vendor/shalvah/upgrader/src/Upgrader.php:77
      Shalvah\Upgrader\Upgrader::parseConfigFiles()

  5   vendor/shalvah/upgrader/src/Upgrader.php:61
      Shalvah\Upgrader\Upgrader::fetchChanges()

  6   vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php:183
      Shalvah\Upgrader\Upgrader::dryRun()

  7   vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php:69
      Knuckles\Scribe\Commands\GenerateDocumentation::upgradeConfigFileIfNeeded()

  8   vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
      Knuckles\Scribe\Commands\GenerateDocumentation::handle(Object(Knuckles\Scribe\Matching\RouteMatcher), Object(Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory))

  9   vendor/laravel/framework/src/Illuminate/Container/Util.php:41
      Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()

  10  vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
      Illuminate\Container\Util::unwrapIfClosure(Object(Closure))

  11  vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:35
      Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))

  12  vendor/laravel/framework/src/Illuminate/Container/Container.php:662
      Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])

  13  vendor/laravel/framework/src/Illuminate/Console/Command.php:211
      Illuminate\Container\Container::call()

  14  vendor/symfony/console/Command/Command.php:326
      Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))

  15  vendor/laravel/framework/src/Illuminate/Console/Command.php:180
      Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))

  16  vendor/symfony/console/Application.php:1096
      Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  17  vendor/symfony/console/Application.php:324
      Symfony\Component\Console\Application::doRunCommand(Object(Knuckles\Scribe\Commands\GenerateDocumentation), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  18  vendor/symfony/console/Application.php:175
      Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  19  vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:201
      Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  20  artisan:35
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

This did not affect your docs. Please report this issue in the project repo: https://github.com/knuckleswtf/scribe

If there are routes in file api.php, I get this:

bdfccbe92020:/var/www/timetracker$ php artisan scribe:generate --verbose
ⓘ Processing route: [GET] api/v1/projects

   Error 

  Call to undefined method PhpParser\ParserFactory::create()

  at vendor/knuckleswtf/scribe/src/Extracting/MethodAstParser.php:46
     42▕      * @return \PhpParser\Node\Stmt[]|null
     43▕      */
     44▕     protected static function parseClassSourceCode(string $sourceCode): ?array
     45▕     {
  ➜  46▕         $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
     47▕         try {
     48▕             $ast = $parser->parse($sourceCode);
     49▕         } catch (Throwable $error) {
     50▕             throw new Exception("Parse error: {$error->getMessage()}");

  1   vendor/knuckleswtf/scribe/src/Extracting/MethodAstParser.php:93
      Knuckles\Scribe\Extracting\MethodAstParser::parseClassSourceCode("<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreProjectRequest;
use App\Http\Resources\ProjectResource;
use App\Http\Services\ProjectService;
use App\Models\Project;
use Illuminate\Http\Resources\Json\JsonResource;

class ProjectController extends Controller
{
    public function index(): JsonResource
    {
        $projects = Project::with(['tasks'])->paginate(10);

        return ProjectResource::collection($projects);
    }

    public function store(StoreProjectRequest $request, ProjectService $service): JsonResource
    {
        $project = $service->store($request->dto());

        return ProjectResource::make($project);
    }
}
")

  2   vendor/knuckleswtf/scribe/src/Extracting/MethodAstParser.php:32
      Knuckles\Scribe\Extracting\MethodAstParser::getClassAst("/var/www/timetracker/app/Http/Controllers/Api/ProjectController.php")

  3   vendor/knuckleswtf/scribe/src/Extracting/Strategies/GetFromInlineValidatorBase.php:24
      Knuckles\Scribe\Extracting\MethodAstParser::getMethodAst(Object(ReflectionMethod))

  4   vendor/knuckleswtf/scribe/src/Extracting/Extractor.php:236
      Knuckles\Scribe\Extracting\Strategies\GetFromInlineValidatorBase::__invoke(Object(Knuckles\Camel\Extraction\ExtractedEndpointData), [])

  5   vendor/knuckleswtf/scribe/src/Extracting/Extractor.php:139
      Knuckles\Scribe\Extracting\Extractor::iterateThroughStrategies("queryParameters", Object(Knuckles\Camel\Extraction\ExtractedEndpointData), [], Object(Closure))

  6   vendor/knuckleswtf/scribe/src/Extracting/Extractor.php:70
      Knuckles\Scribe\Extracting\Extractor::fetchQueryParameters(Object(Knuckles\Camel\Extraction\ExtractedEndpointData), [])

  7   vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php:125
      Knuckles\Scribe\Extracting\Extractor::processRoute(Object(Illuminate\Routing\Route), [])

  8   vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php:72
      Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFromApp::extractEndpointsInfoFromLaravelApp([], [])

  9   vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php:50
      Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFromApp::extractEndpointsInfoAndWriteToDisk(Object(Knuckles\Scribe\Matching\RouteMatcher))

  10  vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php:53
      Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFromApp::get()

  11  vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
      Knuckles\Scribe\Commands\GenerateDocumentation::handle(Object(Knuckles\Scribe\Matching\RouteMatcher), Object(Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory))

  12  vendor/laravel/framework/src/Illuminate/Container/Util.php:41
      Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()

  13  vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
      Illuminate\Container\Util::unwrapIfClosure(Object(Closure))

  14  vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:35
      Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))

  15  vendor/laravel/framework/src/Illuminate/Container/Container.php:662
      Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])

  16  vendor/laravel/framework/src/Illuminate/Console/Command.php:211
      Illuminate\Container\Container::call()

  17  vendor/symfony/console/Command/Command.php:326
      Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))

  18  vendor/laravel/framework/src/Illuminate/Console/Command.php:180
      Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))

  19  vendor/symfony/console/Application.php:1096
      Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  20  vendor/symfony/console/Application.php:324
      Symfony\Component\Console\Application::doRunCommand(Object(Knuckles\Scribe\Commands\GenerateDocumentation), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  21  vendor/symfony/console/Application.php:175
      Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  22  vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:201
      Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

  23  artisan:35
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

I've read another issues so i tried to create a model from factory and it works correct

$project = Project::factory()->create();

dd($project);

/* App\Models\Project {
 *    attributes: [
 *         "name" => "Some Name"
 *         "updated_at" => "2024-02-20 13:53:18"
 *         "created_at" => "2024-02-20 13:53:18"
 *         "id" => 13
 *    ]
 * }
* /

There is my scribe config

<?php

use Knuckles\Scribe\Extracting\Strategies;

return [
    // The HTML <title> for the generated documentation. If this is empty, Scribe will infer it from config('app.name').
    'title' => null,

    // A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec.
    'description' => '',

    // The base URL displayed in the docs. If this is empty, Scribe will use the value of config('app.url') at generation time.
    // If you're using `laravel` type, you can set this to a dynamic string, like '{{ config("app.tenant_url") }}' to get a dynamic base URL.
    'base_url' => 'null',

    'routes' => [
        [
            // Routes that match these conditions will be included in the docs
            'match' => [
                // Match only routes whose paths match this pattern (use * as a wildcard to match any characters). Example: 'users/*'.
                'prefixes' => ['api/*'],

                // Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'.
                'domains' => ['*'],

                // [Dingo router only] Match only routes registered under this version. Wildcards are NOT supported.
                'versions' => ['v1'],
            ],

            // Include these routes even if they did not match the rules above.
            'include' => [
                // 'users.index', 'POST /new', '/auth/*'
            ],

            // Exclude these routes even if they matched the rules above.
            'exclude' => [
                // 'GET /health', 'admin.*'
            ],

            'apply' => [
                /*
                 * Additional headers to be added to the example requests
                 */
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Accept' => 'application/json',
                ],

                /*
                 * If no @response or @transformer declarations are found for the route,
                 * Scribe will try to get a sample response by attempting an API call.
                 * Configure the settings for the API call here.
                 */
                'response_calls' => [
                    /*
                     * API calls will be made only for routes in this group matching these HTTP methods (GET, POST, etc).
                     * List the methods here or use '*' to mean all methods. Leave empty to disable API calls.
                     */
                    'methods' => ['GET'],

                    /*
                     * Laravel config variables which should be set for the API call.
                     * This is a good place to ensure that notifications, emails and other external services
                     * are not triggered during the documentation API calls.
                     * You can also create a `.env.docs` file and run the generate command with `--env docs`.
                     */
                    'config' => [
                        'app.env' => 'documentation',
                        // 'app.debug' => false,
                    ],

                    /*
                     * Query parameters which should be sent with the API call.
                     */
                    'queryParams' => [
                        // 'key' => 'value',
                    ],

                    /*
                     * Body parameters which should be sent with the API call.
                     */
                    'bodyParams' => [
                        // 'key' => 'value',
                    ],

                    /*
                     * Files which should be sent with the API call.
                     * Each value should be a valid path (absolute or relative to your project directory) to a file on this machine (but not in the project root).
                     */
                    'fileParams' => [
                        // 'key' => 'storage/app/image.png',
                    ],

                    /*
                     * Cookies which should be sent with the API call.
                     */
                    'cookies' => [
                        // 'name' => 'value'
                    ],
                ],
            ],
        ],
    ],

    // The type of documentation output to generate.
    // - "static" will generate a static HTMl page in the /public/docs folder,
    // - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication.
    // - "external_static" and "external_laravel" do the same as above, but generate a basic template,
    // passing the OpenAPI spec as a URL, allowing you to easily use the docs with an external generator
    'type' => 'static',

    // See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options
    'theme' => 'default',

    'static' => [
        // HTML documentation, assets and Postman collection will be generated to this folder.
        // Source Markdown will still be in resources/docs.
        'output_path' => 'public/docs',
    ],

    'laravel' => [
        // Whether to automatically create a docs endpoint for you to view your generated docs.
        // If this is false, you can still set up routing manually.
        'add_routes' => true,

        // URL path to use for the docs endpoint (if `add_routes` is true).
        // By default, `/docs` opens the HTML page, `/docs.postman` opens the Postman collection, and `/docs.openapi` the OpenAPI spec.
        'docs_url' => '/docs',

        // Directory within `public` in which to store CSS and JS assets.
        // By default, assets are stored in `public/vendor/scribe`.
        // If set, assets will be stored in `public/{{assets_directory}}`
        'assets_directory' => null,

        // Middleware to attach to the docs endpoint (if `add_routes` is true).
        'middleware' => [],
    ],

    'external' => [
        'html_attributes' => []
    ],

    'try_it_out' => [
        // Add a Try It Out button to your endpoints so consumers can test endpoints right from their browser.
        // Don't forget to enable CORS headers for your endpoints.
        'enabled' => true,

        // The base URL for the API tester to use (for example, you can set this to your staging URL).
        // Leave as null to use the current app URL when generating (config("app.url")).
        'base_url' => null,

        // [Laravel Sanctum] Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header.
        'use_csrf' => false,

        // The URL to fetch the CSRF token from (if `use_csrf` is true).
        'csrf_url' => '/sanctum/csrf-cookie',
    ],

    // How is your API authenticated? This information will be used in the displayed docs, generated examples and response calls.
    'auth' => [
        // Set this to true if ANY endpoints in your API use authentication.
        'enabled' => false,

        // Set this to true if your API should be authenticated by default. If so, you must also set `enabled` (above) to true.
        // You can then use @unauthenticated or @authenticated on individual endpoints to change their status from the default.
        'default' => false,

        // Where is the auth value meant to be sent in a request?
        // Options: query, body, basic, bearer, header (for custom header)
        'in' => 'bearer',

        // The name of the auth parameter (eg token, key, apiKey) or header (eg Authorization, Api-Key).
        'name' => 'key',

        // The value of the parameter to be used by Scribe to authenticate response calls.
        // This will NOT be included in the generated documentation. If empty, Scribe will use a random value.
        'use_value' => env('SCRIBE_AUTH_KEY'),

        // Placeholder your users will see for the auth parameter in the example requests.
        // Set this to null if you want Scribe to use a random value as placeholder instead.
        'placeholder' => '{YOUR_AUTH_KEY}',

        // Any extra authentication-related info for your users. Markdown and HTML are supported.
        'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.',
    ],

    // Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported.
    'intro_text' => <<<INTRO
This documentation aims to provide all the information you need to work with our API.

<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
INTRO
    ,

    // Example requests for each endpoint will be shown in each of these languages.
    // Supported options are: bash, javascript, php, python
    // To add a language of your own, see https://scribe.knuckles.wtf/laravel/advanced/example-requests
    'example_languages' => [
        'bash',
        'javascript',
    ],

    // Generate a Postman collection (v2.1.0) in addition to HTML docs.
    // For 'static' docs, the collection will be generated to public/docs/collection.json.
    // For 'laravel' docs, it will be generated to storage/app/scribe/collection.json.
    // Setting `laravel.add_routes` to true (above) will also add a route for the collection.
    'postman' => [
        'enabled' => true,

        'overrides' => [
            // 'info.version' => '2.0.0',
        ],
    ],

    // Generate an OpenAPI spec (v3.0.1) in addition to docs webpage.
    // For 'static' docs, the collection will be generated to public/docs/openapi.yaml.
    // For 'laravel' docs, it will be generated to storage/app/scribe/openapi.yaml.
    // Setting `laravel.add_routes` to true (above) will also add a route for the spec.
    'openapi' => [
        'enabled' => true,

        'overrides' => [
            // 'info.version' => '2.0.0',
        ],
    ],

    'groups' => [
        // Endpoints which don't have a @group will be placed in this default group.
        'default' => 'Endpoints',

        // By default, Scribe will sort groups alphabetically, and endpoints in the order their routes are defined.
        // You can override this by listing the groups, subgroups and endpoints here in the order you want them.
        // See https://scribe.knuckles.wtf/blog/laravel-v4#easier-sorting and https://scribe.knuckles.wtf/laravel/reference/config#order for details
        'order' => [],
    ],

    // Custom logo path. This will be used as the value of the src attribute for the <img> tag,
    // so make sure it points to an accessible URL or path. Set to false to not use a logo.
    // For example, if your logo is in public/img:
    // - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs)
    // - 'logo' => 'img/logo.png' // for `laravel` type
    'logo' => false,

    // Customize the "Last updated" value displayed in the docs by specifying tokens and formats.
    // Examples:
    // - {date:F j Y} => March 28, 2022
    // - {git:short} => Short hash of the last Git commit
    // Available tokens are `{date:<format>}` and `{git:<format>}`.
    // The format you pass to `date` will be passed to PHP's `date()` function.
    // The format you pass to `git` can be either "short" or "long".
    'last_updated' => 'Last updated: {date:F j, Y}',

    'examples' => [
        // Set this to any number (eg. 1234) to generate the same example values for parameters on each run,
        'faker_seed' => null,

        // With API resources and transformers, Scribe tries to generate example models to use in your API responses.
        // By default, Scribe will try the model's factory, and if that fails, try fetching the first from the database.
        // You can reorder or remove strategies here.
        'models_source' => ['factoryCreate', 'factoryMake', 'databaseFirst'],
    ],

    // The strategies Scribe will use to extract information about your routes at each stage.
    // If you create or install a custom strategy, add it here.
    'strategies' => [
        'metadata' => [
            Strategies\Metadata\GetFromDocBlocks::class,
            Strategies\Metadata\GetFromMetadataAttributes::class,
        ],
        'urlParameters' => [
            Strategies\UrlParameters\GetFromLaravelAPI::class,
            Strategies\UrlParameters\GetFromUrlParamAttribute::class,
            Strategies\UrlParameters\GetFromUrlParamTag::class,
        ],
        'queryParameters' => [
            Strategies\QueryParameters\GetFromFormRequest::class,
            Strategies\QueryParameters\GetFromInlineValidator::class,
            Strategies\QueryParameters\GetFromQueryParamAttribute::class,
            Strategies\QueryParameters\GetFromQueryParamTag::class,
        ],
        'headers' => [
            Strategies\Headers\GetFromHeaderAttribute::class,
            Strategies\Headers\GetFromHeaderTag::class,
            [
                'override',
                [
                    'Content-Type' => 'application/json',
                    'Accept' => 'application/json',
                ]
            ]
        ],
        'bodyParameters' => [
            Strategies\BodyParameters\GetFromFormRequest::class,
            Strategies\BodyParameters\GetFromInlineValidator::class,
            Strategies\BodyParameters\GetFromBodyParamAttribute::class,
            Strategies\BodyParameters\GetFromBodyParamTag::class,
        ],
        'responses' => [
            Strategies\Responses\UseResponseAttributes::class,
            Strategies\Responses\UseTransformerTags::class,
            Strategies\Responses\UseApiResourceTags::class,
            Strategies\Responses\UseResponseTag::class,
            Strategies\Responses\UseResponseFileTag::class,
            [
                Strategies\Responses\ResponseCalls::class,
                ['only' => ['GET *']]
            ]
        ],
        'responseFields' => [
            Strategies\ResponseFields\GetFromResponseFieldAttribute::class,
            Strategies\ResponseFields\GetFromResponseFieldTag::class,
        ],
    ],

    // For response calls, API resource responses and transformer responses,
    // Scribe will try to start database transactions, so no changes are persisted to your database.
    // Tell Scribe which connections should be transacted here. If you only use one db connection, you can leave this as is.
    'database_connections_to_transact' => [config('database.default')],

    'fractal' => [
        // If you are using a custom serializer with league/fractal, you can specify it here.
        'serializer' => null,
    ],

    'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class,
];

I run everything in docker, so there is my docker configuration:

php/Dockerfile

FROM php:8.2-fpm-alpine

RUN apk add --no-cache curl git build-base zlib-dev oniguruma-dev autoconf bash libpq-dev && \
    apk add --update linux-headers

RUN docker-php-ext-install pdo pdo_pgsql

RUN pecl install xdebug && docker-php-ext-enable xdebug

COPY ./php/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini

ARG PUID=1000
ARG PGID=1000
RUN apk --no-cache add shadow && \
    groupmod -o -g ${PGID} www-data && \
    usermod -o -u ${PUID} -g www-data www-data

USER www-data

WORKDIR /var/www/timetracker

CMD ["php-fpm", "--nodaemonize"]

php/composer.Dockerfile

FROM composer:latest

WORKDIR /var/www/timetracker

ENTRYPOINT ["composer", "--ignore-platform-reqs"]

docker-compose.yaml

version: "3.8"

services:
  nginx:
    image: "nginx:stable-alpine"
    restart: always
    ports:
      - "${NGINX_HOST_HTTP_PORT}:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./app:/var/www/timetracker
    container_name: timetracker_nginx

  php:
    build:
      context: .
      dockerfile: php/Dockerfile
      args:
        - PUID=${PUID}
        - PGID=${PGID}
    restart: always
    environment:
      PHP_IDE_CONFIG: "serverName=${XDEBUG_SERVER_NAME}"
    volumes:
      - ./app:/var/www/timetracker
    container_name: timetracker_php

  postgres:
    image: postgres:alpine
    restart: always
    ports:
      - ${POSTGRES_HOST_PORT}:5432
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - timetracker_db:/var/lib/postgresql/data:rw
    container_name: timetracker_postgres

  adminer:
    image: adminer
    restart: always
    environment:
      ADMINER_DEFAULT_SERVER: postgres
    ports:
      - ${ADMINER_HOST_PORT}:8080
    container_name: timetracker_adminer

  composer:
    build:
      context: .
      dockerfile: php/composer.Dockerfile
    volumes:
      - ./app:/var/www/timetracker
    user: "${PUID}:${PGID}"

  artisan:
    build:
      context: .
      dockerfile: php/Dockerfile
    volumes:
      - ./app:/var/www/timetracker
    entrypoint: [ "php", "/var/www/timetracker/artisan" ]
    user: "${PUID}:${PGID}"

volumes:
  timetracker_db:

It's my first time when i report problem, so I'm almost sure I missed something when described my issue, so tell me if you need additional info. As well I can divide this issue on two different issue for each problem, if you need it. Thanks in advance.

Docs

shalvah commented 4 months ago

Use version 4.32.0

ArtyomDikarevWeb commented 4 months ago

Yes, this is worked, thank you