Skip to content

Commit

Permalink
Fixes and config refactoring (#11)
Browse files Browse the repository at this point in the history
* Fixing the interface declaration
* Working on the docker setup
* Fixing phpstan issues
* Refactoring the config
  • Loading branch information
floriankraemer authored Oct 1, 2024
1 parent 565564e commit b543b54
Show file tree
Hide file tree
Showing 24 changed files with 360 additions and 116 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ coverage-html:
docker compose run php composer test-coverage-html

all:
@echo "Running CS-Fixer, CS-Checker, Static Analyser and Tests"
docker compose run php composer all
@echo "Running CS-Checker, Static Analyser and Tests"
docker compose run -T php composer all

shell:
@echo "Running shell"
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"bin/phpbench run tests/Benchmark/ --report=aggregate"
],
"all": [
"@csfix",
"@cscheck",
"@analyze",
"@test"
Expand Down
19 changes: 11 additions & 8 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
cognitive:
excludeFilePatterns:
excludePatterns:
scoreThreshold: 0.5
showOnlyMethodsExceedingThreshold: false
metrics:
lineCount:
threshold: 60
scale: 25.0
enabled: true
argCount:
threshold: 4
scale: 1.0
enabled: true
returnCount:
threshold: 2
scale: 5.0
enabled: true
variableCount:
threshold: 2
scale: 5.0
enabled: true
propertyCallCount:
threshold: 2
scale: 15.0
enabled: true
ifCount:
threshold: 3
scale: 1.0
enabled: true
ifNestingLevel:
threshold: 1
scale: 1.0
enabled: true
elseCount:
threshold: 1
scale: 1.0

halstead:
threshold:
difficulty: 0.0
effort: 0.0
time: 0.0
bugs: 0.0
volume: 0.0
enabled: true
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ services:
command: "tail -f /dev/null"
ports:
- 9003:9003
user: php
6 changes: 6 additions & 0 deletions docker/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN git config --global --add safe.directory /app

# Create a new user
RUN useradd -m php

# Set the new user as the default user for the container
USER php
10 changes: 10 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,13 @@ cognitive:
```
It is recommended to play with the values until you get weights that you are comfortable with. The default values are a good starting point.
## Excluding Files
Regular expression patterns can be defined to exclude files from the analysis.
```yaml
cognitive:
excludeFilePatterns:
- '(.*)Test.php'
```
3 changes: 3 additions & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ private function registerServices(): void
->setPublic(true);

$this->containerBuilder->register(CognitiveMetricTextRenderer::class, CognitiveMetricTextRenderer::class)
->setArguments([
new Reference(OutputInterface::class)
])
->setPublic(true);

$this->containerBuilder->register(BaselineService::class, BaselineService::class)
Expand Down
20 changes: 14 additions & 6 deletions src/Business/Cognitive/CognitiveMetricsCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ public function contains(CognitiveMetrics $otherMetric): bool

public function getClassWithMethod(string $class, string $method): ?CognitiveMetrics
{
if (isset($this->metrics[$class . '::' . $method])) {
return $this->metrics[$class . '::' . $method];
$fullMethod = $class . '::' . $method;
if (isset($this->metrics[$fullMethod])) {
return $this->metrics[$fullMethod];
}

return null;
Expand All @@ -94,6 +95,16 @@ public function filterByClassName(string $className): CognitiveMetricsCollection
});
}

private function assertMetricHasGetter(
CognitiveMetrics $metric,
string $getter,
string $property
): void {
if (!method_exists($metric, $getter)) {
throw new InvalidArgumentException("Property '$property' does not exist in CognitiveMetrics class");
}
}

/**
* Group the collection by a property of the CognitiveMetrics object
*
Expand All @@ -107,12 +118,9 @@ public function groupBy(string $property): array

foreach ($this->metrics as $metric) {
$getter = 'get' . ucfirst($property);
if (!method_exists($metric, $getter)) {
throw new InvalidArgumentException("Property '$property' does not exist in CognitiveMetrics class");
}
$this->assertMetricHasGetter($metric, $getter, $property);

$key = $metric->$getter();

if (!isset($grouped[$key])) {
$grouped[$key] = new self();
}
Expand Down
41 changes: 19 additions & 22 deletions src/Business/Cognitive/CognitiveMetricsCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Phauthentic\CognitiveCodeAnalysis\Business\DirectoryScanner;
use Phauthentic\CognitiveCodeAnalysis\CognitiveAnalysisException;
use Phauthentic\CognitiveCodeAnalysis\Config\CognitiveConfig;
use Phauthentic\CognitiveCodeAnalysis\Config\ConfigService;
use Phauthentic\CognitiveCodeAnalysis\PhpParser\CognitiveMetricsVisitor;
use PhpParser\Error;
Expand Down Expand Up @@ -34,38 +35,38 @@ public function __construct(
$this->parser = $parserFactory->createForHostVersion();
}

/**
* @param array<string, mixed> $config
* @return array<int, string>
*/
private function getExcludePatternsFromConfig(array $config): array
{
if (isset($config['excludePatterns'])) {
return $config['excludePatterns'];
}

return [];
}

/**
* Collect cognitive metrics from the given path
*
* @param string $path
* @param array<string, mixed> $config
* @param CognitiveConfig $config
* @return CognitiveMetricsCollection
* @throws CognitiveAnalysisException
*/
public function collect(string $path, array $config = []): CognitiveMetricsCollection
public function collect(string $path, CognitiveConfig $config): CognitiveMetricsCollection
{
$files = $this->findSourceFiles($path, $this->getExcludePatternsFromConfig($config));
$files = $this->findSourceFiles($path, $config->excludeFilePatterns);

return $this->findMetrics($files);
}

private function getCodeFromFile(SplFileInfo $file): string
{
$code = file_get_contents($file->getRealPath());

if ($code === false) {
throw new CognitiveAnalysisException("Could not read file: {$file->getRealPath()}");
}

return $code;
}

/**
* Collect metrics from the found source files
*
* @param iterable<SplFileInfo> $files
* @return CognitiveMetricsCollection
* @throws CognitiveAnalysisException
*/
private function findMetrics(iterable $files): CognitiveMetricsCollection
{
Expand All @@ -81,11 +82,7 @@ private function findMetrics(iterable $files): CognitiveMetricsCollection
$plugin->beforeFindMetrics($file);
}

$code = file_get_contents($file->getRealPath());

if ($code === false) {
throw new CognitiveAnalysisException("Could not read file: {$file->getRealPath()}");
}
$code = $this->getCodeFromFile($file);

$this->traverser->addVisitor($visitor);
$this->traverseAbstractSyntaxTree($code);
Expand Down Expand Up @@ -139,7 +136,7 @@ private function processMethodMetrics(

private function isExcluded(string $classAndMethod): bool
{
$regexes = $this->configService->getConfig()['cognitive']['excludePatterns'];
$regexes = $this->configService->getConfig()->excludePatterns;

foreach ($regexes as $regex) {
if (preg_match('/' . $regex . '/', $classAndMethod, $matches)) {
Expand Down
4 changes: 3 additions & 1 deletion src/Business/Cognitive/Exporter/DataExporterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Phauthentic\CognitiveCodeAnalysis\Business\Cognitive\Exporter;

use Phauthentic\CognitiveCodeAnalysis\Business\Cognitive\CognitiveMetricsCollection;

/**
*
*/
interface DataExporterInterface
{
//public function export(array $metrics, string $filename): void;
public function export(CognitiveMetricsCollection $metrics, string $filename): void;
}
20 changes: 11 additions & 9 deletions src/Business/Cognitive/ScoreCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Phauthentic\CognitiveCodeAnalysis\Business\Cognitive;

use Phauthentic\CognitiveCodeAnalysis\Config\CognitiveConfig;

/**
*
*/
Expand All @@ -25,13 +27,11 @@ class ScoreCalculator

/**
* @param CognitiveMetrics $metrics
* @param array<string, mixed> $metricConfiguration
* @param CognitiveConfig $config
* @return void
*/
public function calculate(CognitiveMetrics $metrics, array $metricConfiguration = []): void
public function calculate(CognitiveMetrics $metrics, CognitiveConfig $config): void
{
$metricConfiguration = $metricConfiguration['metrics'];

// List of metric types to process
$metricTypes = [
'LineCount' => 'lineCount',
Expand All @@ -45,7 +45,7 @@ public function calculate(CognitiveMetrics $metrics, array $metricConfiguration
];

// Calculate and set weights for each metric type
$this->calculateMetricWeights($metricTypes, $metrics, $metricConfiguration);
$this->calculateMetricWeights($metricTypes, $metrics, $config);

// Calculate the overall score
$this->calculateScore($metrics);
Expand All @@ -65,20 +65,22 @@ private function calculateScore(CognitiveMetrics $metrics): void
/**
* @param array<string, string> $metricTypes
* @param CognitiveMetrics $metrics
* @param array<string, mixed> $config
* @param CognitiveConfig $config
* @return void
*/
private function calculateMetricWeights(array $metricTypes, CognitiveMetrics $metrics, array $config): void
private function calculateMetricWeights(array $metricTypes, CognitiveMetrics $metrics, CognitiveConfig $config): void
{
$metricConfigs = $config->metrics;

foreach ($metricTypes as $methodSuffix => $configKey) {
$getMethod = 'get' . $methodSuffix;
$setMethod = 'set' . $methodSuffix . 'Weight';

$metrics->{$setMethod}(
$this->calculateLogWeight(
$metrics->{$getMethod}(),
$config[$configKey]['threshold'],
$config[$configKey]['scale']
$metricConfigs[$configKey]->threshold,
$metricConfigs[$configKey]->scale,
)
);
}
Expand Down
10 changes: 8 additions & 2 deletions src/Business/MetricsFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Phauthentic\CognitiveCodeAnalysis\Business\Cognitive\Exporter\HtmlExporter;
use Phauthentic\CognitiveCodeAnalysis\Business\Cognitive\Exporter\JsonExporter;
use Phauthentic\CognitiveCodeAnalysis\Business\Cognitive\ScoreCalculator;
use Phauthentic\CognitiveCodeAnalysis\Config\CognitiveConfig;
use Phauthentic\CognitiveCodeAnalysis\Config\ConfigService;

/**
Expand All @@ -36,10 +37,10 @@ public function __construct(
*/
public function getCognitiveMetrics(string $path): CognitiveMetricsCollection
{
$metricsCollection = $this->cognitiveMetricsCollector->collect($path, $this->configService->getConfig()['cognitive']);
$metricsCollection = $this->cognitiveMetricsCollector->collect($path, $this->configService->getConfig());

foreach ($metricsCollection as $metric) {
$this->scoreCalculator->calculate($metric, $this->configService->getConfig()['cognitive']);
$this->scoreCalculator->calculate($metric, $this->configService->getConfig());
}

return $metricsCollection;
Expand All @@ -56,6 +57,11 @@ public function loadConfig(string $configFilePath): void
$this->configService->loadConfig($configFilePath);
}

public function getConfig(): CognitiveConfig
{
return $this->configService->getConfig();
}

public function metricsCollectionToCsv(CognitiveMetricsCollection $metricsCollection, string $filename): void
{
(new CsvExporter())->export($metricsCollection, $filename);
Expand Down
Loading

0 comments on commit b543b54

Please sign in to comment.