Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #9 #18

Merged
merged 1 commit into from
Jun 19, 2017
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
57 changes: 13 additions & 44 deletions src/Commands/ChurnCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Churn\Assessors\GitCommitCount\GitCommitCountAssessor;
use Churn\Assessors\CyclomaticComplexity\CyclomaticComplexityAssessor;
use Churn\Services\CommandService;
use Symfony\Component\Console\Helper\Table;
use Illuminate\Support\Collection;
use SplFileInfo;
use Churn\Results\ResultsGenerator;
use Churn\Managers\FileManager;
use Churn\Results\ResultCollection;

class ChurnCommand extends Command
{
Expand All @@ -23,8 +19,8 @@ class ChurnCommand extends Command
public function __construct()
{
parent::__construct();
$this->commitCountAssessor = new GitCommitCountAssessor(new CommandService);
$this->complexityAssessor = new CyclomaticComplexityAssessor();
$this->resultsGenerator = new ResultsGenerator;
$this->fileManager = new FileManager;
}

/**
Expand All @@ -47,51 +43,24 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$path = $input->getArgument('path');

$directoryIterator = new RecursiveDirectoryIterator($path);

$results = Collection::make();
foreach (new RecursiveIteratorIterator($directoryIterator) as $file) {
if ($file->getExtension() !== 'php') {
continue;
}
$results->push($this->getResults($file));
}
$results = $results->sortByDesc('score');
$this->displayTable($output, $results);
}

/**
* Calculate the results for a file.
* @param \SplFileInfo $file File.
* @return array
*/
protected function getResults(SplFileInfo $file): array
{
$commits = $this->commitCountAssessor->assess($file->getRealPath());
$complexity = $this->complexityAssessor->assess($file->getRealPath());

return [
'file' => $file->getRealPath(),
'commits' => $commits,
'complexity' => $complexity,
'score' => ($commits/ 10) * ($complexity * 8.75),
];
$path = $input->getArgument('path');
$phpFiles = $this->fileManager->getPhpFiles($path);
$results = $this->resultsGenerator->getResults($phpFiles);
$this->displayResults($output, $results);
}

/**
* Displays the results in a table.
* @param OutputInterface $output Output.
* @param \Illuminate\Support\Collection $results Results.
* @param Churn\Results\ResultCollection $results Results Collection.
* @return void
*/
protected function displayTable(OutputInterface $output, Collection $results)
protected function displayResults(OutputInterface $output, ResultCollection $results)
{
$table = new Table($output);
$table->setHeaders(['File', 'Times Changed', 'Complexity', 'Score']);
foreach ($results as $resultsRow) {
$table->addRow($resultsRow);
foreach ($results->orderByScoreDesc() as $result) {
$table->addRow($result->toArray());
}
$table->render();
}
Expand Down
28 changes: 28 additions & 0 deletions src/Managers/FileManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);

namespace Churn\Managers;

use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

class FileManager
{
/**
* Recursively finds all files with the .php extension in the provided
* $path and returns list as array.
* @param string $path Path to look for .php files.
* @return array
*/
public function getPhpFiles(string $path): array
{
$directoryIterator = new RecursiveDirectoryIterator($path);
$files = [];
foreach (new RecursiveIteratorIterator($directoryIterator) as $file) {
if ($file->getExtension() !== 'php') {
continue;
}
$files[] = $file->getRealPath();
}
return $files;
}
}
85 changes: 85 additions & 0 deletions src/Results/Result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php declare(strict_types = 1);

namespace Churn\Results;

class Result
{
/**
* The file property.
* @var string
*/
private $file;

/**
* The commits property.
* @var string
*/
private $commits;

/**
* The complexity property.
* @var string
*/
private $complexity;

/**
* Class constructor.
* @param array $data Data to store in the object.
*/
public function __construct(array $data)
{
$this->file = $data['file'];
$this->commits = $data['commits'];
$this->complexity = $data['complexity'];
}

/**
* Get the file property.
* @return string
*/
public function getFile(): string
{
return $this->file;
}

/**
* Get the file property.
* @return string
*/
public function getCommits(): string
{
return $this->commits;
}

/**
* Get the file property.
* @return string
*/
public function getComplexity(): string
{
return $this->complexity;
}

/**
* Calculate the score.
* @return string
*/
public function getScore(): string
{
return $this->getCommits() + $this->getComplexity();
}

/**
* Output results to an array.
* @return string
*/
public function toArray(): string
{
return [
$this->getFile(),
$this->getCommits(),
$this->getComplexity(),
$this->getScore(),
];
}
}
19 changes: 19 additions & 0 deletions src/Results/ResultCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);

namespace Churn\Results;

use Illuminate\Support\Collection;

class ResultCollection extends Collection
{
/**
* Order results by their score in descending order.
* @return self
*/
public function orderByScoreDesc(): self
{
return $this->sortByDesc(function ($result) {
return $result->getScore();
});
}
}
63 changes: 63 additions & 0 deletions src/Results/ResultsGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php declare(strict_types = 1);

namespace Churn\Results;

use Churn\Services\CommandService;
use Churn\Assessors\GitCommitCount\GitCommitCountAssessor;
use Churn\Assessors\CyclomaticComplexity\CyclomaticComplexityAssessor;

class ResultsGenerator
{

/**
* The commit count assesor.
* @var GitCommitCountAssessor
*/
protected $commitCountAssessor;

/**
* The complexity assesor.
* @var CyclomaticComplexityAssessor
*/
protected $complexityAssessor;

/**
* Class constructor.
*/
public function __construct()
{
$this->commitCountAssessor = new GitCommitCountAssessor(new CommandService);
$this->complexityAssessor = new CyclomaticComplexityAssessor();
}

/**
* Generates a ResultCollection for the provided $fils.
* @param array $files List of files.
* @return ResultCollection
*/
public function getResults(array $files): ResultCollection
{
$results = new ResultCollection;
foreach ($files as $file) {
$results->push($this->getResultsForFile($file));
}
return $results;
}

/**
* Returns a Result object for the provided $file.
* @param string $file File.
* @return Result
*/
protected function getResultsForFile(string $file): Result
{
$commits = $this->commitCountAssessor->assess($file);
$complexity = $this->complexityAssessor->assess($file);

return new Result([
'file' => $file,
'commits' => $commits,
'complexity' => $complexity,
]);
}
}