src/Process/ChangesCountProcessBuilder.php
<?php
declare(strict_types=1);
namespace Churn\Process;
use Churn\File\File;
use Churn\Process\ChangesCount\FossilChangesCountProcess;
use Churn\Process\ChangesCount\GitChangesCountProcess;
use Churn\Process\ChangesCount\MercurialChangesCountProcess;
use Churn\Process\ChangesCount\NoVcsChangesCountProcess;
use Churn\Process\ChangesCount\SubversionChangesCountProcess;
use Closure;
use DateTime;
use InvalidArgumentException;
use Webmozart\Assert\Assert;
/**
* @internal
*/
final class ChangesCountProcessBuilder
{
/**
* @param string $vcs Name of the version control system.
* @param string $commitsSince String containing the date of when to look at commits since.
* @return Closure(File):ChangesCountInterface
* @throws InvalidArgumentException If VCS is not supported.
*/
public function getBuilder(string $vcs, string $commitsSince): Closure
{
switch ($vcs) {
case 'git':
return $this->getGitChangesCountProcessBuilder($commitsSince);
case 'subversion':
return $this->getSubversionChangesCountProcessBuilder($commitsSince);
case 'mercurial':
return $this->getMercurialChangesCountProcessBuilder($commitsSince);
case 'fossil':
return $this->getFossilChangesCountProcessBuilder($commitsSince);
case 'none':
return $this->getNoVcsChangesCountProcessBuilder();
default:
throw new InvalidArgumentException('Unsupported VCS: ' . $vcs);
}
}
/**
* @param string $commitsSince String containing the date of when to look at commits since.
* @return Closure(File):ChangesCountInterface
*/
private function getGitChangesCountProcessBuilder(string $commitsSince): Closure
{
return static function (File $file) use ($commitsSince): ChangesCountInterface {
return new GitChangesCountProcess($file, $commitsSince);
};
}
/**
* @param string $commitsSince String containing the date of when to look at commits since.
* @return Closure(File):ChangesCountInterface
*/
private function getSubversionChangesCountProcessBuilder(string $commitsSince): Closure
{
$dateRange = \sprintf(
'{%s}:{%s}',
\date('Y-m-d', $this->toTime($commitsSince)),
(new DateTime('tomorrow'))->format('Y-m-d')
);
return static function (File $file) use ($dateRange): ChangesCountInterface {
return new SubversionChangesCountProcess($file, $dateRange);
};
}
/**
* @param string $commitsSince String containing the date of when to look at commits since.
* @return Closure(File):ChangesCountInterface
*/
private function getMercurialChangesCountProcessBuilder(string $commitsSince): Closure
{
$date = \date('Y-m-d', $this->toTime($commitsSince));
return static function (File $file) use ($date): ChangesCountInterface {
return new MercurialChangesCountProcess($file, $date);
};
}
/**
* @param string $commitsSince String containing the date of when to look at commits since.
* @return Closure(File):ChangesCountInterface
*/
private function getFossilChangesCountProcessBuilder(string $commitsSince): Closure
{
$date = \date('Y-m-d', $this->toTime($commitsSince));
return static function (File $file) use ($date): ChangesCountInterface {
return new FossilChangesCountProcess($file, $date);
};
}
/**
* Returns a builder for NoVcsChangesCountProcess.
*
* @return Closure(File):ChangesCountInterface
*/
private function getNoVcsChangesCountProcessBuilder(): Closure
{
return static function (File $file): ChangesCountInterface {
return new NoVcsChangesCountProcess($file);
};
}
/**
* Convert a string like "3 years ago" to timestamp.
*
* @param string $commitsSince String containing the date of when to look at commits since.
*/
private function toTime(string $commitsSince): int
{
$time = \strtotime($commitsSince);
Assert::positiveInteger($time, 'Commits since can not be converted to timestamp');
return $time;
}
}