Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions .github/workflows/infection.yml → .github/workflows/psalm.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Infection
name: Psalm

on:
pull_request:
Expand All @@ -7,43 +7,41 @@ on:
paths:
- '**.php'
- 'composer.*'
- 'phpunit*'
- '.github/workflows/infection.yml'
- 'psalm*'
- '.github/workflows/psalm.yml'
push:
branches:
- develop
paths:
- '**.php'
- 'composer.*'
- 'phpunit*'
- '.github/workflows/infection.yml'
- 'psalm*'
- '.github/workflows/psalm.yml'

jobs:
main:
name: Mutation Testing
build:
name: PHP ${{ matrix.php-versions }} Psalm Analysis
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]')"
strategy:
fail-fast: false
matrix:
php-versions: ['7.4', '8.0', '8.1']

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set up PHP
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
tools: infection, phpunit
extensions: intl, json, mbstring, gd, xml, sqlite3
coverage: xdebug
php-version: ${{ matrix.php-versions }}
tools: phpstan, phpunit
extensions: intl, json, mbstring, xml
coverage: none
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Set up problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

- name: Configure matchers
uses: mheap/phpunit-matcher-action@v1

- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
Expand All @@ -55,6 +53,16 @@ jobs:
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Create Psalm cache directory
run: mkdir -p build/psalm

- name: Cache Psalm results
uses: actions/cache@v3
with:
path: build/psalm
key: ${{ runner.os }}-psalm-${{ github.sha }}
restore-keys: ${{ runner.os }}-psalm-

- name: Install dependencies
run: |
if [ -f composer.lock ]; then
Expand All @@ -63,10 +71,5 @@ jobs:
composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
fi

- name: Test with PHPUnit
run: vendor/bin/phpunit --teamcity

- name: Mutate with Infection
run: |
git fetch --depth=1 origin $GITHUB_BASE_REF
infection --threads=2 --skip-initial-tests --coverage=build/phpunit --git-diff-base=origin/$GITHUB_BASE_REF --git-diff-filter=AM --logger-github --ignore-msi-with-no-mutations
- name: Run Psalm analysis
run: vendor/bin/psalm
55 changes: 24 additions & 31 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,47 +1,43 @@
{
"name": "codeigniter4/shield",
"type": "library",
"description": "Authentication and Authorization for CodeIgniter 4",
"license": "MIT",
"type": "library",
"keywords": [
"codeigniter",
"codeigniter4",
"authentication",
"authorization"
],
"homepage": "https://github.com/codeigniter4/shield",
"license": "MIT",
"authors": [
{
"name": "Lonnie Ezell",
"email": "[email protected]",
"role": "Developer"
}
],
"homepage": "https://github.com/codeigniter4/shield",
"require": {
"php": "^7.4 || ^8.0",
"codeigniter4/settings": "^2.0"
},
"provide": {
"codeigniter4/authentication-implementation": "1.0"
},
"require-dev": {
"codeigniter/coding-standard": "^1.1",
"codeigniter4/devkit": "^1.0",
"codeigniter4/framework": "^4.1",
"fakerphp/faker": "^1.9",
"friendsofphp/php-cs-fixer": "^3.0",
"mockery/mockery": "^1.0",
"nexusphp/cs-config": "^3.1",
"nexusphp/tachycardia": "^1.0",
"php-coveralls/php-coveralls": "^2.4",
"phpstan/phpstan": "^1.0",
"phpunit/phpunit": "^9.1",
"vimeo/psalm": "^4.22"
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
"provide": {
"codeigniter4/authentication-implementation": "1.0"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/codeigniter4/CodeIgniter4"
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"CodeIgniter\\Shield\\": "src"
Expand All @@ -56,23 +52,16 @@
"Tests\\Support\\": "tests/_support"
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/codeigniter4/CodeIgniter4"
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
],
"minimum-stability": "dev",
"prefer-stable": true,
},
"scripts": {
"post-update-cmd": [
"bash admin/setup.sh"
],
"analyze": "phpstan analyze",
"sa": [
"@analyze",
"psalm"
],
"ci": [
"Composer\\Config::disableProcessTimeout",
"@deduplicate",
Expand All @@ -82,11 +71,15 @@
"rector process",
"@style"
],
"cs-fix": "@style",
"deduplicate": "phpcpd app/ src/",
"inspect": "deptrac analyze --cache-file=build/deptrac.cache",
"mutate": "infection --threads=2 --skip-initial-tests --coverage=build/phpunit",
"style": "php-cs-fixer fix --ansi --verbose --diff",
"cs-fix": "@style",
"sa": [
"phpstan analyze",
"psalm"
],
"style": "php-cs-fixer fix --verbose --ansi --using-cache=no",
"test": "phpunit"
}
}
4 changes: 3 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
autoloader="psalm_autoload.php"
cacheDirectory="build/psalm/"
>
<projectFiles>
<directory name="src" />
<directory name="src/" />
<directory name="tests/" />
<ignoreFiles>
<directory name="vendor" />
<directory name="src/Views" />
Expand Down
86 changes: 37 additions & 49 deletions rector.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Rector\Config\RectorConfig;
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
use Rector\CodeQuality\Rector\For_\ForToForeachRector;
Expand All @@ -17,7 +18,6 @@
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\Core\Configuration\Option;
use Rector\Core\ValueObject\PhpVersion;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector;
use Rector\DeadCode\Rector\MethodCall\RemoveEmptyMethodCallRector;
Expand All @@ -34,47 +34,38 @@
use Rector\PSR4\Rector\FileWithoutNamespace\NormalizeNamespaceByPSR4ComposerAutoloadRector;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
// Rule sets to apply
$containerConfigurator->import(SetList::DEAD_CODE);
$containerConfigurator->import(LevelSetList::UP_TO_PHP_74);
$containerConfigurator->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD);
$containerConfigurator->import(PHPUnitSetList::PHPUNIT_80);

