Skip to content

Commit

Permalink
Add PHP-CS-Fixer and phpstan to dev pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
cviebrock committed Nov 29, 2024
1 parent a4281cf commit a46915e
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 57 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/.php_cs.cache
/.php-cs-fixer.cache
/.phpunit.cache
/.phpunit.result.cache
/.idea/
/build/
/vendor/
composer.lock
composer.phar
55 changes: 55 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;

$finder = (new Finder())
->in(__DIR__);

return (new Config())
->setParallelConfig(ParallelConfigFactory::detect())
->setRules([
'@PhpCsFixer' => true,
'@PHP84Migration' => true,
'indentation_type' => true,

// Overrides for (opinionated) @PhpCsFixer and @Symfony rules:

// Align "=>" in multi-line array definitions, unless a blank line exists between elements
'binary_operator_spaces' => ['operators' => ['=>' => 'align_single_space_minimal']],

// Subset of statements that should be proceeded with blank line
'blank_line_before_statement' => ['statements' => ['case', 'continue', 'default', 'return', 'throw', 'try', 'yield', 'yield_from']],

// Enforce space around concatenation operator
'concat_space' => ['spacing' => 'one'],

// Use {} for empty loop bodies
'empty_loop_body' => ['style' => 'braces'],

// Don't change any increment/decrement styles
'increment_style' => false,

// Forbid multi-line whitespace before the closing semicolon
'multiline_whitespace_before_semicolons' => ['strategy' => 'no_multi_line'],

// Clean up PHPDocs, but leave @inheritDoc entries alone
'no_superfluous_phpdoc_tags' => ['allow_mixed' => true, 'remove_inheritdoc' => false],

// Ensure that traits are listed first in classes
// (it would be nice to enforce more, but we'll start simple)
'ordered_class_elements' => ['order' => ['use_trait']],

// Ensure that param and return types are sorted consistently, with null at end
'phpdoc_types_order' => ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],

// Don't add @coversNothing annotations to tests
'php_unit_test_class_requires_covers' => false,

// Yoda style is too weird
'yoda_style' => false,
])
->setIndent(' ')
->setLineEnding("\n")
->setFinder($finder);
14 changes: 0 additions & 14 deletions .php_cs.dist

This file was deleted.

