Skip to content

Commit

Permalink
Merge pull request #154 from coenjacobs/phpmd-experiment
Browse files Browse the repository at this point in the history
Adding phpmd as code quality ensurance
  • Loading branch information
coenjacobs authored Sep 19, 2024
2 parents eac01ed + b1a58c5 commit 952d847
Show file tree
Hide file tree
Showing 23 changed files with 536 additions and 299 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,20 @@ jobs:
cache-to: type=gha,mode=max
- name: Run analysis
run: docker compose run --rm actions-tester composer test:phpstan
mess-detect:
runs-on: ubuntu-latest
name: Mess detector
steps:
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2
- uses: actions/checkout@v4
- name: Build Docker image
id: build-and-push
uses: docker/build-push-action@v4
with:
context: "{{defaultContext}}"
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run mess detector
run: docker compose run --rm actions-tester composer test:phpmd
9 changes: 7 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@
"symfony/console": "^5.4",
"symfony/finder": "^5.4",
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"phpcompatibility/php-compatibility": "dev-develop"
"phpcompatibility/php-compatibility": "dev-develop",
"phpmd/phpmd": "^2.15"
},
"scripts": {
"test": [
"@test:lint",
"@test:phpunit",
"@test:phpstan"
"@test:phpstan",
"@test:phpmd"
],
"test:lint": [
"composer validate",
Expand All @@ -57,6 +59,9 @@
],
"test:phpstan": [
"./vendor/bin/phpstan analyse -c phpstan.neon.dist --memory-limit=2G"
],
"test:phpmd": [
"./vendor/bin/phpmd src ansi phpmd.xml.dist"
]
}
}
16 changes: 16 additions & 0 deletions phpmd.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<ruleset name="Rule set for PHPMD to detect code smells"
xmlns="https://phpmd.org/xml/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://phpmd.org/xml/ruleset/1.0.0
http://phpmd.org/xml/ruleset_xml_schema_1.0.0.xsd"
xsi:noNamespaceSchemaLocation="
http://phpmd.org/xml/ruleset_xml_schema_1.0.0.xsd">

<rule ref="rulesets/codesize.xml" />
<rule ref="rulesets/cleancode.xml" />
<rule ref="rulesets/controversial.xml" />
<rule ref="rulesets/design.xml" />
<rule ref="rulesets/naming.xml" />
<rule ref="rulesets/unusedcode.xml" />
</ruleset>
27 changes: 27 additions & 0 deletions src/Composer/Autoload/AbstractAutoloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace CoenJacobs\Mozart\Composer\Autoload;

use CoenJacobs\Mozart\Config\Package;

abstract class AbstractAutoloader implements Autoloader
{
private Package $package;

public function getPackage(): Package
{
return $this->package;
}

public function setPackage(Package $package): void
{
$this->package = $package;
}

public function getOutputDir(string $basePath, string $autoloadPath): string
{
$outputDir = $basePath . $autoloadPath;
$outputDir = str_replace('\\', DIRECTORY_SEPARATOR, $outputDir);
return $outputDir;
}
}
9 changes: 9 additions & 0 deletions src/Composer/Autoload/Autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

namespace CoenJacobs\Mozart\Composer\Autoload;

use CoenJacobs\Mozart\FilesHandler;
use Symfony\Component\Finder\SplFileInfo;

interface Autoloader
{
/**
* @param mixed $autoloadConfig
*/
public function processConfig($autoloadConfig): void;
public function getSearchNamespace(): string;
public function getOutputDir(string $basePath, string $autoloadPath): string;
/**
* @return array<string,SplFileInfo>
*/
public function getFiles(FilesHandler $files): array;
public function getTargetFilePath(SplFileInfo $file): string;
}
58 changes: 55 additions & 3 deletions src/Composer/Autoload/NamespaceAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace CoenJacobs\Mozart\Composer\Autoload;

abstract class NamespaceAutoloader implements Autoloader
use CoenJacobs\Mozart\FilesHandler;
use Symfony\Component\Finder\SplFileInfo;

