laravel-shift / blueprint

A code generation tool for Laravel developers.
MIT License
2.83k stars 271 forks source link

Controllers not generated, empty namespace #269

Closed gmgarrison closed 4 years ago

gmgarrison commented 4 years ago

Issue:

Controller files are generated with no namespace and empty classes. Models are generated in the root directory. (Am I doing any of this right??)

Also, php artisan blueprint:build ends with an error relating to the lack of namespaces, I believe:

 TypeError

  Argument 1 passed to Blueprint\Blueprint::relativeNamespace() must be of the type string, null given, called in /srv/fameo/vendor/laravel-shift/blueprint/src/Generators/TestGenerator.php on line 76

  at vendor/laravel-shift/blueprint/src/Blueprint.php:15
    11| {
    12|     private $lexers = [];
    13|     private $generators = [];
    14|
  > 15|     public static function relativeNamespace(string $fullyQualifiedClassName)
    16|     {
    17|         $namespace = config('blueprint.namespace') . '\\';
    18|         $reference = ltrim($fullyQualifiedClassName, '\\');
    19|

The error was the only output, so I was surprised to see that the Model files, factories and seeders were all generated. (Models also have no namespace.)

draft.yaml:

# https://blueprint.laravelshift.com/docs/generating-components/
models:
  Enum:
    value: varchar(200)
  EnumCountry:
    value: varchar(200)
  EnumState:
    value: varchar(200)
  Profile:
    state: id foreign:enumState
    country: id foreign:enumCountry
    type: tinyint unsigned index
    status: tinyint unsigned index
    timezone: tinyint unsigned
    softDeletes
  Video:
    owner_id: id foreign:user
    parent_id: id foreign:user
    url: string(150)
    status: tinyint unsigned index
    visibility: tinyint unsigned
    prompt: id foreign:prompt
    size: int unsigned
    length: int unsigned
    views: mediumint unsigned
    softDeletes
  Prompt:
    text: varchar(400)
    type: tinyint unsigned index
    status: tinyint unsigned index
    group: id foreign:promptGroup
    softDeletes
  PromptGroup:
    name: varchar(100)
    type: tinyint unsigned index
    status: tinyint unsigned index
    softDeletes
  PromptSchedule:
    parent_id: id foreign:user
    user_id: id foreign:user
    prompt_id: id foreign:prompt
    video_id: id foreign:video
    status: tinyint unsigned index
    send_date: datetime
    softDeletes
  Family:
    name: varchar(100)
    status: tinyint unsigned index
    softDeletes
  Relation:
    family_id: id foreign:family
    parent_id: id foreign:user
    user_id: id foreign:user
    type: tinyint unsigned
    status: tinyint unsigned
    softDeletes
seeders: Profile, Video, Prompt, PromptGroup, PromptSchedule, Family, Relation
controllers:
  Profile:
    resource: all
  Video:
    resource: all
  Prompt:
    resource: all
  PromptGroup:
    resource: all
  PromptSchedule:
    resource: all
  Family:
    resource: all
  Relation:
    resource: all

I also have the blueprint.php config file:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Application Namespace
    |--------------------------------------------------------------------------
    |
    | Blueprint uses the default Laravel application namespace of 'App'.
    | However, you may configure Blueprint to use a custom namespace.
    | This value should match a PSR-4 autoload configuration value
    | within the composer.json file of your Laravel application.
    |
    */
    'namespace' => 'App',

    /*
    |--------------------------------------------------------------------------
    | Component Namespaces
    |--------------------------------------------------------------------------
    |
    | Blueprint promotes following Laravel conventions. As such, it generates
    | components under the default namespaces. For example, models are under
    | the `App` namespace. However, you may configure Blueprint to use
    | your own custom namespace when generating these components.
    |
    */
    'models_namespace' => 'Models',
    'controllers_namespace' => 'Http\\Controllers',

    /*
    |--------------------------------------------------------------------------
    | Application Path
    |--------------------------------------------------------------------------
    |
    | By default, Blueprint will save the generated application components
    | under the files under the `app` folder. However, you may configure
    | Blueprint  to save these generated component under a custom path.
    |
    */
    'app_path' => 'app',

    /*
    |--------------------------------------------------------------------------
    | Generate PHPDocs
    |--------------------------------------------------------------------------
    |
    | Here you may enable generate PHPDocs for classes like Models. This
    | not only serves as documentation, but also allows your IDE to
    | map to the dynamic properties used by Laravel Models.
    |
    */
    'generate_phpdocs' => true,

    /*
    |--------------------------------------------------------------------------
    | Foreign Key Constraints
    |--------------------------------------------------------------------------
    |
    | Here you may enable Blueprint to always add foreign key constraints
    | within the generated migration. This will relate these records
    | together to add structure and integrity to your database.
    |
    | In addition, you may specify the action to perform `ON DELETE`. By
    | default Blueprint will use `cascade`. However, you may set this
    | to 'restrict', 'no_action', or 'null' as well as inline
    | by defining your `foreign` key column with an `onDelete`.
    |
    */
    'use_constraints' => false,

    'on_delete' => 'cascade',

    /*
    |--------------------------------------------------------------------------
    | Fake Nullables
    |--------------------------------------------------------------------------
    |
    | By default, Blueprint will set fake data even for nullable columns
    | within the generated model factories. However, you may disable
    | this behavior if you prefer to only set required columns
    | within your model factories.
    |
    */
    'fake_nullables' => true,

    /*
    |--------------------------------------------------------------------------
    | Use Guarded
    |--------------------------------------------------------------------------
    |
    | By default, Blueprint will set the `fillable` property within generated
    | models with the defined columns. These are set to provide a foundation
    | for mass assignment protection provided by Laravel. However, you may
    | configure Blueprint to instead set an empty `guarded` property to
    | generated "unguarded" models.
    |
    */
    'use_guarded' => false,

];

Thanks for any help!!

jasonmccreary commented 4 years ago

Believe some have reported this for Windows, but not Mac. I will try using Blueprint with a config file to see how I might be able to reproduce.

gmgarrison commented 4 years ago

If it's any help, I'm starting with this Laravel boilerplate: https://github.com/jeremykenedy/laravel-auth. From there, I think about all I've done is add Cashier. Let me know if I can provide anything else!

jasonmccreary commented 4 years ago

It's probably unrelated. But I will say Blueprint follows Laravel conventions and structure. So any customizations required by the "template" or "modules" package will need to be done manually, and as such likely diminish the value of Blueprint.

With that said, Blueprint should run without error for custom configurations.

gmgarrison commented 4 years ago

I assumed it would be unrelated but know that having as complete a picture as possible can come in handy in unexpected ways. To my (limited) understanding, the boilerplate follows Laravel conventions as most of it seems to come in the form of supplied middleware. If you end up spending any time poking around in it and come to a different conclusion, I'd appreciate hearing it!

jasonmccreary commented 4 years ago

Sorry, but I am unable to reproduce this error. I used your exact draft.yaml and blueprint.php config file.

It doesn't seem to be widespread, otherwise Blueprint would be completely unusable. So it has to be some kind of local setup I'm not expecting.

If you are so inclined, maybe you could dig into the code a bit to see what is missing.

A simple dd() of the values used in TestGenerator.php on line 76 would likely provide some clues.

gmgarrison commented 4 years ago

I just re-cloned that boilerplate repo, added Blueprint and it worked like a charm... I'll make a mental note to do Blueprint very early in my process and one day maybe I'll debug this and see what's happening. When/if that happens, I'll let you know. Thank you!!

Ghosstk commented 4 years ago

Hey! I have the same error.

I didn't used any boilerplate. Fresh laravel and laravel ui install.

Laravel Version: 7.15.0 PHP Version: 7.4.4 Blueprint Version: 1.14.0 Platform: Win10

draft.yml ``` models: Project: name: string:255 payment_type: unsignedTinyInteger currency: string:10 price: decimal:13,2 start_at: timestamp nullable end_at: timestamp nullable relationships: belongsTo: User controllers: Project: resource: api seeders: Project ```
config: ``` 'App', 'models_namespace' => 'Models', 'controllers_namespace' => 'Http\\Controllers\\Api\\V1', 'app_path' => 'app', 'generate_phpdocs' => false, 'use_constraints' => false, 'on_delete' => 'cascade', 'fake_nullables' => true, 'use_guarded' => false ]; ```
TestGenerator#76-77 - dd($controller) ``` Blueprint\Models\Controller {#1835 -name: "Project" -namespace: "" -methods: array:5 [ "index" => array:2 [ 0 => Blueprint\Models\Statements\QueryStatement {#1830 -operation: "all" -clauses: array:1 [ 0 => "projects" ] -model: "Project" } 1 => Blueprint\Models\Statements\ResourceStatement {#1843 -reference: "projects" -collection: true -paginate: false } ] "store" => array:3 [ 0 => Blueprint\Models\Statements\ValidateStatement {#1841 -data: array:1 [ 0 => "project" ] } 1 => Blueprint\Models\Statements\EloquentStatement {#1842 -operation: "save" -reference: "project" -columns: [] } 2 => Blueprint\Models\Statements\ResourceStatement {#1840 -reference: "project" -collection: false -paginate: false } ] "show" => array:1 [ 0 => Blueprint\Models\Statements\ResourceStatement {#1839 -reference: "project" -collection: false -paginate: false } ] "update" => array:3 [ 0 => Blueprint\Models\Statements\ValidateStatement {#1838 -data: array:1 [ 0 => "project" ] } 1 => Blueprint\Models\Statements\EloquentStatement {#1837 -operation: "update" -reference: "project" -columns: [] } 2 => Blueprint\Models\Statements\ResourceStatement {#1836 -reference: "project" -collection: false -paginate: false } ] "destroy" => array:2 [ 0 => Blueprint\Models\Statements\EloquentStatement {#1844 -operation: "delete" -reference: "project" -columns: [] } 1 => Blueprint\Models\Statements\RespondStatement {#1845 -status: 200 -content: null } ] ] -apiResource: true } ```
dd($stubs) ``` """

Fixed:

Config cache clear helped.

php artisan config:clear
jasonmccreary commented 4 years ago

Interesting. So it seems you published a custom config, however, Laravel was caching the original "empty" config. We'll see if clearing cache helps future users.