From f4fbbcab77112de00e4bd04d397a41ce2475495d Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 11:52:52 +0100 Subject: [PATCH 1/6] FEATURE: Provide first basic implementation of classmapping * Install PHP CodeSniffer. * Install our project as new Standard. * Set our Standard as default. * Provide first basic implementation to detect implemented interfaces with old legacy class names and migrate them to new ones. --- .gitignore | 4 + Makefile | 16 +++ Readme.rst | 27 ++++ composer.json | 23 ++++ .../Sniffs/Legacy/ClassnamesSniff.php | 116 ++++++++++++++++++ src/Standards/Typo3Update/ruleset.xml | 4 + 6 files changed, 190 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 Readme.rst create mode 100644 composer.json create mode 100644 src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php create mode 100644 src/Standards/Typo3Update/ruleset.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b4873f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/LegacyClassnames.php + +/composer.lock +/vendor/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..432e039 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +BIN_PHPCS = ./vendor/bin/phpcs +BIN_PHPCBF = ./vendor/bin/phpcbf +DEFAULT_STANDARD = Typo3Update +CUSTOM_STANDARDS = $(abspath ./src/Standards/) + +install: + composer install + $(BIN_PHPCS) --config-set installed_paths $(CUSTOM_STANDARDS) + $(BIN_PHPCS) -i | grep Typo3Update + $(BIN_PHPCS) --config-set default_standard $(DEFAULT_STANDARD) + +# For development / testing purposes: +test-search: + $(BIN_PHPCS) -p --colors -s PROJECT_PATH +test-fix: + $(BIN_PHPCBF) -p --colors -s PROJECT_PATH diff --git a/Readme.rst b/Readme.rst new file mode 100644 index 0000000..50a98b1 --- /dev/null +++ b/Readme.rst @@ -0,0 +1,27 @@ +.. _highlight: bash + +About +===== + +Our goal is to provide an automated migration for TYPO3 updates. + +This should include source code modifications like adjusting old legacy class names to new ones. + +Requirements +============ + +- ``composer`` needs to be installed and inside your ``$PATH``. + +Installation +============ + +Run:: + + make install + +Copy the ``vendor/composer/autoload_classaliasmap.php`` generated by ``composer`` in your TYPO3 installation to ``LegacyClassnames.php`` in the root of this project. + +Usage +===== + +Will follow. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..896e5ec --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "siepmann/typo3_update", + "description": "Auto migrate PHP Source of extensions to be compatible.", + "type": "project", + "autoload": { + "psr-4": { + "Typo3Update\\": "src/Classes/" + } + }, + "require-dev": { + "psy/psysh": "~0.8" + }, + "require": { + "squizlabs/php_codesniffer_tests": "^2.0" + }, + "license": "GPL-2.0+", + "authors": [ + { + "name": "Daniel Siepmann", + "email": "coding@daniel-siepmann.de" + } + ] +} diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php new file mode 100644 index 0000000..2eec4fc --- /dev/null +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -0,0 +1,116 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * This sniff detects old, legacy class names like t3lib_div. + * Also it will make them fixable and migrate them to new ones. + */ +class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff +{ + /** + * Contains mapping from old -> new class names. + * @var array + */ + protected $legacyClassnames = []; + + /** + * @param string $mappingFile File containing php array for mapping. + */ + public function __construct($mappingFile = __DIR__ . '/../../../../../LegacyClassnames.php') + { + $legacyClassnames = require $mappingFile; + $this->legacyClassnames = $legacyClassnames['aliasToClassNameMapping']; + } + + /** + * Returns the token types that this sniff is interested in. + * + * @see http://php.net/manual/en/tokens.php + * + * @return array(int) + */ + public function register() + { + return [ + // T_USE, + // T_NEW, + // T_INSTANCEOF, + T_IMPLEMENTS, + // T_EXTENDS, + // T_STRING, + ]; + } + + /** + * Processes the tokens that this sniff is interested in. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. + * @param int $stackPtr The position in the stack where + * the token was found. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); + $classname = $tokens[$classnamePosition]['content']; + + if ($this->isLegacyClassname($classname)) { + $fix = $phpcsFile->addFixableError( + 'Legacy classes are not allowed; found %s', + $classnamePosition, + 'legacyClassname', + [$classname] + ); + + if ($fix === true) { + switch ($tokens[$stackPtr]['code']) { + case T_IMPLEMENTS: + $phpcsFile->fixer->replaceToken($classnamePosition, $this->getNewClassname($classname)); + break; + + default: + + break; + } + } + } + } + + /** + * @param string $classname + * @return bool + */ + protected function isLegacyClassname($classname) + { + return isset($this->legacyClassnames[strtolower($classname)]); + } + + /** + * @param string $classname + * @return string + */ + protected function getNewClassname($classname) + { + return $this->legacyClassnames[strtolower($classname)]; + } +} diff --git a/src/Standards/Typo3Update/ruleset.xml b/src/Standards/Typo3Update/ruleset.xml new file mode 100644 index 0000000..b44e6e2 --- /dev/null +++ b/src/Standards/Typo3Update/ruleset.xml @@ -0,0 +1,4 @@ + + + Provides sniffs and fixes for TYPO3 Updates. + From 1aaf0e58401080dba64f233f15307e5bdbdccbda Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 12:04:01 +0100 Subject: [PATCH 2/6] BUGFIX: Prefix classes with slash to prevent issues * As we might be in a namespace, we have to prefix new class names with a leading slash --- src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php index 2eec4fc..0fe1b39 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -85,7 +85,7 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff if ($fix === true) { switch ($tokens[$stackPtr]['code']) { case T_IMPLEMENTS: - $phpcsFile->fixer->replaceToken($classnamePosition, $this->getNewClassname($classname)); + $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); break; default: From f912313da39c463c2b9cfcd8228d5af14bf5f447 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 12:05:50 +0100 Subject: [PATCH 3/6] FEATURE: Also migrate legacy classes in extends * Migrate legacy classes after extends keyword. * Sort token types alphabetical. --- .../Typo3Update/Sniffs/Legacy/ClassnamesSniff.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php index 0fe1b39..16cc3d2 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -50,12 +50,12 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff public function register() { return [ - // T_USE, - // T_NEW, - // T_INSTANCEOF, + T_EXTENDS, T_IMPLEMENTS, - // T_EXTENDS, + // T_INSTANCEOF, + // T_NEW, // T_STRING, + // T_USE, ]; } @@ -84,6 +84,7 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff if ($fix === true) { switch ($tokens[$stackPtr]['code']) { + case T_EXTENDS: case T_IMPLEMENTS: $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); break; From 4fe1287247ce20cf31e41f7eda69eb0678782732 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 13:41:36 +0100 Subject: [PATCH 4/6] TASK: Fix Scrutinizer issues --- src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php index 16cc3d2..2cf11d0 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -45,7 +45,7 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff * * @see http://php.net/manual/en/tokens.php * - * @return array(int) + * @return array */ public function register() { @@ -74,6 +74,10 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); $classname = $tokens[$classnamePosition]['content']; + if ($classnamePosition === false) { + return; + } + if ($this->isLegacyClassname($classname)) { $fix = $phpcsFile->addFixableError( 'Legacy classes are not allowed; found %s', From 8d8a8cc3309962d50c1efe3b508de32a800377b2 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 13:52:40 +0100 Subject: [PATCH 5/6] TASK: Adjust flow * Reduce indentation by introducing guards to code. --- .../Sniffs/Legacy/ClassnamesSniff.php | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php index 2cf11d0..bae9950 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -72,32 +72,35 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff { $tokens = $phpcsFile->getTokens(); $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); - $classname = $tokens[$classnamePosition]['content']; - if ($classnamePosition === false) { return; } + $classname = $tokens[$classnamePosition]['content']; - if ($this->isLegacyClassname($classname)) { - $fix = $phpcsFile->addFixableError( - 'Legacy classes are not allowed; found %s', - $classnamePosition, - 'legacyClassname', - [$classname] - ); + if ($this->isLegacyClassname($classname) === false) { + return; + } - if ($fix === true) { - switch ($tokens[$stackPtr]['code']) { - case T_EXTENDS: - case T_IMPLEMENTS: - $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); - break; + $fix = $phpcsFile->addFixableError( + 'Legacy classes are not allowed; found %s', + $classnamePosition, + 'legacyClassname', + [$classname] + ); - default: + if ($fix === false) { + return; + } - break; - } - } + switch ($tokens[$stackPtr]['code']) { + case T_EXTENDS: + case T_IMPLEMENTS: + $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); + break; + + default: + + break; } } From eab9d0c99998639a13ec847960f9e840e32136e6 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 13:58:50 +0100 Subject: [PATCH 6/6] TASK: Fix PR issue, add exception if type could not be fixed --- src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php index bae9950..d9993ae 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -99,7 +99,7 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff break; default: - + throw new \RuntimeException('Could not fix type "' . $tokens[$stackPtr]['type'] . '"', 1488891438); break; } }