abstract class NamespaceAutoloader extends AbstractAutoloader
{
/** @var string */
public $namespace = '';
Expand All @@ -16,6 +19,8 @@ abstract class NamespaceAutoloader implements Autoloader
*/
public $paths = [];

private FilesHandler $fileHandler;

/**
* A package's composer.json config autoload key's value, where $key is `psr-1`|`psr-4`|`classmap`.
*
Expand All @@ -27,9 +32,10 @@ public function processConfig($autoloadConfig): void
foreach ($autoloadConfig as $path) {
array_push($this->paths, $path);
}
} else {
array_push($this->paths, $autoloadConfig);

return;
}
array_push($this->paths, $autoloadConfig);
}

public function getNamespace(): string
Expand All @@ -46,4 +52,50 @@ public function getNamespacePath(): string
{
return '';
}

public function getFiles(FilesHandler $fileHandler): array
{
$this->fileHandler = $fileHandler;
$filesToMove = array();

foreach ($this->paths as $path) {
$sourcePath = $fileHandler->getConfig()->getWorkingDir() . 'vendor' . DIRECTORY_SEPARATOR
. $this->getPackage()->getName() . DIRECTORY_SEPARATOR . $path;

$sourcePath = str_replace('/', DIRECTORY_SEPARATOR, $sourcePath);


$files = $fileHandler->getFilesFromPath($sourcePath);

foreach ($files as $foundFile) {
$filePath = $foundFile->getRealPath();
$filesToMove[ $filePath ] = $foundFile;
}
}

return $filesToMove;
}

public function getTargetFilePath(SplFileInfo $file): string
{
$suffix = '';
foreach ($this->paths as $path) {
if (! empty(strstr($file->getPathname(), $this->getPackage()->getName() . DIRECTORY_SEPARATOR . $path))) {
$suffix = $path;
break;
}
}

$replaceWith = $this->fileHandler->getConfig()->getDepDirectory() . $this->getNamespacePath();
$targetFile = str_replace($this->fileHandler->getConfig()->getWorkingDir(), $replaceWith, $file->getPathname());

$packageVendorPath = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $this->getPackage()->getName();

if (! empty($suffix)) {
$packageVendorPath = $packageVendorPath . DIRECTORY_SEPARATOR . $suffix;
}

$packageVendorPath = str_replace('/', DIRECTORY_SEPARATOR, $packageVendorPath);
return str_replace($packageVendorPath, DIRECTORY_SEPARATOR, $targetFile);
}
}
5 changes: 4 additions & 1 deletion src/Config/Autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Autoload
/** @var array<Autoloader> */
public array $autoloaders = [];

public function setupAutoloaders(stdClass $autoloadData): void
public function setupAutoloaders(stdClass $autoloadData, Package $package): void
{
$autoloaders = [];

Expand All @@ -20,6 +20,7 @@ public function setupAutoloaders(stdClass $autoloadData): void
$autoloader = new Psr4();
$autoloader->namespace = $key;
$autoloader->processConfig($value);
$autoloader->setPackage($package);
$autoloaders[] = $autoloader;
}
}
Expand All @@ -30,13 +31,15 @@ public function setupAutoloaders(stdClass $autoloadData): void
$autoloader = new Psr0();
$autoloader->namespace = $key;
$autoloader->processConfig($value);
$autoloader->setPackage($package);
$autoloaders[] = $autoloader;
}
}

if (isset($autoloadData->classmap)) {
$autoloader = new Classmap();
$autoloader->processConfig($autoloadData->classmap);
$autoloader->setPackage($package);
$autoloaders[] = $autoloader;
}

Expand Down
73 changes: 69 additions & 4 deletions src/Config/Classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

namespace CoenJacobs\Mozart\Config;

use CoenJacobs\Mozart\Composer\Autoload\Autoloader;
use CoenJacobs\Mozart\Composer\Autoload\AbstractAutoloader;
use CoenJacobs\Mozart\FilesHandler;
use Exception;
use Symfony\Component\Finder\SplFileInfo;

class Classmap implements Autoloader
class Classmap extends AbstractAutoloader
{
/** @var string[] */
public $files = [];

/** @var string[] */
public $paths = [];

private FilesHandler $fileHandler;

/**
* @inheritdoc
*/
Expand All @@ -21,9 +25,10 @@ public function processConfig($autoloadConfig): void
foreach ($autoloadConfig as $value) {
if ('.php' == substr($value, -4, 4)) {
array_push($this->files, $value);
} else {
array_push($this->paths, $value);
continue;
}

array_push($this->paths, $value);
}
}

Expand All @@ -34,4 +39,64 @@ public function getSearchNamespace(): string
{
throw new Exception('Classmap autoloaders do not contain a namespace and this method can not be used.');
}

/**
* @return array<string,SplFileInfo>
*/
public function getFiles(FilesHandler $fileHandler): array
{
$this->fileHandler = $fileHandler;
$filesToMove = array();

foreach ($this->files as $file) {
$sourcePath = $fileHandler->getConfig()->getWorkingDir() . 'vendor'
. DIRECTORY_SEPARATOR . $this->getPackage()->getName();

$files = $fileHandler->getFile($sourcePath, $file);

foreach ($files as $foundFile) {
$filePath = $foundFile->getRealPath();
$filesToMove[ $filePath ] = $foundFile;
}
}

foreach ($this->paths as $path) {
$sourcePath = $fileHandler->getConfig()->getWorkingDir() . 'vendor'
. DIRECTORY_SEPARATOR . $this->getPackage()->getName() . DIRECTORY_SEPARATOR . $path;

$files = $fileHandler->getFilesFromPath($sourcePath);
foreach ($files as $foundFile) {
$filePath = $foundFile->getRealPath();
$filesToMove[ $filePath ] = $foundFile;
}
}

return $filesToMove;
}

public function getTargetFilePath(SplFileInfo $file): string
{
$suffix = '';
foreach ($this->paths as $path) {
if (! empty(strstr($file->getPathname(), $this->getPackage()->getName() . DIRECTORY_SEPARATOR . $path))) {
$suffix = $path;
break;
}
}

$namespacePath = $this->getPackage()->getName();
$replaceWith = $this->fileHandler->getConfig()->getClassmapDirectory() . $namespacePath . DIRECTORY_SEPARATOR;

$targetFile = str_replace($this->fileHandler->getConfig()->getWorkingDir(), $replaceWith, $file->getPathname());

$packageVendorPath = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $this->getPackage()->getName()
. DIRECTORY_SEPARATOR;

if (! empty($suffix)) {
$packageVendorPath = $packageVendorPath . DIRECTORY_SEPARATOR . $suffix;
}

$packageVendorPath = str_replace('/', DIRECTORY_SEPARATOR, $packageVendorPath);
return str_replace($packageVendorPath, DIRECTORY_SEPARATOR, $targetFile);
}
}
Loading

0 comments on commit 952d847

Please sign in to comment.