Skip to content

Commit

Permalink
Merge branch 'feature/updates' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ventrec committed Jan 17, 2023
2 parents 58ebdd2 + 6ce5db7 commit abea662
Show file tree
Hide file tree
Showing 22 changed files with 739 additions and 40 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) s360
Copyright (c) Indent

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "s360digital/laravel-linter",
"name": "indentno/laravel-linter",
"description": "Linting for your laravel project",
"type": "library",
"license": "MIT",
"require": {
"php": ">=7.3",
"tightenco/tlint": "^6.1"
"php": ">=8.0",
"tightenco/tlint": "^8.0"
},
"autoload": {
"psr-4": {
"S360Digital\\LaravelLinter\\": "src/"
"Indent\\LaravelLinter\\": "src/"
}
},
"autoload-dev": {
Expand Down
29 changes: 23 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Linting for your laravel project.
[![Build Status](https://travis-ci.com/s360digital/laravel-linter.svg?branch=master)](https://travis-ci.com/s360digital/laravel-linter)
[![Build Status](https://travis-ci.com/indentno/laravel-linter.svg?branch=master)](https://travis-ci.com/indentno/laravel-linter)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
[![psr-2](https://img.shields.io/badge/code_style-PSR_2-blue.svg)](http://www.php-fig.org/psr/psr-2/)

Expand All @@ -14,14 +14,14 @@ A laravel linter based on the [tlint](https://github.com/tighten/tlint) package
Install the package as a dev dependency:

```bash
composer require s360digital/laravel-linter --dev
composer require indentno/laravel-linter --dev
```

Create a config (`tlint.json`), at the root of your repository, with the following contents:

```json
{
"preset": "S360Digital\\LaravelLinter\\Presets\\S360DigitalPreset",
"preset": "Indent\\LaravelLinter\\Presets\\IndentPreset",
"excluded": [
"tests/",
"database/"
Expand Down Expand Up @@ -64,11 +64,11 @@ The "preset" defines which preset that should be used for linting the project. A

### Disabled

The "disabled" key can be used to disable a set of linters from being ran in your project.
The "disabled" key can be used to disable a set of linters from being run in your project.

```json
{
"preset": "S360Digital\\LaravelLinter\\Presets\\S360DigitalPreset",
"preset": "Indent\\LaravelLinter\\Presets\\IndentPreset",
"disabled": [
"NoCompact",
"UseConfigOverEnv"
Expand All @@ -80,6 +80,23 @@ The "disabled" key can be used to disable a set of linters from being ran in you
}
```

## Rules

An overview of rules that needs further explanation.

### ValidRouteStructure

Routes should be structured the way we prefer.

**Examples**
```php
Route::get('articles', [ArticleController::class, 'index'])->name('article.index');

Route::patch('page/{id}', [PageController::class, 'update'])
->name('admin.page.update')
->middleware(CanUpdatePage::class);
```

## License

MIT © [s360](http://s360digital.com/)
MIT © [Indent](https://indent.no/)
2 changes: 1 addition & 1 deletion src/Linters/ControllerHasCorrectOrderForRestMethods.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace S360Digital\LaravelLinter\Linters;
namespace Indent\LaravelLinter\Linters;

use PhpParser\Node;
use PhpParser\NodeTraverser;
Expand Down
2 changes: 1 addition & 1 deletion src/Linters/FormRequestForControllerValidation.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace S360Digital\LaravelLinter\Linters;
namespace Indent\LaravelLinter\Linters;

use PhpParser\Node;
use PhpParser\NodeTraverser;
Expand Down
47 changes: 47 additions & 0 deletions src/Linters/ImportFacades.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Indent\LaravelLinter\Linters;

use Closure;
use PhpParser\Node;
use PhpParser\Node\Name;
use Tighten\TLint\BaseLinter;
use Tighten\TLint\Concerns\IdentifiesFacades;

class ImportFacades extends BaseLinter
{
use IdentifiesFacades;

public const DESCRIPTION = "Import facades (don't use aliases).";

protected function visitor(): Closure
{
return function (Node $node) {
static $hasNamespace = false;

if ($node instanceof Node\Stmt\Namespace_) {
$hasNamespace = true;
}

static $useNames = [];
static $useAliases = [];

if ($node instanceof Node\Stmt\GroupUse) {
foreach ($node->uses as $use) {
$useNames[] = Name::concat($node->prefix, $use->name)->toString();
$useAliases[] = $use->getAlias();
}
} elseif ($node instanceof Node\Stmt\UseUse) {
$useNames[] = $node->name->toString();
$useAliases[] = $node->getAlias();
}

return $node instanceof Node\Expr\StaticCall
&& $hasNamespace
&& $node->class instanceof Node\Name
&& in_array($node->class->toString(), array_keys(static::$aliases), false)
&& ! in_array($node->class->toString(), $useAliases, false)
&& ! in_array(static::$aliases[$node->class->toString()], $useNames, false);
};
}
}
23 changes: 23 additions & 0 deletions src/Linters/NoCompact.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Indent\LaravelLinter\Linters;

use Closure;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use Tighten\TLint\BaseLinter;
use Tighten\TLint\Linters\Concerns\LintsControllers;

class NoCompact extends BaseLinter
{
use LintsControllers;

public const DESCRIPTION = 'There should be no calls to `compact()` in controllers';

protected function visitor(): Closure
{
return function (Node $node) {
return $node instanceof FuncCall && ! empty($node->name->parts) && $node->name->parts[0] === 'compact';
};
}
}
22 changes: 22 additions & 0 deletions src/Linters/NoDump.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Indent\LaravelLinter\Linters;

use Closure;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Identifier;
use Tighten\TLint\BaseLinter;

class NoDump extends BaseLinter
{
public const DESCRIPTION = 'There should be no calls to `dd()`, `dump()`, `ray()`, or `var_dump()`';

protected function visitor(): Closure
{
return function (Node $node) {
return ($node instanceof FuncCall && ! empty($node->name->parts) && in_array($node->name->parts[0], ['dd', 'dump', 'var_dump', 'ray'], true))
|| ($node instanceof Identifier && in_array($node->name, ['dump', 'dd'], true));
};
}
}
47 changes: 47 additions & 0 deletions src/Linters/NoStringInterpolationWithoutBraces.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Indent\LaravelLinter\Linters;

use Closure;
use PhpParser\Node;
use Tighten\TLint\BaseLinter;

class NoStringInterpolationWithoutBraces extends BaseLinter
{
public const DESCRIPTION = 'Never use string interpolation without braces';

protected function visitor(): Closure
{
return function (Node $node) {
if ($node instanceof Node\Scalar\Encapsed) {
foreach ($node->parts as $part) {
if ($part instanceof Node\Expr\Variable) {
$line = $this->getCodeLinesFromNode($node);
$name = $part->name;

return ! (strpos($line, "{\${$name}}") !== false);
} elseif ($part instanceof Node\Expr\PropertyFetch) {
$line = $this->getCodeLinesFromNode($node);
$propertyFetchString = $this->constructPropertyFetchString($part);

return ! (strpos($line, "{\${$propertyFetchString}") !== false);
}
}
}

return false;
};
}

private function constructPropertyFetchString($next, $string = '')
{
if (property_exists($next, 'var')) {
return $this->constructPropertyFetchString(
$next->var,
$next->name->name . ($string ? ('->' . $string) : $string)
);
}

return $next->name . '->' . $string;
}
}
2 changes: 1 addition & 1 deletion src/Linters/PreventUseOfPhpDirectiveInBladeViews.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace S360Digital\LaravelLinter\Linters;
namespace Indent\LaravelLinter\Linters;

use PhpParser\Parser;
use Tighten\TLint\BaseLinter;
Expand Down
24 changes: 24 additions & 0 deletions src/Linters/UseConfigOverEnv.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Indent\LaravelLinter\Linters;

use Closure;
use PhpParser\Node;
use Tighten\TLint\BaseLinter;
use Tighten\TLint\Linters\Concerns\LintsNonConfigFiles;

class UseConfigOverEnv extends BaseLinter
{
use LintsNonConfigFiles;

public const DESCRIPTION = 'Don’t use environment variables directly; instead, use them in config files and call config vars from code';

protected function visitor(): Closure
{
return function (Node $node) {
return $node instanceof Node\Expr\FuncCall
&& $node->name instanceof Node\Name
&& $node->name->toString() === 'env';
};
}
}
4 changes: 2 additions & 2 deletions src/Linters/ValidRouteStructure.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace S360Digital\LaravelLinter\Linters;
namespace Indent\LaravelLinter\Linters;

use PhpParser\Node;
use PhpParser\NodeTraverser;
Expand All @@ -14,7 +14,7 @@ class ValidRouteStructure extends BaseLinter
use LintsRoutesFiles;

public const DESCRIPTION = 'Routes should be structured correctly. More information '
. 'here: https://docs.sempro.no/laravel/routing.html#anbefalt-struktur-for-routes';
. 'here: https://github.com/indentno/laravel-linter#validroutestructure';

private const ROUTE_METHOD_NAMES = [
'get',
Expand Down
30 changes: 10 additions & 20 deletions src/Presets/S360DigitalPreset.php
Original file line number Diff line number Diff line change
@@ -1,60 +1,50 @@
<?php

namespace S360Digital\LaravelLinter\Presets;
namespace Indent\LaravelLinter\Presets;

use S360Digital\LaravelLinter\Linters\ControllerHasCorrectOrderForRestMethods;
use S360Digital\LaravelLinter\Linters\FormRequestForControllerValidation;
use S360Digital\LaravelLinter\Linters\ValidRouteStructure;
use Tighten\TLint\Linters\AlphabeticalImports;
use Indent\LaravelLinter\Linters\ControllerHasCorrectOrderForRestMethods;
use Indent\LaravelLinter\Linters\FormRequestForControllerValidation;
use Indent\LaravelLinter\Linters\ImportFacades;
use Indent\LaravelLinter\Linters\NoCompact;
use Indent\LaravelLinter\Linters\NoDump;
use Indent\LaravelLinter\Linters\NoStringInterpolationWithoutBraces;
use Indent\LaravelLinter\Linters\UseConfigOverEnv;
use Indent\LaravelLinter\Linters\ValidRouteStructure;
use Tighten\TLint\Linters\ApplyMiddlewareInRoutes;
use Tighten\TLint\Linters\ArrayParametersOverViewWith;
use Tighten\TLint\Linters\ConcatenationSpacing;
use Tighten\TLint\Linters\ImportFacades;
use Tighten\TLint\Linters\NoCompact;
use Tighten\TLint\Linters\NoDatesPropertyOnModels;
use Tighten\TLint\Linters\NoDump;
use Tighten\TLint\Linters\NoJsonDirective;
use Tighten\TLint\Linters\NoLeadingSlashesOnRoutePaths;
use Tighten\TLint\Linters\NoParensEmptyInstantiations;
use Tighten\TLint\Linters\NoSpaceAfterBladeDirectives;
use Tighten\TLint\Linters\NoStringInterpolationWithoutBraces;
use Tighten\TLint\Linters\NoUnusedImports;
use Tighten\TLint\Linters\QualifiedNamesOnlyForClassName;
use Tighten\TLint\Linters\RemoveLeadingSlashNamespaces;
use Tighten\TLint\Linters\SpaceAfterBladeDirectives;
use Tighten\TLint\Linters\SpacesAroundBladeRenderContent;
use Tighten\TLint\Linters\TrailingCommasOnArrays;
use Tighten\TLint\Linters\UseAnonymousMigrations;
use Tighten\TLint\Linters\UseAuthHelperOverFacade;
use Tighten\TLint\Linters\UseConfigOverEnv;
use Tighten\TLint\Presets\PresetInterface;

class S360DigitalPreset implements PresetInterface
class IndentPreset implements PresetInterface
{
public function getLinters(): array
{
return [
AlphabeticalImports::class,
ApplyMiddlewareInRoutes::class,
ArrayParametersOverViewWith::class,
ConcatenationSpacing::class,
FormRequestForControllerValidation::class,
ImportFacades::class,
NoCompact::class,
NoDatesPropertyOnModels::class,
NoDump::class,
NoJsonDirective::class,
NoLeadingSlashesOnRoutePaths::class,
NoParensEmptyInstantiations::class,
NoSpaceAfterBladeDirectives::class,
NoStringInterpolationWithoutBraces::class,
NoUnusedImports::class,
QualifiedNamesOnlyForClassName::class,
RemoveLeadingSlashNamespaces::class,
ControllerHasCorrectOrderForRestMethods::class,
SpaceAfterBladeDirectives::class,
SpacesAroundBladeRenderContent::class,
TrailingCommasOnArrays::class,
UseAuthHelperOverFacade::class,
UseConfigOverEnv::class,
ValidRouteStructure::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Tests\Linters;

use PHPUnit\Framework\TestCase;
use S360Digital\LaravelLinter\Linters\ControllerHasCorrectOrderForRestMethods;
use Indent\LaravelLinter\Linters\ControllerHasCorrectOrderForRestMethods;
use Tighten\TLint\TLint;

class ControllerHasCorrectOrderForRestMethodsTest extends TestCase
Expand Down
2 changes: 1 addition & 1 deletion tests/Linters/FormRequestForControllerValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Tests\Linters;

use PHPUnit\Framework\TestCase;
use S360Digital\LaravelLinter\Linters\FormRequestForControllerValidation;
use Indent\LaravelLinter\Linters\FormRequestForControllerValidation;
use Tighten\TLint\TLint;

class FormRequestForControllerValidationTest extends TestCase
Expand Down
Loading

0 comments on commit abea662

Please sign in to comment.