$parameters = $containerConfigurator->parameters();

$parameters->set(Option::PARALLEL, true);
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([SetList::DEAD_CODE, LevelSetList::UP_TO_PHP_74, PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD, PHPUnitSetList::PHPUNIT_80]);
$rectorConfig->parallel();
// The paths to refactor (can also be supplied with CLI arguments)
$parameters->set(Option::PATHS, [
$rectorConfig->paths([
__DIR__ . '/src/',
__DIR__ . '/tests/',
]);

// Include Composer's autoload - required for global execution, remove if running locally
$parameters->set(Option::AUTOLOAD_PATHS, [
$rectorConfig->autoloadPaths([
__DIR__ . '/vendor/autoload.php',
]);

// Do you need to include constants, class aliases, or a custom autoloader?
$parameters->set(Option::BOOTSTRAP_FILES, [
$rectorConfig->bootstrapFiles([
realpath(getcwd()) . '/vendor/codeigniter4/framework/system/Test/bootstrap.php',
]);

if (is_file(__DIR__ . '/phpstan.neon.dist')) {
$parameters->set(Option::PHPSTAN_FOR_RECTOR_PATH, __DIR__ . '/phpstan.neon.dist');
$rectorConfig->phpstanConfig(__DIR__ . '/phpstan.neon.dist');
}

// Set the target version for refactoring
$parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_74);
$rectorConfig->phpVersion(PhpVersion::PHP_74);

// Auto-import fully qualified class names
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
$rectorConfig->importNames();

// Are there files or rules you need to skip?
$parameters->set(Option::SKIP, [
__DIR__ . '/src/Config/Auth.php',
$rectorConfig->skip([
__DIR__ . '/src/Views',

JsonThrowOnErrorRector::class,
Expand All @@ -88,7 +79,7 @@
__DIR__ . '/tests',
],

// Ignore files that should not be namespaced
// Ignore files that should not be namespaced to their folder
NormalizeNamespaceByPSR4ComposerAutoloadRector::class => [
__DIR__ . '/src/Helpers',
__DIR__ . '/tests/_support',
Expand All @@ -100,33 +91,30 @@
// May be uninitialized on purpose
AddDefaultValueForUndefinedVariableRector::class,
]);

// Additional rules to apply
$services = $containerConfigurator->services();
$services->set(SimplifyUselessVariableRector::class);
$services->set(RemoveAlwaysElseRector::class);
$services->set(CountArrayToEmptyArrayComparisonRector::class);
$services->set(ForToForeachRector::class);
$services->set(ChangeNestedForeachIfsToEarlyContinueRector::class);
$services->set(ChangeIfElseValueAssignToEarlyReturnRector::class);
$services->set(SimplifyStrposLowerRector::class);
$services->set(CombineIfRector::class);
$services->set(SimplifyIfReturnBoolRector::class);
$services->set(InlineIfToExplicitIfRector::class);
$services->set(PreparedValueToEarlyReturnRector::class);
$services->set(ShortenElseIfRector::class);
$services->set(SimplifyIfElseToTernaryRector::class);
$services->set(UnusedForeachValueToArrayKeysRector::class);
$services->set(ChangeArrayPushToArrayAssignRector::class);
$services->set(UnnecessaryTernaryExpressionRector::class);
$services->set(AddPregQuoteDelimiterRector::class);
$services->set(SimplifyRegexPatternRector::class);
$services->set(FuncGetArgsToVariadicParamRector::class);
$services->set(MakeInheritedMethodVisibilitySameAsParentRector::class);
$services->set(SimplifyEmptyArrayCheckRector::class);
$services->set(NormalizeNamespaceByPSR4ComposerAutoloadRector::class);
$services->set(TypedPropertyRector::class)
->configure([
TypedPropertyRector::INLINE_PUBLIC => true,
$rectorConfig->rule(SimplifyUselessVariableRector::class);
$rectorConfig->rule(RemoveAlwaysElseRector::class);
$rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class);
$rectorConfig->rule(ForToForeachRector::class);
$rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class);
$rectorConfig->rule(ChangeIfElseValueAssignToEarlyReturnRector::class);
$rectorConfig->rule(SimplifyStrposLowerRector::class);
$rectorConfig->rule(CombineIfRector::class);
$rectorConfig->rule(SimplifyIfReturnBoolRector::class);
$rectorConfig->rule(InlineIfToExplicitIfRector::class);
$rectorConfig->rule(PreparedValueToEarlyReturnRector::class);
$rectorConfig->rule(ShortenElseIfRector::class);
$rectorConfig->rule(SimplifyIfElseToTernaryRector::class);
$rectorConfig->rule(UnusedForeachValueToArrayKeysRector::class);
$rectorConfig->rule(ChangeArrayPushToArrayAssignRector::class);
$rectorConfig->rule(UnnecessaryTernaryExpressionRector::class);
$rectorConfig->rule(AddPregQuoteDelimiterRector::class);
$rectorConfig->rule(SimplifyRegexPatternRector::class);
$rectorConfig->rule(FuncGetArgsToVariadicParamRector::class);
$rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class);
$rectorConfig->rule(SimplifyEmptyArrayCheckRector::class);
$rectorConfig->rule(NormalizeNamespaceByPSR4ComposerAutoloadRector::class);
$rectorConfig
->ruleWithConfiguration(TypedPropertyRector::class, [
TypedPropertyRector::INLINE_PUBLIC => false,
]);
};
4 changes: 2 additions & 2 deletions src/Config/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use CodeIgniter\Shield\Authentication\Authenticators\AccessTokens;
use CodeIgniter\Shield\Authentication\Authenticators\Session;
use CodeIgniter\Shield\Authentication\Passwords\ValidatorInterface;
use CodeIgniter\Shield\Models\UserModel;

class Auth extends BaseConfig
{
Expand Down Expand Up @@ -324,7 +325,6 @@ class Auth extends BaseConfig
* OTHER SETTINGS
* ////////////////////////////////////////////////////////////////////
*/

/**
* --------------------------------------------------------------------
* User Provider
Expand All @@ -335,7 +335,7 @@ class Auth extends BaseConfig
* You can change it as long as they adhere to the
* CodeIgniter\Shield\Models\UserModel.
*
* @var class-string<\CodeIgniter\Shield\Models\UserModel>
* @var class-string<UserModel>
*/
public string $userProvider = 'CodeIgniter\Shield\Models\UserModel';

Expand Down
1 change: 1 addition & 0 deletions tests/Authentication/HasAccessTokensTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function testAccessTokens()
['user_id' => $this->user->id, 'type' => 'access_token', 'secret' => 'secretToken2']
);

/** @var AccessToken[] $tokens */
$tokens = $this->user->accessTokens();

$this->assertCount(2, $tokens);
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/UserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function testLastLogin()

$last = $this->user->lastLogin();

$this->assertInstanceOf(Login::class, $last);
$this->assertInstanceOf(Login::class, $last); // @phpstan-ignore-line
$this->assertSame($login->id, $last->id);
$this->assertInstanceOf(Time::class, $last->date);
}
Expand Down