diff --git a/composer.json b/composer.json index 9f99a83a..fa6c8222 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "php": "^8.1", "cakephp/console": "^5.1.5", "nette/utils": "^4.0", - "rector/rector": "~2.0.0", + "rector/rector": "^2.0.17", + "symfony/process": "^6.0 || ^7.0", "symfony/string": "^6.0 || ^7.0" }, "autoload": { diff --git a/config/rector/sets/cakephp60.php b/config/rector/sets/cakephp60.php index 9800a76c..0d0c7f9f 100644 --- a/config/rector/sets/cakephp60.php +++ b/config/rector/sets/cakephp60.php @@ -27,82 +27,46 @@ 'accessibleFields' => 'patchableFields', ]); + $staticReturnTypeMap = [ + 'Cake\Console\BaseCommand' => ['setName'], + 'Cake\Controller\Controller' => [ + 'setName', 'setPlugin', 'enableAutoRender', 'disableAutoRender', 'addViewClasses', + ], + 'Cake\Core\BasePlugin' => ['enable', 'disable'], + 'Cake\Core\PluginApplicationInterface' => ['addPlugin'], + 'Cake\Core\PluginInterface' => ['enable', 'disable'], + 'Cake\Database\TypedResultInterface' => ['setReturnType'], + 'Cake\Datasource\EntityInterface' => [ + 'setHidden', 'setVirtual', 'setDirty', 'setErrors', 'setError', 'setAccess', + 'setPatchable', 'setSource', 'set', 'unset', 'setNew', + ], + 'Cake\Datasource\InvalidPropertyInterface' => ['setInvalid', 'setInvalidField'], + 'Cake\Datasource\RepositoryInterface' => ['setAlias', 'setRegistryAlias'], + 'Cake\Event\EventInterface' => ['setResult', 'setData'], + 'Cake\Form\Form' => ['setSchema', 'setErrors', 'set', 'setData'], + 'Cake\Http\BaseApplication' => ['addPlugin', 'addOptionalPlugin'], + 'Cake\Mailer\Mailer' => ['setRenderer', 'setViewVars', 'render', 'setProfile', 'restore', 'reset'], + 'Cake\ORM\Behavior\Translate\TranslateStrategyInterface' => ['setLocale'], + 'Cake\ORM\Locator\LocatorInterface' => ['setConfig'], + 'Cake\ORM\Table' => [ + 'setTable', 'setAlias', 'setRegistryAlias', 'setConnection', 'setSchema', + 'setPrimaryKey', 'setDisplayField', 'setEntityClass', 'addBehavior', + 'addBehaviors', 'removeBehavior', 'addAssociations', + 'setRequest', 'setResponse', 'setTemplatePath', + 'enableAutoLayout', 'disableAutoLayout', 'setTheme', 'setTemplate', + 'set', 'start', 'append', 'assign', 'reset', 'end', 'extend', + 'loadHelpers', 'setPlugin', 'setElementCache', + ], + ]; + // For cakephp/cakephp#18115 - $rectorConfig->ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ - new AddReturnTypeDeclaration('Cake\Console\BaseCommand', 'setName', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Controller\Controller', 'setName', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Controller\Controller', 'setPlugin', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Controller\Controller', 'enableAutoRender', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Controller\Controller', 'disableAutoRender', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Controller\Controller', 'addViewClasses', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\BasePlugin', 'enable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\BasePlugin', 'disable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\PluginApplicationInterface', 'addPlugin', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\PluginInterface', 'disable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\PluginInterface', 'enable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Core\PluginInterface', 'enable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Database\TypedResultInterface', 'setReturnType', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setHidden', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setVirtual', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setDirty', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setErrors', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setError', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setAccess', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setPatchable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setSource', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'set', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'unset', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\EntityInterface', 'setNew', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\InvalidPropertyInterface', 'setInvalid', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\InvalidPropertyInterface', 'setInvalidField', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\RepositoryInterface', 'setAlias', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Datasource\RepositoryInterface', 'setRegistryAlias', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Event\EventInterface', 'setResult', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Event\EventInterface', 'setData', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Form\Form', 'setSchema', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Form\Form', 'setErrors', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Form\Form', 'set', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Form\Form', 'setData', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Http\BaseApplication', 'addPlugin', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Http\BaseApplication', 'addOptionalPlugin', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'setRenderer', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'setViewVars', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'render', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'setProfile', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'restore', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\Mailer\Mailer', 'reset', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Behavior\Translate\TranslateStrategyInterface', 'setLocale', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Locator\LocatorInterface', 'setConfig', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setTable', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setAlias', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setRegistryAlias', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setConnection', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setSchema', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setPrimaryKey', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setDisplayField', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'setEntityClass', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'addBehavior', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'addBehaviors', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'removeBehavior', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\ORM\Table', 'addAssociations', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setRequest', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setResponse', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setTemplatePath', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'enableAutoLayout', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'disableAutoLayout', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setTheme', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setTemplate', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'set', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'start', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'append', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'assign', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'reset', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'end', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'extend', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'loadHelpers', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setPlugin', new SimpleStaticType('')), - new AddReturnTypeDeclaration('Cake\View\View', 'setElementCache', new SimpleStaticType('')), - ]); + foreach ($staticReturnTypeMap as $className => $methods) { + foreach ($methods as $method) { + $rectorConfig->ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ + new AddReturnTypeDeclaration($className, $method, new SimpleStaticType($className)), + ]); + } + } // ===== Remove underscores from method names ===== @@ -116,6 +80,447 @@ '_connect', '_connectTransient', '_connectPersistent', '_createRedisInstance', ], ], + 'Collection' => [ + // _extract can't be easily renamed to extract as it conflicts with the CollectionTrait::extract() method + 'Cake\Collection\ExtractTrait' => [ + '_propertyExtractor', '_simpleExtract', '_createMatcherFilter', + ], + 'Cake\Collection\Iterator\MapReduce' => ['_execute'], + 'Cake\Collection\Iterator\TreePrinter' => ['_fetchCurrent'], + ], + 'Command' => [ + 'Cake\Command\Helper\TreeHelper' => [ + '_calculateWidths', '_cellWidth', '_rowSeparator', '_render', '_addStyle', + ], + 'Cake\Command\Helper\TableHelper' => [ + '_calculateWidths', '_cellWidth', '_rowSeparator', '_render', '_addStyle', + ], + 'Cake\Command\RoutesGenerateCommand' => ['_splitArgs'], + 'Cake\Command\I18nExtractCommand' => [ + '_getPaths', '_addTranslation', '_extract', '_extractTokens', '_parse', + '_buildFiles', '_store', '_writeFiles', '_writeHeader', '_getStrings', + '_formatString', '_markerError', '_searchFiles', '_isExtractingApp', '_isPathUsable', + ], + 'Cake\Command\PluginAssetsTrait' => [ + '_list', '_process', '_remove', '_createDirectory', + '_createSymlink', '_makeRelativePath', '_copyDirectory', + ], + ], + 'Console' => [ + 'Cake\Console\HelpFormatter' => ['_generateUsage', '_getMaxLength'], + 'Cake\Console\ConsoleIo' => ['_getInput'], + // _write can't be renamed to write as it conflicts with the ConsoleOutput::write() method + 'Cake\Console\ConsoleOutput' => ['_replaceTags'], + 'Cake\Console\ConsoleOptionParser' => [ + '_parseLongOption', '_parseShortOption', '_parseOption', '_optionExists', '_parseArg', '_nextToken', + ], + ], + 'Controller' => [ + 'Cake\Controller\Component\FormProtectionComponent' => ['_getSessionId'], + 'Cake\Controller\Controller' => ['_templatePath'], + ], + 'Core' => [ + 'Cake\Core\App' => ['_classExistsInBase'], + 'Cake\Core\Configure' => ['_getEngine'], + 'Cake\Core\Configure\Engine\IniConfig' => ['_parseNestedValues', '_value'], + 'Cake\Core\ObjectRegistry' => [ + '_checkDuplicate', '_resolveClassName', '_throwMissingClassError', '_create', + ], + 'Cake\Core\ConventionsTrait' => [ + '_fixtureName', '_entityName', '_modelKey', '_modelNameFromKey', + '_singularName', '_variableName', '_singularHumanName', '_camelize', + '_pluralHumanName', '_pluginPath', '_pluginNamespace', + ], + 'Cake\Core\Configure\FileConfigTrait' => ['_getFilePath'], + 'Cake\Core\InstanceConfigTrait' => ['_configRead', '_configWrite', '_configDelete'], + ], + 'Database' => [ + 'Cake\Database\IdentifierQuoter' => [ + '_quoteParts', '_basicQuoter', + '_quoteJoins', '_quoteSelect', + '_quoteDelete', '_quoteInsert', + '_quoteUpdate', '_quoteComparison', + '_quoteOrderBy', '_quoteIdentifierExpression', + ], + 'Cake\Database\Query' => [ + '_makeJoin', '_expressionsVisitor', '_conjugate', '_dirty', + ], + + // Expressions + 'Cake\Database\Expression\BetweenExpression' => ['_bindValue'], + 'Cake\Database\Expression\ComparisonExpression' => [ + '_stringExpression', '_bindValue', '_flattenValue', '_collectExpressions', + ], + 'Cake\Database\Expression\TupleComparison' => ['_stringifyValues', '_traverseValue'], + 'Cake\Database\Expression\QueryExpression' => [ + '_addConditions', '_parseCondition', '_calculateType', + ], + 'Cake\Database\Expression\ValuesExpression' => ['_columnNames', '_processExpressions'], + + // Drivers + 'Cake\Database\Driver' => [ + '_expressionTranslators', '_selectQueryTranslator', + '_transformDistinct', '_deleteQueryTranslator', + '_updateQueryTranslator', '_removeAliasesFromConditions', + '_insertQueryTranslator', + ], + 'Cake\Database\Driver\Postgres' => [ + '_transformIdentifierExpression', '_transformFunctionExpression', + '_transformStringExpression', + ], + 'Cake\Database\Driver\Sqlite' => ['_transformFunctionExpression'], + 'Cake\Database\Driver\Sqlserver' => [ + '_pagingSubquery', '_transformFunctionExpression', + ], + 'Cake\Database\Driver\TupleComparisonTranslatorTrait' => [ + '_transformTupleComparison', + ], + + // Compilers + 'Cake\Database\QueryCompiler' => [ + '_sqlCompiler', '_buildWithPart', '_buildSelectPart', + '_buildFromPart', '_buildJoinPart', '_buildWindowPart', + '_buildSetPart', '_buildSetOperationPart', + '_buildIntersectPart', '_buildUnionPart', '_buildInsertPart', + '_buildValuesPart', '_buildUpdatePart', '_buildModifierPart', + '_stringifyExpressions', + ], + 'Cake\Database\PostgresCompiler' => ['_buildHavingPart'], + 'Cake\Database\SqlserverCompiler' => ['_buildLimitPart', '_buildHavingPart'], + + // Types + 'Cake\Database\Type\ExpressionTypeCasterTrait' => ['_castToExpression', '_requiresToExpressionCasting'], + 'Cake\Database\Type\FloatType' => ['_parseValue'], + 'Cake\Database\Type\DateType' => ['_parseValue', '_parseLocaleValue'], + 'Cake\Database\Type\DateTimeType' => ['_parseValue', '_parseLocaleValue'], + 'Cake\Database\Type\DecimalType' => ['_parseValue', '_parseLocaleValue'], + 'Cake\Database\Type\TimeType' => ['_parseTimeValue', '_parseLocalTimeValue'], + + // Schema + 'Cake\Database\Schema\TableSchema' => ['_checkForeignKey'], + 'Cake\Database\Schema\SchemaDialect' => [ + '_foreignOnClause', '_convertOnClause', '_convertConstraintColumns', + '_getTypeSpecificColumnSql', '_applyTypeSpecificColumnConversion', + ], + 'Cake\Database\Schema\SqliteSchemaDialect' => [ + '_convertColumn', '_defaultValue', + ], + 'Cake\Database\Schema\SqlserverSchemaDialect' => [ + '_convertColumn', '_defaultValue', '_keySql', + ], + 'Cake\Database\Schema\MysqlSchemaDialect' => [ + '_convertColumn', '_keySql', + ], + 'Cake\Database\Schema\PostgresSchemaDialect' => [ + '_convertColumn', '_keySql', '_defaultValue', '_convertConstraint', + ], + ], + + 'Datasource' => [ + 'Cake\Datasource\QueryCacher' => ['_resolveKey', '_resolveCacher'], + 'Cake\Datasource\EntityTrait' => [ + '_accessor', '_nestedErrors', '_readHasErrors', '_readError', + ], + 'Cake\Datasource\ModelAwareTrait' => ['_setModelClass'], + 'Cake\Datasource\Paging\NumericPaginator' => ['_removeAliases', '_prefix'], + 'Cake\Datasource\RulesChecker' => ['_checkRules', '_addError'], + ], + + 'Error' => [ + 'Cake\Error\Renderer\WebExceptionRenderer' => [ + '_getController', '_customMethod', '_method', + '_message', '_template', '_outputMessage', + '_outputMessageSafe', '_shutdown', + ], + 'Cake\Error\Debugger' => ['_highlight'], + ], + + 'Event' => [ + 'Cake\Event\Decorator\AbstractDecorator' => ['_call'], + 'Cake\Event\Decorator\ConditionDecorator' => ['_evaluateCondition'], + 'Cake\Event\EventManager' => [ + '_attachSubscriber', '_detachSubscriber', '_callListener', + ], + ], + + 'Form' => [ + // Can't rename _execute as it conflicts with the Form::execute() method + 'Cake\Form\Form' => ['_buildSchema'], + 'Cake\Form\Schema' => ['_addField'], + ], + + 'Http' => [ + 'Cake\Http\CorsBuilder' => ['_normalizeDomains'], + 'Cake\Http\Session' => ['_defaultConfig', '_overwrite', '_hasSession', '_timedOut'], + // Can't rename _sendRequest as it conflicts with the Client::sendRequest() method + 'Cake\Http\Client' => [ + '_doRequest', '_mergeOptions', '_createRequest', '_typeHeaders', + '_addAuthentication', '_addProxy', '_createAuth', + ], + + // Can't rename _is as it conflicts with the ServerRequest::is() method + 'Cake\Http\ServerRequest' => [ + '_setConfig', '_acceptHeaderDetector', '_headerDetector', + '_paramDetector', '_environmentDetector', + ], + + 'Cake\Http\Response' => [ + '_createStream', '_setContentType', '_setHeader', '_clearHeader', + '_setStatus', '_setCacheControl', '_getUTCDate', '_fileRange', + ], + + 'Cake\Http\Cookie\Cookie' => ['_setValue', '_flatten', '_expand'], + + // Can't rename _getHeaders as it conflicts with the MessageTrait::getHeaders() method + // Can't rename _getBody as it conflicts with the MessageTrait::getBody() method + // Can't rename _getCookies as it conflicts with the Response::getCookies() method + // Can't rename _getJson as it conflicts with the Response::getJson() method + // Can't rename _getXml as it conflicts with the Response::getXml() method + 'Cake\Http\Client\Response' => [ + '_decodeGzipBody', '_parseHeaders', + ], + + 'Cake\Http\Client\FormDataPart' => ['_headerParameterToString'], + 'Cake\Http\Client\Auth\Basic' => ['_generateHeader'], + 'Cake\Http\Client\Auth\Digest' => ['_generateHeader', '_getServerInfo'], + 'Cake\Http\Client\Auth\Oauth' => [ + '_plaintext', '_hmacSha1', '_rsaSha1', '_normalizedUrl', + '_normalizedParams', '_normalizeData', '_buildAuth', + '_encode', + ], + + // Can't rename _send as it conflicts with the Stream::send() method + 'Cake\Http\Client\Adapter\Stream' => [ + '_buildContext', '_buildHeaders', '_buildContent', '_buildOptions', + '_buildSslContext', '_buildResponse', '_open', + ], + + 'Cake\Http\Middleware\CsrfProtectionMiddleware' => [ + '_unsetTokenField', '_verifyToken', '_addTokenCookie', + '_validateToken', '_createCookie', + ], + ], + + 'I18n' => [ + // Can't rename _parseDateTime as it conflicts with the DateTime::parseDateTime() method + 'Cake\I18n\DateFormatTrait' => ['_formatObject'], + 'Cake\I18n\Number' => ['_setAttributes'], + 'Cake\I18n\RelativeTimeFormatter' => ['_options', '_diffData'], + 'Cake\I18n\TranslatorRegistry' => ['_getTranslator'], + 'Cake\I18n\Parser\MoFileParser' => ['_readLong'], + 'Cake\I18n\Parser\PoFileParser' => ['_addMessage'], + ], + + 'Log' => [ + 'Cake\Log\Engine\FileLog' => ['_getFilename', '_rotateFile'], + 'Cake\Log\Engine\SyslogLog' => ['_open', '_write'], + ], + + 'Mailer' => [ + 'Cake\Mailer\TransportFactory' => ['_buildTransport'], + 'Cake\Mailer\Transport\MailTransport' => ['_mail'], + // Can't rename _connect as it conflicts with the SmtpTransport::connect() method + // Can't rename _disconnect as it conflicts with the SmtpTransport::disconnect() method + 'Cake\Mailer\Transport\SmtpTransport' => [ + '_bufferResponseLines', '_parseAuthType', + '_auth', '_authPlain', '_authLogin', '_authXoauth2', + '_prepareFromCmd', '_prepareRcptCmd', '_prepareFromAddress', + '_prepareRecipientAddresses', '_prepareMessage', + '_sendRcpt', '_sendData', '_generateSocket', '_smtpSend', + ], + ], + + 'Network' => [ + 'Cake\Network\Socket' => ['_getStreamSocketClient', '_setSslContext', '_connectionErrorHandler'], + ], + + 'ORM' => [ + 'Cake\ORM\AssociationsNormalizerTrait' => ['_normalizeAssociations'], + 'Cake\ORM\AssociationCollection' => ['_saveAssociations', '_save'], + 'Cake\ORM\EagerLoader' => [ + '_reformatContain', '_normalizeContain', '_fixStrategies', + '_correctStrategy', '_resolveJoins', '_buildAssociationsMap', + '_collectKeys', '_groupKeys', + ], + 'Cake\ORM\LazyEagerLoader' => ['_getQuery', '_getPropertyMap', '_injectResults'], + 'Cake\ORM\Marshaller' => [ + '_buildPropertyMap', '_validate', '_prepareDataAndOptions', '_marshalAssociation', + '_belongsToMany', '_loadAssociatedByIds', '_mergeAssociation', '_mergeBelongsToMany', + '_mergeJoinData', + ], + 'Cake\ORM\Table' => [ + // Can't rename _saveMany as it conflicts with the Table::saveMany() method + // Can't rename _deleteMany as it conflicts with the Table::deleteMany() method + '_setFieldMatchers', '_executeTransaction', '_transactionCommitted', + '_processFindOrCreate', '_getFindOrCreateQuery', '_processSave', + '_onSaveSuccess', '_insert', '_newId', '_update', '_processDelete', '_dynamicFinder', + ], + + // Behaviors + 'Cake\ORM\Behavior' => ['_resolveMethodAliases', '_reflectionCache'], + 'Cake\ORM\Behavior\TreeBehavior' => [ + // Can't rename _moveUp/_moveDown as it conflicts with the TreeBehavior::moveUp()/moveDown() methods + // Can't rename _removeFromTree as it conflicts with the TreeBehavior::removeFromTree() method + '_setChildrenLevel', '_setParent', '_setAsRoot', '_unmarkInternalTree', + '_getNode', '_recoverTree', '_getMax', '_sync', '_scope', '_ensureFields', '_getPrimaryKey', + ], + 'Cake\ORM\Behavior\CounterCacheBehavior' => [ + '_processAssociations', '_processAssociation', '_shouldUpdateCount', '_getCount', + ], + 'Cake\ORM\Behavior\TimestampBehavior' => ['_updateField'], + + // Associations + 'Cake\ORM\Association' => [ + '_propertyName', '_options', '_appendNotMatching', + '_dispatchBeforeFind', '_appendFields', '_formatAssociationResults', + '_bindNewAssociations', '_joinCondition', '_extractFinder', + ], + 'Cake\ORM\Association\HasMany' => [ + // Can't rename _unlink as it conflicts with the HasMany::unlink() method + '_saveTarget', '_unlinkAssociated', '_foreignKeyAcceptsNull', + ], + 'Cake\ORM\Association\BelongsToMany' => [ + '_generateTargetAssociations', '_generateSourceAssociations', + '_generateJunctionAssociations', '_saveTarget', '_saveLinks', + '_appendJunctionJoin', '_diffLinks', '_checkPersistenceStatus', + '_collectJointEntities', '_junctionAssociationName', '_junctionTableName', + ], + + // Loaders + 'Cake\ORM\Association\Loader\SelectLoader' => [ + '_defaultOptions', '_buildQuery', '_extractFinder', + '_assertFieldsPresent', '_addFilteringJoin', '_addFilteringCondition', + '_createTupleCondition', '_linkField', '_buildSubquery', + '_subqueryFields', '_buildResultMap', '_resultInjector', + '_multiKeysInjector', + ], + + // Locators + 'Cake\ORM\Locator\TableLocator' => ['_getClassName', '_create'], + + // Query + 'Cake\ORM\Query\SelectQuery' => [ + // Can't rename _decorateResults as it conflicts with the DB\SelectQuery::decorateResults() method + // Can't rename _execute as it conflicts with the DB\Query::execute() method + '_dirty', '_addAssociationsToTypeMap', + '_performCount', '_transformQuery', + '_addDefaultFields', '_addDefaultSelectTypes', + ], + + // Rules + 'Cake\ORM\RulesChecker' => ['_addLinkConstraintRule', '_addError'], + 'Cake\ORM\Rule\LinkConstraint' => ['_aliasFields', '_buildConditions', '_countLinks'], + 'Cake\ORM\Rule\IsUnique' => ['_alias'], + 'Cake\ORM\Rule\ExistsIn' => ['_fieldsAreNull'], + + ], + + 'Routing' => [ + 'Cake\Routing\Router' => ['_methodRoute', '_makeRoute', '_applyUrlFilters'], + 'Cake\Routing\RouteBuilder' => ['_methodRoute', '_makeRoute'], + 'Cake\Routing\RouteCollection' => ['_getNames'], + 'Cake\Routing\Route\Route' => [ + '_writeRoute', '_parseExtension', '_parseArgs', + '_persistParams', '_matchMethod', '_writeUrl', + ], + 'Cake\Routing\Route\DashedRoute' => ['_camelizePlugin' ,'_dasherize'], + 'Cake\Routing\Route\EntityRoute' => ['_checkEntity'], + 'Cake\Routing\Route\InflectedRoute' => ['_underscore'], + 'Cake\Routing\Middleware\AssetMiddleware' => ['_getAssetFile'], + ], + + 'TestSuite' => [ + 'Cake\TestSuite\IntegrationTestTrait' => [ + '_sendRequest', '_makeDispatcher', '_handleError', + '_buildRequest', '_addTokens', '_castToString', + '_url', '_getBodyAsString', + ], + 'Cake\TestSuite\MiddlewareDispatcher' => ['_createRequest'], + 'Cake\TestSuite\TestCase' => ['_assertAttributes', '_normalizePath', '_getTableClassName'], + 'Cake\TestSuite\Fixture\TestFixture' => ['_tableFromClass', '_schemaFromReflection', '_getRecords'], + 'Cake\TestSuite\Constraint\Response\ResponseBase' => ['_getBodyAsString'], + 'Cake\TestSuite\LogTestTrait' => ['_expectLogMessage'], + ], + + 'Utility' => [ + 'Cake\Utility\CookieCryptTrait' => [ + '_getCookieEncryptionKey', '_encrypt', '_checkCipher', + '_decrypt', '_decode', '_implode', '_explode', + ], + 'Cake\Utility\Hash' => [ + // Can't rename _filter as it conflicts with the Hash::filter() method + // Can't rename _merge as it conflicts with the Hash::merge() method + '_splitConditions', '_matchToken', '_matches', '_simpleOp', '_squash', + ], + // Can't rename _wordWrap as it conflicts with the Text::wordWrap() method + 'Cake\Utility\Text' => ['_strlen', '_substr', '_removeLastWord'], + // Can't rename _fromArray as it conflicts with the Xml::fromArray() method + // Can't rename _toArray as it conflicts with the Xml::toArray() method + 'Cake\Utility\Xml' => ['_loadXml', '_createChild'], + 'Cake\Utility\MergeVariablesTrait' => ['_mergeVars', '_mergeProperty', '_mergePropertyData'], + 'Cake\Utility\Inflector' => ['_cache'], + 'Cake\Utility\Security' => ['_checkKey'], + ], + + 'Validation' => [ + 'Cake\Validation\ValidationRule' => ['_skip'], + 'Cake\Validation\Validation' => ['_check', '_getDateString', '_populateIp', '_reset'], + 'Cake\Validation\Validator' => [ + '_convertValidatorToArray', '_checkPresence', '_canBeEmpty', '_processRules', + ], + ], + + 'View' => [ + 'Cake\View\View' => [ + // Can't rename _render as it conflicts with the View::render() method + '_evaluate', '_getTemplateFileName', '_inflectTemplateFileName', + '_checkFilePath', '_getLayoutFileName', '_getElementFileName', '_getSubPaths', + '_paths', '_elementCache', '_renderElement', + ], + 'Cake\View\Cell' => ['_cacheConfig'], + 'Cake\View\CellTrait' => ['_createCell'], + 'Cake\View\ViewBuilder' => ['_checkViewVars'], + 'Cake\View\JsonView' => ['_dataToSerialize'], + 'Cake\View\SerializedView' => ['_serialize'], + 'Cake\View\StringTemplate' => ['_compileTemplates', '_formatAttribute'], + + // Helpers + 'Cake\View\Helper' => ['_confirm'], + 'Cake\View\Helper\FormHelper' => [ + '_formUrl', '_lastAction', '_csrfField', '_getFormProtectorSessionId', + '_groupTemplate', '_inputContainerTemplate', '_getInput', '_parseOptions', + '_inputType', '_optionsOptions', '_magicOptions', '_getLabel', + '_extractOption', '_inputLabel', '_initInputField', '_isDisabled', '_getContext', + ], + 'Cake\View\Helper\HtmlHelper' => ['_renderCells', '_nestedListItem'], + 'Cake\View\Helper\PaginatorHelper' => [ + // Can't rename _numbers as it conflicts with the PaginatorHelper::numbers() method + '_toggledLink', '_removeAlias', '_getNumbersStartAndEnd', '_formatNumber', + '_modulusNumbers', '_firstNumber', '_lastNumber', + ], + 'Cake\View\Helper\TextHelper' => [ + '_insertPlaceHolder', '_linkUrls', '_prepareLinkLabel', '_linkEmails', + ], + 'Cake\View\Helper\TimeHelper' => ['_getTimezone'], + 'Cake\View\Helper\IdGeneratorTrait' => ['_clearIds', '_id', '_idSuffix', '_domId'], + + // Form Context + 'Cake\View\Form\EntityContext' => [ + '_prepare', '_schemaDefault', '_extractMultiple', + '_getProp', '_getValidator', '_getTable', + ], + 'Cake\View\Form\FormContext' => ['_schemaDefault'], + + // Widgets + 'Cake\View\Widget\SelectBoxWidget' => [ + '_renderContent', '_emptyValue', '_renderOptgroup', + '_renderOptions', '_isSelected', '_isDisabled', + ], + 'Cake\View\Widget\MultiCheckboxWidget' => ['_renderInputs', '_renderInput', '_isSelected', '_isDisabled'], + 'Cake\View\Widget\RadioWidget' => ['_renderInput', '_renderLabel', '_isDisabled'], + 'Cake\View\Widget\CheckboxWidget' => ['_isChecked'], + 'Cake\View\Widget\WidgetLocator' => ['_resolveWidget'], + ], ]; foreach ($map as $definitions) { diff --git a/src/Command/RectorCommand.php b/src/Command/RectorCommand.php index 60159cc5..ea245cb8 100644 --- a/src/Command/RectorCommand.php +++ b/src/Command/RectorCommand.php @@ -20,6 +20,7 @@ use Cake\Console\BaseCommand; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; +use Symfony\Component\Process\Process; /** * Runs rector rulesets against the provided path. @@ -59,11 +60,11 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $result = $this->runRector($io, $args, $autoload); if ($result === false) { - $io->error('Could not run rector. Ensure that `php` is on your PATH.'); + $io->error('Something went wrong while running rector. Ensure that `php` is on your PATH.'); return static::CODE_ERROR; } - $io->success('Rector applied successfully'); + $io->success('🎉 Upgrade complete! 🎉'); return static::CODE_SUCCESS; } @@ -93,39 +94,28 @@ protected function runRector(ConsoleIo $io, Arguments $args, string $autoload): ); $io->verbose("Running {$command}"); - $descriptorSpec = [ - 0 => ['pipe', 'r'], - 1 => ['pipe', 'w'], - 2 => ['pipe', 'w'], - ]; - $process = proc_open( - $command, - $descriptorSpec, - $pipes, - ); - if (!is_resource($process)) { - $io->error('Could not create rector process'); + $io->info('Starting rector at ' . date('Y-m-d H:i:s')); - return false; - } + $process = Process::fromShellCommandline($command); + $process->setEnv($_ENV); + $process->setTimeout(null); + $process->start(); - while (true) { - if (feof($pipes[1]) && feof($pipes[2])) { - break; - } - $output = fread($pipes[1], 1024); - if ($output) { - $io->out($output); - } - $error = fread($pipes[2], 1024); - if ($error) { - $io->err($error); + foreach ($process as $type => $data) { + if ($type === Process::OUT) { + $io->out($data); + } elseif ($type === Process::ERR) { + $io->err($data); } } - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); + if (!$process->isSuccessful()) { + $io->error('Something went wrong while running rector.'); + + return false; + } + + $io->info('Rector completed successfully at ' . date('Y-m-d H:i:s')); return true; } diff --git a/tests/TestCase/Command/RectorCommandTest.php b/tests/TestCase/Command/RectorCommandTest.php index e9c9ad93..dba84d20 100644 --- a/tests/TestCase/Command/RectorCommandTest.php +++ b/tests/TestCase/Command/RectorCommandTest.php @@ -62,10 +62,9 @@ public function testApplyAppDir() $this->setupTestApp(__FUNCTION__); $this->exec('upgrade rector --rules cakephp40 --dry-run ' . TEST_APP); - $this->assertExitSuccess(); + $this->assertExitError(); // --dry-run inverts the exit code $this->assertOutputContains('HelloCommand.php'); $this->assertOutputContains('begin diff'); - $this->assertOutputContains('Rector applied successfully'); } /**