├── .scrutinizer.yml ├── .travis └── before_script.sh ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── auth.json ├── composer.json ├── dev ├── .gitignore ├── LICENSE ├── README.md ├── bin │ └── init ├── composer.json ├── favicon.png ├── init ├── src │ ├── Config.php │ ├── Initialize.php │ └── TravisJob.php ├── tests │ └── TravisJobTest.php └── use-this-template.png ├── registration.php └── src ├── ExampleClass.php └── etc └── module.xml /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | filter: 2 | excluded_paths: 3 | - 'tests/*' 4 | 5 | build: 6 | environment: 7 | php: 7.3 8 | tests: 9 | override: 10 | - true 11 | nodes: 12 | analysis: 13 | dependencies: 14 | after: 15 | - vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard/ # Scrutinizer does not run composer scripts 16 | tests: 17 | override: 18 | - php-scrutinizer-run 19 | - phpcs-run 20 | 21 | tools: 22 | external_code_coverage: 23 | runs: 2 # Scrutinizer will wait for two code coverage submissions (unit and integration test suites) 24 | timeout: 2400 # Timeout in seconds. -------------------------------------------------------------------------------- /.travis/before_script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR 5 | 6 | # Disable XDebug if not needed 7 | if [[ $COVERAGE == "true" ]]; then 8 | pecl install -f xdebug-2.9.8 #see https://github.com/magento/magento2/issues/28961 9 | else 10 | phpenv config-rm xdebug.ini 11 | fi 12 | 13 | # mock mail 14 | sudo service postfix stop 15 | echo # print a newline 16 | smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000 & 17 | echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/sendmail.ini 18 | 19 | # adjust memory limit 20 | echo 'memory_limit = -1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini 21 | phpenv rehash; 22 | 23 | composer selfupdate 24 | 25 | # clone main magento github repository 26 | git clone --branch $MAGENTO_VERSION --depth=1 https://github.com/magento/magento2 27 | 28 | # install Magento 29 | cd magento2 30 | 31 | # add composer package under test, composer require will trigger update/install 32 | composer config minimum-stability dev 33 | composer config repositories.travis_to_test git https://github.com/${TRAVIS_REPO_SLUG}.git 34 | if [ ! -z $TRAVIS_TAG ] 35 | then 36 | composer require ${COMPOSER_PACKAGE_NAME}:${TRAVIS_TAG} 37 | elif [ ! -z $TRAVIS_PULL_REQUEST_BRANCH ] 38 | then 39 | # For pull requests, use the remote repository 40 | composer config repositories.travis_to_test git https://github.com/${TRAVIS_PULL_REQUEST_SLUG}.git 41 | composer require ${COMPOSER_PACKAGE_NAME}:dev-${TRAVIS_PULL_REQUEST_BRANCH}\#${TRAVIS_PULL_REQUEST_SHA} 42 | else 43 | composer require ${COMPOSER_PACKAGE_NAME}:dev-${TRAVIS_BRANCH}\#${TRAVIS_COMMIT} 44 | fi 45 | 46 | # Add tests/src to autoload-dev on project level 47 | php -r '$composer_json = json_decode(file_get_contents("composer.json"), true); 48 | $composer_json["autoload-dev"]["psr-4"][":module-namespace\\:module-name\\"] = "vendor/:vendor/:package/src"; 49 | file_put_contents("composer.json", json_encode($composer_json));' 50 | composer dumpautoload 51 | 52 | # prepare for test suite 53 | case $TEST_SUITE in 54 | integration) 55 | cp vendor/$COMPOSER_PACKAGE_NAME/tests/integration/phpunit.xml.dist dev/tests/integration/phpunit.xml 56 | 57 | cd dev/tests/integration 58 | 59 | # create database and move db config into place 60 | mysql -uroot -e ' 61 | SET @@global.sql_mode = NO_ENGINE_SUBSTITUTION; 62 | CREATE DATABASE magento_integration_tests; 63 | ' 64 | cp etc/install-config-mysql.php.dist etc/install-config-mysql.php 65 | # Remove AMQP configuration 66 | sed -i '/amqp/d' etc/install-config-mysql.php 67 | # Remove default root password 68 | sed -i 's/123123q//' etc/install-config-mysql.php 69 | 70 | cd ../../.. 71 | ;; 72 | unit) 73 | cp vendor/$COMPOSER_PACKAGE_NAME/tests/unit/phpunit.xml.dist dev/tests/unit/phpunit.xml 74 | ;; 75 | esac 76 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | ### Added 9 | ### Changed 10 | ### Removed 11 | ### Fixed 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to :module-namespace_:module-name 2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 3 | 4 | - Reporting a bug 5 | - Discussing the current state of the code 6 | - Submitting a fix 7 | - Proposing new features 8 | - Becoming a maintainer 9 | 10 | ## We Develop with Github 11 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 12 | 13 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 14 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 15 | 16 | 1. Fork the repo and create your branch from `master`. 17 | 2. If you've added code that should be tested, add tests. 18 | 3. If you've changed APIs, update the documentation. 19 | 4. Ensure the test suite passes. 20 | 5. Make sure your code lints. 21 | 6. Issue that pull request! 22 | 23 | ## Any contributions you make will be under the MIT Software License 24 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 25 | 26 | ## Report bugs using Github's [issues](https://github.com/:vendor/:package/issues) 27 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/:vendor/:package/issues/new); it's that easy! 28 | 29 | ## Write bug reports with detail, background, and sample code 30 | [This is an example](http://stackoverflow.com/q/12488905/180626) of a bug report I wrote, and I think it's not a bad model. Here's [another example from Craig Hockenberry](http://www.openradar.me/11905408), an app developer whom I greatly respect. 31 | 32 | **Great Bug Reports** tend to have: 33 | 34 | - A quick summary and/or background 35 | - Steps to reproduce 36 | - Be specific! 37 | - Give sample code if you can. [My stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing 38 | - What you expected would happen 39 | - What actually happens 40 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 41 | 42 | People *love* thorough bug reports. I'm not even kidding. 43 | 44 | ## Pull Requests 45 | 46 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - Check the code style with ``$ composer check-style`` and fix it with ``$ composer fix-style``. 47 | 48 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 49 | 50 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 51 | 52 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 53 | 54 | - **Create feature branches** - Don't ask us to pull from your master branch. 55 | 56 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 57 | 58 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 59 | 60 | ## License 61 | By contributing, you agree that your contributions will be licensed under its MIT License. 62 | 63 | ## References 64 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) with additions from [ThePhpLeague Template](https://github.com/thephpleague/skeleton) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) :year :company 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![/>](./dev/favicon.png) integer_net Magento 2 Module Template 2 | 3 | This is a GitHub template. 4 | 5 | **Create your module now with the "use this template" button:** 6 | 7 | [![Use this template](dev/use-this-template.png)](https://github.com/integer-net/magento2-module-template/generate) 8 | 9 | After that, clone it on your machine and run `./dev/init` inside the repository directory for automatic configuration. For more information, see [dev/README.md](dev/README.md) 10 | 11 |
Waschbär Approved Module
12 | 13 | --- 14 | 15 | 16 | 17 | # :module-namespace_:module-name Magento Module 18 |
19 | 20 | [![Latest Version on Packagist][ico-version]][link-packagist] 21 | [![Software License][ico-license]](LICENSE.md) 22 | [![Build Status][ico-travis]][link-travis] 23 | ![Supported Magento Versions][ico-compatibility] 24 | 25 | [![Coverage Status][ico-scrutinizer]][link-scrutinizer] 26 | [![Quality Score][ico-code-quality]][link-code-quality] 27 | [![Maintainability][ico-maintainability]][link-maintainability] 28 |
29 | 30 | --- 31 | 32 | :description 33 | 34 | ## Installation 35 | 36 | 1. Install it into your Magento 2 project with composer: 37 | ``` 38 | composer require :vendor/:package 39 | ``` 40 | 41 | 2. Enable module 42 | ``` 43 | bin/magento setup:upgrade 44 | ``` 45 | 46 | ## Configuration 47 | 48 | ## Usage 49 | 50 | ## Changelog 51 | 52 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 53 | 54 | ## Contributing 55 | 56 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 57 | 58 | ## Testing 59 | 60 | ### Unit Tests 61 | 62 | ``` 63 | ./vendor/bin/phpunit tests/unit 64 | ``` 65 | 66 | ### Magento Integration Tests 67 | 68 | 0. Configure test database in `dev/tests/integration/etc/install-config-mysql.php`. [Read more in the Magento docs.](https://devdocs.magento.com/guides/v2.4/test/integration/integration_test_execution.html) 69 | 70 | 1. Copy `tests/integration/phpunit.xml.dist` from the package to `dev/tests/integration/phpunit.xml` in your Magento installation. 71 | 72 | 2. In that directory, run 73 | ``` bash 74 | ../../../vendor/bin/phpunit 75 | ``` 76 | 77 | 78 | ## Security 79 | 80 | If you discover any security related issues, please email :author-email instead of using the issue tracker. 81 | 82 | ## Credits 83 | 84 | - [:author-name][link-author] 85 | - [All Contributors][link-contributors] 86 | 87 | ## License 88 | 89 | The MIT License (MIT). Please see [License File](LICENSE) for more information. 90 | 91 | [ico-version]: https://img.shields.io/packagist/v/:vendor/:package.svg?style=flat-square 92 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square 93 | [ico-travis]: https://img.shields.io/travis/:vendor/:package/master.svg?style=flat-square 94 | [ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/:vendor/:package?style=flat-square 95 | [ico-code-quality]: https://img.shields.io/scrutinizer/g/:vendor/:package.svg?style=flat-square 96 | [ico-maintainability]: https://img.shields.io/codeclimate/maintainability/:vendor/:package?style=flat-square 97 | [ico-compatibility]: https://img.shields.io/badge/magento-:version-badge-brightgreen.svg?logo=magento&longCache=true&style=flat-square 98 | 99 | [link-packagist]: https://packagist.org/packages/:vendor/:package 100 | [link-travis]: https://travis-ci.org/:vendor/:package 101 | [link-scrutinizer]: https://scrutinizer-ci.com/g/:vendor/:package/code-structure 102 | [link-code-quality]: https://scrutinizer-ci.com/g/:vendor/:package 103 | [link-maintainability]: https://codeclimate.com/github/:vendor/:package 104 | [link-author]: https://github.com/:author-github 105 | [link-contributors]: ../../contributors 106 | -------------------------------------------------------------------------------- /auth.json: -------------------------------------------------------------------------------- 1 | { 2 | "http-basic": { 3 | "repo.magento.com": { 4 | "username": ":magento-repo-public-key", 5 | "password": ":magento-repo-private-key" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": ":vendor/:package", 3 | "description": ":description", 4 | "type": "magento2-module", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": ":author-name", 9 | "email": ":author-email" 10 | } 11 | ], 12 | "minimum-stability": "stable", 13 | "autoload": { 14 | "files": [ 15 | "registration.php" 16 | ], 17 | "psr-4": { 18 | ":module-namespace\\:module-name\\": "src" 19 | } 20 | }, 21 | "autoload-dev": { 22 | "psr-4": { 23 | ":module-namespace\\:module-name\\": "tests/src" 24 | } 25 | }, 26 | "repositories": [ 27 | { 28 | "type": "composer", 29 | "url": "https://repo.magento.com/" 30 | } 31 | ], 32 | "require": { 33 | "php": ":php-constraint", 34 | "magento/framework": ":framework-constraint" 35 | }, 36 | "require-dev": { 37 | "roave/security-advisories": "dev-master", 38 | "phpunit/phpunit": "^6.0|^9.0", 39 | "pds/skeleton": "^1.0", 40 | "phpro/grumphp": "^v0.21.0", 41 | "phpstan/phpstan": "^0.12.0", 42 | "squizlabs/php_codesniffer": "^3.5", 43 | "magento/magento-coding-standard": "@dev" 44 | }, 45 | "scripts": { 46 | "post-install-cmd": [ 47 | "vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard/" 48 | ], 49 | "post-update-cmd": [ 50 | "vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard/" 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dev/.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /composer.lock -------------------------------------------------------------------------------- /dev/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 integer_net GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dev/README.md: -------------------------------------------------------------------------------- 1 | # integer_net Magento 2 Module Template 2 | 3 | To automatically replace all placeholders with custom values, run the following script: 4 | 5 | ``` 6 | dev/init 7 | ``` 8 | 9 | It runs interactively and tries to present you sensible default variables based on your repository. 10 | 11 | 12 | To learn about additional options, run `dev/init --help`. 13 | 14 | **The `dev/` directory can be removed after initialization!** 15 | 16 | ## Placeholders explained 17 | 18 | | Placeholder | Purpose | 19 | | -------------- | ------- | 20 | | Magento Repo Public Key | Used for `auth.json` so that composer install works with repo.magento.com. See https://devdocs.magento.com/guides/v2.4/install-gde/prereq/connect-auth.html how to obtain keys.
⚠ **The keys will be visible, so do not use an account used for commerce license or marketplace extensions!** | 21 | | Magento Repo Private Key | see above | 22 | | Vendor | Vendor name for composer package, should match the name of your GitHub user or organization | 23 | | Package | Package name for composer package | 24 | | Description | A short description what the module does and for whom it is useful. Placed at the top of the README and as description in `composer.json` | 25 | | Author name | Main author name, used in composer.json and README | 26 | | Author email | Main author email, used in composer.json and README | 27 | | Author github | GitHub username of main author, used in README to link to the profile | 28 | | Module namespace | Top level PHP namespace (e.g. company name) | 29 | | Module name | Second level PHP namespace (module name) | 30 | | Company | Full company name, used in LICENSE | 31 | | Year | Current year, used in LICENSE | 32 | 33 | ## Magento Compatibility 34 | 35 | You are asked which Magento versions you want so support. Based on the answer, version constraints for `php` and `magento/framework` are initialized in `composer.json`, and test jobs generated in `.travis.yml`. Feel free to change those later, for example if you don't want to support older PHP versions. 36 | 37 | # Developing the template 38 | 39 | ### Adding placeholders 40 | 41 | To add new placeholders, adjust the initialization script config in `dev/src/Config.php` 42 | 43 | Files where placeholders are replaced are defined in `getFilesToUpdate()`, placeholders with their default values in `getDefaultVariables()` 44 | 45 | ### Adding or removing a new Magento version 46 | 47 | When new Magento versions should be added to the template or support for old ones dropped, the following changes are necessary: 48 | 49 | - In `dev/src/Config.php`, change `getMagentoVersions()`, where Magento versions are defined together with their PHP and framework version constraints. 50 | - In `dev/src/TravisJob.php` change the constants `LATEST_MAGENTO_VERSION` and `DEV_BRANCH_JOBS` to define the current develop branch of Magento. 51 | 52 | 53 | ## License 54 | 55 | ### Template 56 | 57 | The template itself is licensed under [WTFPL](http://www.wtfpl.net/txt/copying/). 58 | 59 | ### Initialization script 60 | 61 | The initialization script (content of the dev/ directory) is licensed under [MIT](./LICENSE) 62 | -------------------------------------------------------------------------------- /dev/bin/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | setSignature('./' . __FILE__ . ''); 15 | 16 | $app->registerCommand( 17 | 'init', 18 | new Initialize($app) 19 | ); 20 | 21 | $app->runCommand([$argv[0], 'init', ...array_slice($argv, 1)]); 22 | 23 | -------------------------------------------------------------------------------- /dev/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integer-net/magento2-module-template-init", 3 | "description": "Initializes Magento module based on integer_net template", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Fabian Schmengler", 8 | "email": "fs@integer-net.de" 9 | } 10 | ], 11 | "bin": [ 12 | "./bin/init" 13 | ], 14 | "require": { 15 | "php": "^7.4", 16 | "minicli/minicli": "^2.1", 17 | "nette/neon": "^3.2" 18 | }, 19 | "require-dev": { 20 | "roave/security-advisories": "dev-master", 21 | "phpunit/phpunit": "^9.3" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "IntegerNet\\ModuleTemplate\\": "src" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dev/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/integer-net/magento2-module-template/9599521413663a118e776614222b1a09c52d18c2/dev/favicon.png -------------------------------------------------------------------------------- /dev/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd $(realpath $(dirname $0)) 3 | [ -d vendor ] || composer install --no-dev 4 | ./bin/init .. $@ 5 | -------------------------------------------------------------------------------- /dev/src/Config.php: -------------------------------------------------------------------------------- 1 | '', 58 | ':magento-repo-private-key' => '', 59 | ':vendor' => $vendor, 60 | ':package' => $package, 61 | ':description' => 'This module is awesome!', 62 | ':author-name' => $gitUserName ?: 'John Doe', 63 | ':author-email' => $gitUserEmail ?: 'john.doe@example.com', 64 | ':author-github' => $vendor, 65 | ':module-namespace' => $moduleNamespace, 66 | ':module-name' => $moduleName, 67 | ':company' => $company, 68 | ':year' => (string)date('Y'), 69 | ]; 70 | } 71 | 72 | /** 73 | * Exact PHP requirements are already handled by magento/framework itself, but making it explicit allows the module 74 | * author to tighten the constraints, e.g. make the module work with Magento 2.3 but still require at least PHP 7.3. 75 | * 76 | * Also, the supported PHP versions are used by {@see TravisJob::getConfiguration()} to generate Travis jobs. 77 | * 78 | * The following placeholder values will be generated automatically based on choosen compatible versions: 79 | * 80 | * @return string[][][] Associative array with Magento versions and dependencies for composer 81 | * @see Initialize::askMagentoCompatibility() 82 | * 83 | * :php-constraint Composer version constraint for PHP 84 | * :framework-constraint Composer version constraint for Magento framework 85 | * :version-badge Text for the "Magento" compatibility badge 86 | * 87 | */ 88 | public static function getMagentoVersions(): array 89 | { 90 | return [ 91 | '2.2' => [ 92 | 'php' => ['~7.0', '~7.1', '~7.2'], 93 | 'magento-framework' => ['^101.0.0'], 94 | ], 95 | '2.3' => [ 96 | 'php' => ['~7.1', '~7.2', '~7.3'], 97 | 'magento-framework' => ['^102.0.0'], 98 | ], 99 | '2.4' => [ 100 | 'php' => ['~7.3', '~7.4'], 101 | 'magento-framework' => ['^103.0.0'], 102 | ], 103 | ]; 104 | } 105 | 106 | /** 107 | * package prefixes that should not be part of the module name (capitalized because used after ucwords()) 108 | * 109 | * This covers e.g.: 110 | * 111 | * magento2- 112 | * magento2-module 113 | * 114 | * @param string $moduleNamespace 115 | * @return string[] 116 | */ 117 | private static function getCommonModulePrefixes(string $moduleNamespace): array 118 | { 119 | return ['Magento2', 'Module', $moduleNamespace]; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /dev/src/Initialize.php: -------------------------------------------------------------------------------- 1 | app = $app; 32 | $this->prompt = new Input('>'); 33 | $this->printer = $app->getPrinter(); 34 | } 35 | 36 | public function __invoke(CommandCall $input) 37 | { 38 | $this->configureFromFlags($input); 39 | 40 | if ($input->hasFlag('--help') || $input->hasFlag('-h') || $input->hasParam('help')) { 41 | $this->showHelp(); 42 | return; 43 | } 44 | 45 | try { 46 | $rootDir = $this->getRootDir($input); 47 | $this->printer->display("Module directory: $rootDir"); 48 | 49 | $this->welcome(); 50 | 51 | $values = Config::getDefaultVariables(); 52 | do { 53 | $values = $this->askValues($values); 54 | $this->previewValues($values); 55 | } while (!$this->confirm('Does that look right?')); 56 | $values += $this->askMagentoCompatibility(); 57 | 58 | $this->replaceValues($rootDir, $values); 59 | $this->removeReadmeSection($rootDir); 60 | $this->success($values); 61 | } catch (\Exception $e) { 62 | $this->printer->error($e->getMessage()); 63 | } 64 | } 65 | 66 | private function showHelp() 67 | { 68 | $README = 'file://' . dirname(__DIR__) . '/README.md'; 69 | $this->printer->info('The init script replaces all placeholders in the template for you interactively'); 70 | $this->printer->info("You can find an explanation of the placeholders in dev/README.md if needed."); 71 | $this->printer->display("\t{$README}"); 72 | $this->printer->info('Options:'); 73 | $this->printer->info( 74 | implode( 75 | "\n", 76 | [ 77 | "\t--unicorn\tUse a more colorful theme", 78 | "\t--no-ansi\tDo not use colors", 79 | "\t--help | -h\tShow this help", 80 | ] 81 | ) 82 | ); 83 | } 84 | 85 | private function configureFromFlags(CommandCall $input): void 86 | { 87 | if ($input->hasFlag('--unicorn')) { 88 | $this->app->setTheme('\Unicorn'); 89 | // Registering a theme initializes a new printer instance 90 | $this->printer = $this->app->getPrinter(); 91 | } 92 | if ($input->hasFlag('--no-ansi')) { 93 | $this->printer->clearFilters(); 94 | } 95 | } 96 | 97 | private function getRootDir(CommandCall $input): string 98 | { 99 | $rootDir = ($input->args[2] ?? ''); 100 | if (strpos($rootDir, '/') !== 0) { 101 | $rootDir = getcwd() . '/' . $rootDir; 102 | } 103 | if (realpath($rootDir) === false) { 104 | throw new \RuntimeException('Path not found: ' . $rootDir); 105 | } 106 | return realpath($rootDir); 107 | } 108 | 109 | private function welcome() 110 | { 111 | $helpUrl = 'https://devdocs.magento.com/guides/v2.4/install-gde/prereq/connect-auth.html'; 112 | $this->printer->info( 113 | implode( 114 | "\n", 115 | [ 116 | "┌──────────────────────────────────────────────────┐", 117 | "│ 🎆 Your open source module will be ready soon! 🎆│", 118 | "└──────────────────────────────────────────────────┘", 119 | '🔑 First you need a key pair for repo.magento.com. To learn how to obtain keys,', 120 | ' see: ' . $helpUrl, 121 | '', 122 | '❓ Why? The credentials will be stored in auth.json so that services like', 123 | ' Scrutinizer can install the required Magento modules with composer.', 124 | '', 125 | '✏ But you can also leave them empty for now and change auth.json manually later.', 126 | ] 127 | ) 128 | ); 129 | $this->printer->error( 130 | implode( 131 | "\n", 132 | [ 133 | "⚠ The keys will be visible, so do not use an account used for commerce license", 134 | " or for marketplace extensions!" 135 | ] 136 | ) 137 | ); 138 | } 139 | 140 | private function askValues(array $defaultValues): array 141 | { 142 | $values = []; 143 | foreach ($defaultValues as $key => $default) { 144 | $this->printer->out(str_replace('-', ' ', ucfirst(substr($key, 1))) . " [$default] "); 145 | $values[$key] = $this->prompt->read() ?: $default; 146 | } 147 | return $values; 148 | } 149 | 150 | private function previewValues(array $values): void 151 | { 152 | $this->printer->info('🔄 The following values will be replaced in package files:'); 153 | $this->printer->printTable( 154 | array_merge( 155 | [['placeholder', 'value']], 156 | array_map(fn($key, $value) => [$key, $value], array_keys($values), $values) 157 | ) 158 | ); 159 | } 160 | 161 | private function confirm(string $question): bool 162 | { 163 | do { 164 | $this->printer->out($question . ' [Y/N] ', 'alt'); 165 | $response = $this->prompt->read(); 166 | } while (trim($response) === ''); 167 | return !(stripos($response, 'Y') !== 0); 168 | } 169 | 170 | private function askMagentoCompatibility(): array 171 | { 172 | $this->printer->info( 173 | implode( 174 | "\n", 175 | [ 176 | '📦 Please specify which Magento versions you intend to support.', 177 | ' This will generate:', 178 | ' - Version constraints in composer.json', 179 | ' - Jobs in .travis.yml', 180 | ] 181 | ) 182 | ); 183 | $magentoVersions = []; 184 | $magentoVersionConstraints = []; 185 | while (empty($magentoVersions)) { 186 | foreach (Config::getMagentoVersions() as $version => $constraints) { 187 | if ($this->confirm("Compatible with Magento {$version}?")) { 188 | $magentoVersions[] = $version; 189 | $magentoVersionConstraints[] = $constraints; 190 | } 191 | } 192 | if (empty($magentoVersions)) { 193 | $this->printer->error('Please select at least one Magento version'); 194 | } 195 | } 196 | $mergedConstraints = array_map('array_unique', array_merge_recursive(...$magentoVersionConstraints)); 197 | return [ 198 | ':php-constraint' => implode('||', $mergedConstraints['php']), 199 | ':framework-constraint' => implode('||', $mergedConstraints['magento-framework']), 200 | ':version-badge' => implode('%20|%20', $magentoVersions), 201 | ':travis-jobs' => TravisJob::getConfiguration($magentoVersions), 202 | ]; 203 | } 204 | 205 | private function replaceValues(string $rootDir, array $values): void 206 | { 207 | $this->printer->info('Replacing values in files:', true); 208 | foreach (Config::getFilesToUpdate() as $file) { 209 | $file = $rootDir . '/' . $file; 210 | $content = file_get_contents($file); 211 | file_put_contents($file, strtr($content, $values)); 212 | $this->printer->out('✔ ' . substr($file, strlen($rootDir) + 1) . "\n", 'info'); 213 | } 214 | } 215 | 216 | /** 217 | * Removes everything until from README.md 218 | * @param string $rootDir 219 | */ 220 | private function removeReadmeSection(string $rootDir) 221 | { 222 | $readmeFile = $rootDir . '/README.md'; 223 | $content = file_get_contents($readmeFile); 224 | $separator = "\n\n"; 225 | file_put_contents($readmeFile, substr($content, strpos($content, $separator) + strlen($separator))); 226 | $this->printer->out('✔ ' . "README.md template section removed\n", 'info'); 227 | } 228 | 229 | private function success(array $values): void 230 | { 231 | $this->printer->success( 232 | implode( 233 | "\n", 234 | [ 235 | "┌──────────────────────────────────────────────────────────────┐", 236 | "│ 🔽 All values have been replaced. Your next steps should be: │", 237 | "└──────────────────────────────────────────────────────────────┘", 238 | ] 239 | ) 240 | ); 241 | $this->removeDevDirectory(); 242 | $this->commitChanges(); 243 | $this->connectServices($values); 244 | $this->startCoding($values); 245 | $this->installDependencies(); 246 | $this->printer->success( 247 | implode( 248 | "\n", 249 | [ 250 | "┌──────────────────────────────────────────────────────────────┐", 251 | "│ 🔼 Almost done! Please read your next steps above carefully! │", 252 | "└──────────────────────────────────────────────────────────────┘", 253 | ] 254 | ) 255 | ); 256 | } 257 | 258 | private function removeDevDirectory() 259 | { 260 | $this->printer->out("🔸 Remove the dev directory:", 'info'); 261 | $this->printer->display("\trm -rf ./dev\n"); 262 | } 263 | 264 | private function commitChanges() 265 | { 266 | $this->printer->out("🔸 Commit and push initial version:", 'info'); 267 | $this->printer->display("\tgit add -A && git commit -m 'Replace placeholders' && git push origin master\n"); 268 | } 269 | 270 | private function connectServices(array $values) 271 | { 272 | $this->printer->out( 273 | implode( 274 | "\n", 275 | [ 276 | "🔸 Connect the following services with the Github repository:", 277 | " - Packagist to make it available with composer:", 278 | " https://packagist.org/packages/submit", 279 | " - Travis CI to run tests:", 280 | " https://travis-ci.org/organizations/{$values[':vendor']}/repositories", 281 | " - Scrutinizer for code quality and test coverage:", 282 | " https://scrutinizer-ci.com/g/new", 283 | " - (optional) Code Climate for more code quality metrics:", 284 | " https://codeclimate.com/github/repos/new", 285 | "\n", 286 | ] 287 | ), 288 | 'info' 289 | ); 290 | } 291 | 292 | private function startCoding(array $values) 293 | { 294 | $this->printer->out("🔸 Install module IN A MAGENTO INSTALLATION to start developing:", 'info'); 295 | $this->printer->display( 296 | " composer require --prefer-source {$values[':vendor']}/{$values[':package']} dev-master\n" 297 | ); 298 | $this->printer->out( 299 | "🔸 Now you have the Git repository in\n". 300 | " vendor/{$values[':vendor']}/{$values[':package']}\n\n", 301 | 'info' 302 | ); 303 | } 304 | 305 | private function installDependencies() 306 | { 307 | $this->printer->out( 308 | "🔸 Install dev dependencies IN THAT DIRECTORY for automatic code quality checks:", 309 | 'info' 310 | ); 311 | $this->printer->display(" composer install"); 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /dev/src/TravisJob.php: -------------------------------------------------------------------------------- 1 | '7.4', 25 | 'env' => [ 26 | 'MAGENTO_VERSION=2.4-develop', 27 | 'TEST_SUITE=integration', 28 | ], 29 | ], 30 | ]; 31 | 32 | public static function getConfiguration(array $magentoVersions) 33 | { 34 | $versionConstraints = Config::getMagentoVersions(); 35 | $jobs = []; 36 | foreach ($magentoVersions as $magentoKey => $magentoVersion) { 37 | $phpVersions = map( 38 | fn($constraint) => ltrim($constraint, '^~'), 39 | $versionConstraints[$magentoVersion]['php'] 40 | ); 41 | // Integration tests for each PHP version 42 | foreach ($phpVersions as $phpKey => $phpVersion) { 43 | $job = [ 44 | 'php' => $phpVersion, 45 | 'env' => [ 46 | 'MAGENTO_VERSION=' . $magentoVersion, 47 | 'TEST_SUITE=integration', 48 | ], 49 | ]; 50 | // Integration test coverage only for latest PHP and Magento version 51 | if ($magentoKey === array_key_last($magentoVersions) && $phpKey === array_key_last($phpVersions)) { 52 | $job['env'][] = 'COVERAGE=true'; 53 | } 54 | $jobs['include'][] = $job; 55 | } 56 | // Add unit tests only for latest PHP and Magento version 57 | if ($magentoKey === array_key_last($magentoVersions)) { 58 | $jobs['include'][] = [ 59 | 'php' => $phpVersion, 60 | 'env' => [ 61 | 'MAGENTO_VERSION=' . $magentoVersion, 62 | 'TEST_SUITE=unit', 63 | 'COVERAGE=true', 64 | ], 65 | ]; 66 | } 67 | } 68 | // Add jobs for dev branch if latest Magento version is supported 69 | if (in_array(self::LATEST_MAGENTO_VERSION, $magentoVersions, true)) { 70 | foreach (self::DEV_BRANCH_JOBS as $job) { 71 | $jobs['include'][] = $job; 72 | $jobs['allow_failures'][] = $job; 73 | } 74 | } 75 | return str_replace("\t", ' ', Neon::encode(['jobs' => $jobs], Encoder::BLOCK)); 76 | } 77 | } -------------------------------------------------------------------------------- /dev/tests/TravisJobTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($expectedYaml, TravisJob::getConfiguration($magentoVersions)); 16 | } 17 | 18 | public function yamlExpectation() 19 | { 20 | yield 'Magento 2.3 | 2.4' => [ 21 | ['2.3', '2.4'], 22 | << [ 81 | ['2.4'], 82 | << [ 121 | ['2.3'], 122 | << 2 | 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------