8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
"illuminate/support": "^11.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.65",
"larastan/larastan": "^3.0",
"mockery/mockery": "^1.4.4",
"orchestra/testbench": "^9.0",
"pestphp/pest": "^2.28"
"pestphp/pest": "^2.28",
"phpstan/phpstan": "^2.0"
},
"autoload": {
"psr-4": {
Expand All @@ -40,10 +43,13 @@
}
},
"scripts": {
"analyze": "vendor/bin/phpstan analyze",
"fresh": [
"rm -rf vendor composer.lock",
"composer install"
],
"style:check": "vendor/bin/php-cs-fixer check -v",
"style:fix": "vendor/bin/php-cs-fixer fix -v",
"tests": [
"rm -rf build",
"XDEBUG_MODE=coverage php vendor/bin/pest"
Expand Down
11 changes: 11 additions & 0 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
includes:
- vendor/larastan/larastan/extension.neon

parameters:
level: 4
paths:
- resources
- src
- tests
editorUrl: '%%relFile%%:%%line%%'
editorUrlTitle: '%%relFile%%:%%line%%'
3 changes: 2 additions & 1 deletion src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ protected function setUpConfig(): void

if ($this->app instanceof LaravelApplication) {
$this->publishes([$source => config_path('sluggable.php')], 'config');
/** @phpstan-ignore-next-line */
} elseif ($this->app instanceof LumenApplication) {
$this->app->configure('sluggable');
$this->app->configure('sluggable'); /** @phpstan-ignore class.notFound */
}

$this->mergeConfigFrom($source, 'sluggable');
Expand Down
8 changes: 4 additions & 4 deletions src/Services/SlugService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
class SlugService
{

final public function __construct() {}

/**
* @var \Illuminate\Database\Eloquent\Model
* @var \Cviebrock\EloquentSluggable\Sluggable
Expand Down Expand Up @@ -407,12 +409,12 @@ protected function usesSoftDeleting(): bool
* @throws \InvalidArgumentException
* @throws \UnexpectedValueException
*/
public static function createSlug($model, string $attribute, string $fromString, ?array $config = null): string
public static function createSlug(Model|string $model, string $attribute, string $fromString, ?array $config = null): string
{
if (is_string($model)) {
$model = new $model;
}
/** @var static $instance */

$instance = (new static())->setModel($model);

if ($config === null) {
Expand All @@ -421,8 +423,6 @@ public static function createSlug($model, string $attribute, string $fromString,
$modelClass = get_class($model);
throw new \InvalidArgumentException("Argument 2 passed to SlugService::createSlug ['{$attribute}'] is not a valid slug attribute for model {$modelClass}.");
}
} elseif (!is_array($config)) {
throw new \UnexpectedValueException('SlugService::createSlug expects an array or null as the fourth argument; ' . gettype($config) . ' given.');
}

$config = $instance->getConfiguration($config);
Expand Down
2 changes: 2 additions & 0 deletions src/SluggableObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function __construct(SlugService $slugService, Dispatcher $events)
*/
public function saving(Model $model)
{
/** @phpstan-ignore-next-line */
if ($model->sluggableEvent() !== self::SAVING) {
return;
}
Expand All @@ -59,6 +60,7 @@ public function saving(Model $model)
*/
public function saved(Model $model)
{
/** @phpstan-ignore-next-line */
if ($model->sluggableEvent() !== self::SAVED) {
return;
}
Expand Down
12 changes: 4 additions & 8 deletions tests/Models/Author.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,19 @@
*
* @package Cviebrock\EloquentSluggable\Tests\Models
*
* @property integer id
* @property string name
* @property integer $id
* @property string $name
*/
class Author extends Model
{

/**
* Indicates if the model should be timestamped.
*
* @var bool
* @inheritdoc
*/
public $timestamps = false;

/**
* The attributes that are mass assignable.
*
* @var array
* @inheritdoc
*/
protected $fillable = ['name'];
}
24 changes: 9 additions & 15 deletions tests/Models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,30 @@
*
* @package Cviebrock\EloquentSluggable\Tests\Models
*
* @property integer id
* @property string title
* @property string|null subtitle
* @property string|null slug
* @property string|null dummy
* @property integer author_id
* @property int $id
* @property string $title
* @property ?string $subtitle
* @property ?string $slug
* @property ?string $dummy
* @property ?int $author_id
*/
class Post extends Model
{

use Sluggable;

/**
* The table associated with the model.
*
* @var string
* @inheritdoc
*/
protected $table = 'posts';

/**
* Indicates if the model should be timestamped.
*
* @var bool
* @inheritdoc
*/
public $timestamps = false;

/**
* The attributes that are mass assignable.
*
* @var array
* @inheritdoc
*/
protected $fillable = ['title', 'subtitle', 'slug', 'dummy', 'author_id'];

Expand Down
19 changes: 10 additions & 9 deletions tests/Models/PostNotSluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,29 @@
* A test model that doesn't use the Sluggable package.
*
* @package Cviebrock\EloquentSluggable\Tests\Models
*
* @property int $id
* @property string $title
* @property ?string $subtitle
* @property ?string $slug
* @property ?string $dummy
* @property ?int $author_id
*/
class PostNotSluggable extends Model
{

/**
* The table associated with the model.
*
* @var string
* @inheritdoc
*/
protected $table = 'posts';

/**
* Indicates if the model should be timestamped.
*
* @var bool
* @inheritdoc
*/
public $timestamps = false;

/**
* The attributes that are mass assignable.
*
* @var array
* @inheritdoc
*/
protected $fillable = ['title', 'subtitle'];

Expand Down
2 changes: 1 addition & 1 deletion tests/Models/PostWithRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* @package Cviebrock\EloquentSluggable\Tests\Models
*
* @property \Cviebrock\EloquentSluggable\Tests\Models\Author author
* @property \Cviebrock\EloquentSluggable\Tests\Models\Author|null $author
*/
class PostWithRelation extends Post
{
Expand Down
3 changes: 3 additions & 0 deletions tests/Models/PostWithUniqueSlugConstraints.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* Class PostWithUniqueSlugConstraints
*
* @package Cviebrock\EloquentSluggable\Tests\Models
*
* @property \Cviebrock\EloquentSluggable\Tests\Models\Author|null $author
*/
class PostWithUniqueSlugConstraints extends Post
{
Expand All @@ -27,6 +29,7 @@ public function author(): BelongsTo
*/
public function scopeWithUniqueSlugConstraints(Builder $query, Model $model, $attribute, $config, $slug): Builder
{
/** @var self $model */
$author = $model->author;

return $query->where('author_id', $author->getKey());
Expand Down
2 changes: 1 addition & 1 deletion tests/OnUpdateTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public function testSlugDoesNotChangeIfSourceNotProvidedInModel(): void
]);
self::assertEquals('my-first-post', $post->slug);

$post = Post::whereKey($post->id)->get(['id','subtitle'])->first();
$post = Post::whereKey($post->id)->first(['id','subtitle']);
$post->update([
'subtitle' => 'A Subtitle'
]);
Expand Down

0 comments on commit a46915e

Please sign in to comment.