{"id":20338230,"url":"https://github.com/openclassrooms/codegenerator","last_synced_at":"2025-04-11T23:13:43.853Z","repository":{"id":25346323,"uuid":"96823606","full_name":"OpenClassrooms/CodeGenerator","owner":"OpenClassrooms","description":null,"archived":false,"fork":false,"pushed_at":"2022-02-11T16:35:10.000Z","size":3397,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-04-11T23:13:37.572Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenClassrooms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-10T21:37:48.000Z","updated_at":"2022-08-15T13:16:39.000Z","dependencies_parsed_at":"2022-07-27T05:16:13.377Z","dependency_job_id":null,"html_url":"https://github.com/OpenClassrooms/CodeGenerator","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FCodeGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FCodeGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FCodeGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenClassrooms%2FCodeGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenClassrooms","download_url":"https://codeload.github.com/OpenClassrooms/CodeGenerator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248492877,"owners_count":21113163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T21:12:07.819Z","updated_at":"2025-04-11T23:13:43.831Z","avatar_url":"https://github.com/OpenClassrooms.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CodeGenerator\n[![Build Status](https://github.com/OpenClassrooms/CodeGenerator/workflows/CodeGenerator/badge.svg)](https://github.com/OpenClassrooms/CodeGenerator/)\n[![SensioLabsInsight](https://insight.symfony.com/projects/e91d65d8-55e2-4b66-8649-1bfaf79b67d8/mini.svg)](https://insight.symfony.com/account/widget?project=e91d65d8-55e2-4b66-8649-1bfaf79b67d8)\n![Coverage](../coverage/coverage.svg)\n\nCodeGenerator is a library which generates classes in a Clean Architecture context. \n\nFrom any use case response, developers have the possibility to generate: \n- Generic use case architecture\n- Entity use case Get architecture\n- Entities use case Get architecture\n- Create Entity use case architecture\n- Delete Entity use case architecture\n- ViewModel architecture\n- Controller and models classes\n- Unit tests for each class generated\n\n## Installation\nThe easiest way to install CodeGenerator is via [composer](http://getcomposer.org/).\n\nCreate the following `composer.json` file or run the `php composer.phar install` command to install it.\n\n```commandLine\ncomposer require --dev openclassrooms/code-generator *\n```\nor\n```json\n{\n    \"require\": {\n        \"openclassrooms/code-generator\": \"*\"\n    }\n}\n```\nSetup post-install and post-update hooks in your `composer.json`'s script section,\nfor the `oc_code_generator.yml` default configuration to be generated.\nThis file is mandatory for the code generator to work.\n\n```json\n{\n  \"scripts\": {\n    \"post-install-cmd\": [\n      \"OpenClassrooms\\\\CodeGenerator\\\\Composer\\\\ParameterHandler::createGeneratorFileParameters\"\n\n    ],\n    \"post-update-cmd\": [\n      \"OpenClassrooms\\\\CodeGenerator\\\\Composer\\\\ParameterHandler::createGeneratorFileParameters\"\n    ]\n  }\n}\n```\nThe script creates a file named `oc_code_generator.yml` at the root of the project, and will ask you interactively for parameters \nwhich are missing in the parameters file, using the values of the dist file as default values, as follows:\n\n```yaml\nparameters:\n    api_dir: 'ApiBundle\\'\n    app_dir: 'AppBundle\\'\n    base_namespace: 'OC\\'\n    stub_namespace: 'Doubles\\OC\\'\n    tests_base_namespace: 'OC\\'\n    \n    entity_util_classname: 'OC\\Util\\EntityUtil'\n    \n    security_classname: 'OpenClassrooms\\UseCase\\Application\\Annotations\\Security'\n    transaction_classname: 'OpenClassrooms\\UseCase\\Application\\Annotations\\Transaction'\n    use_case_classname: 'OpenClassrooms\\UseCase\\BusinessRules\\Requestors\\UseCase'\n    use_case_request_classname: 'OpenClassrooms\\UseCase\\BusinessRules\\Requestors\\UseCaseRequest'\n    \n    paginated_collection_builder_impl: 'OpenClassrooms\\UseCase\\Application\\Entity\\PaginatedCollectionBuilderImpl'\n    paginated_collection_classname: 'OC\\BusinessRules\\Entities\\PaginatedCollection'\n    paginated_collection_factory: 'OC\\AppBundle\\Repository\\PaginatedCollectionFactory'\n    paginated_use_case_response_classname: 'OC\\BusinessRules\\Responders\\PaginatedUseCaseResponse'\n    paginated_use_case_response_builder_classname: 'OC\\BusinessRules\\Responders\\PaginatedUseCaseResponseBuilder'\n    use_case_response_classname: 'OC\\BusinessRules\\Responders\\UseCaseResponse'\n    pagination_classname: 'OC\\BusinessRules\\Gateways\\Pagination'\n    \n    abstract_controller : 'OC\\ApiBundle\\Framework\\FrameworkBundle\\Controller\\AbstractApiController'\n    collection_information : 'OC\\ApiBundle\\ParamConverter\\CollectionInformation'\n\n```\n\nYou may need to tweak these values depending on the project you are using the code generator in.\n\n## Usage\n### Basic execution\nTo list all commands: \n``` \nphp bin/code-generator\n```\nTo generate a view model architecture: \n``` \nphp bin/code-generator code-generator:view-models useCaseResponseClassName\n```\nTo generate a generic use case architecture: \n``` \nphp bin/code-generator code-generator:generic-use-case\nor  \nphp bin/code-generator code-generator:generic-use-case Domain\\\\SubDomain UseCaseName\n```\nTo generate an entity CRUD use case architecture: \n```shell\n# Create:\nphp bin/code-generator code-generator:create-entity-use-case EntityClassName\n# Delete: \nphp bin/code-generator code-generator:delete-entity-use-case EntityClassName\n# Edit:\nphp bin/code-generator code-generator:edit-entity-use-case EntityClassName\n# Get all:\nphp bin/code-generator code-generator:get-entities-use-case EntityClassName\n# Get:\nphp bin/code-generator code-generator:get-entity-use-case EntityClassName\n```  \n\n### Extensions\nTo generate without tests:\n```\nphp bin/code-generator code-generator:view-models useCaseResponseClassName --no-test\n```\nTo generate view model architecture tests only if view model classes already exist: \n``` \nphp bin/code-generator code-generator:view-models useCaseResponseClassName --tests-only\n```\nTo dump preview for view model classes: \n``` \nphp bin/code-generator code-generator:view-models useCaseResponseClassName --dump\n```\n\n### Using the code generator in PHPStorm\n\nYou can set up External Tools entries in PHPStorm to be able to run some code generator command\nfrom your IDE by right-clicking on classes in the project tree (e.g., an entity class).\n\nFor the generic use case generation, add an external tool entry like this:\n\u003e Program: /usr/local/bin/php\n\u003e Arguments: bin/code-generator code-generator:generic-use-case $Prompt$\n\u003e Working Directory: $ProjectFileDir$\n\nFor a get entity use case generation, add an external tool entry like this:\n\u003e Program: /usr/local/bin/php\n\u003e Arguments: bin/code-generator code-generator:get-entity-use-case $FilePath$ $Prompt$\n\u003e Working Directory: $ProjectFileDir$\n\nNote that this will only work if the code generator is correctly \nsetup in your project's `composer.json`. You may need to tweak this for your local\nPHP binary path.\n\n## How to create a new generator\n\n### To know\n- A generated file is described by a skeleton, in the skeleton directory.\n- A generator grabs data and sends it to the skeleton (just like a web page).\n- A generator MUST generate only one file.\n- A mediator is responsible for calling different generators.\n- A mediator can call many other mediators.\n- The command MUST call a mediator.\n- Each class MUST have an interface and its implementation.\n- FileObject contains all needed class information to generate a file.\n- Factories are used to create FileObject from Domain and Entity name.\n- Entity name and Domain are getting from ClassNameUtility trait.\n- If you need another class information in your generator, use factories to create the needed FileObject.\n- Some utility classes are used to generate stubs, constants and others things.\n- In view model command, if the use case response class name contains base namespace, the generator uses it when needed.\n\n### Methodology\n\n#### 1) Write the file templates you want to generate \nFirst, you have to create twig templates for the expected files after generation.\n#### 2) Create generator RequestDTO and generator RequestBuilder\nCreate class with the entity name suffixed by `RequestBuilder` , this is used as parameter in generator main method. \n#### 3) Start Generator Implementation\nThe main goal of the generator class is to generate the expected FileObject, but to succeed, it is necessary to build other FileObject from factories and use available Utilities. \n#### 4) Create GeneratorTest\nCreate class with the entity name suffixed by `GeneratorTest` and the related stub class (entity name suffixed by `FileObjectStub1`). The stub MUST contain expected values to compare with the actual object.\n#### 5) Create skeletonModel and SkeletonModelAssembler\nCreate two classes both prefixed by the entity name:\n- Firstly, an abstract class `SkeletonModel`,\n- Secondly `SkeletonModelAssembler`,\nBoth are used to create the object which will be used in the template.\n#### 6) Create mediator or add generator in existing mediator\nThe command uses a mediator pattern to generate classes by functional group. \nAdd the new generator in the concerned group and update the mediator config.\n#### 7) Create config files and update services.xml\nCreate a new `.xml` file for the generator and add it in `src/Resources/config/service.xml`.\n#### 8) Create the command if it does not exist\nCreate your command in `src/Commands` and call mediator `mediate` function in the `execute` method. \n\n### See an example\n\nFor a practical example, check how `src/Generator/ViewModelGenerator.php` is built.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclassrooms%2Fcodegenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenclassrooms%2Fcodegenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclassrooms%2Fcodegenerator/lists"}