Skip to content

Commit

Permalink
Add support for subversion
Browse files Browse the repository at this point in the history
  • Loading branch information
villfa committed Feb 6, 2021
1 parent d5a474b commit 80d2d12
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 24 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ jobs:
strategy:
matrix:
vcs:
- mercurial
- fossil
- mercurial
- subversion

steps:
- name: "Checkout"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fileExtensions:
- inc

# The version control system used for your project.
# Accepted values: fossil, git, mercurial, none
# Accepted values: fossil, git, mercurial, subversion, none
# Default: git
vcs: git
```
Expand Down
2 changes: 2 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<exclude name="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix"/>
<exclude name="SlevomatCodingStandard.Commenting.RequireOneLineDocComment.MultiLineDocComment"/>
<exclude name="SlevomatCodingStandard.Commenting.RequireOneLinePropertyDocComment.MultiLinePropertyComment"/>
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountAfterControlStructure"/>
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountBeforeControlStructure"/>
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowEmpty.DisallowedEmpty"/>
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowYodaComparison.DisallowedYodaComparison"/>
<exclude name="SlevomatCodingStandard.ControlStructures.NewWithoutParentheses.UselessParentheses"/>
Expand Down
35 changes: 35 additions & 0 deletions src/Process/ChangesCount/SubversionChangesCountProcess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Churn\Process\ChangesCount;

use Churn\File\File;
use Churn\Process\ChangesCountInterface;
use Churn\Process\ChurnProcess;
use Symfony\Component\Process\Process;

class SubversionChangesCountProcess extends ChurnProcess implements ChangesCountInterface
{

/**
* Class constructor.
*
* @param File $file The file the process is being executed on.
* @param string $dateRange String containing a date range formatted for SVN.
*/
public function __construct(File $file, string $dateRange)
{
$process = new Process(['svn', 'log', '-q', '-r', $dateRange, $file->getFullPath()]);

parent::__construct($file, $process);
}

/**
* Returns the number of changes for a file.
*/
public function countChanges(): int
{
return (int) \floor(\substr_count($this->getOutput(), "\n") / 2);
}
}
59 changes: 41 additions & 18 deletions src/Process/ChangesCountProcessBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
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;

class ChangesCountProcessBuilder
Expand All @@ -22,25 +24,20 @@ class ChangesCountProcessBuilder
*/
public function getBuilder(string $vcs, string $commitsSince): Closure
{
if ('git' === $vcs) {
return $this->getGitChangesCountProcessBuilder($commitsSince);
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);
}

if ('mercurial' === $vcs) {
return $this->getMercurialChangesCountProcessBuilder($commitsSince);
}

if ('fossil' === $vcs) {
return $this->getFossilChangesCountProcessBuilder($commitsSince);
}

if ('none' === $vcs) {
return static function (File $file): ChangesCountInterface {
return new NoVcsChangesCountProcess($file);
};
}

throw new InvalidArgumentException('Unsupported VCS: ' . $vcs);
}

/**
Expand All @@ -53,6 +50,22 @@ private function getGitChangesCountProcessBuilder(string $commitsSince): Closure
};
}

/**
* @param string $commitsSince String containing the date of when to look at commits since.
*/
private function getSubversionChangesCountProcessBuilder(string $commitsSince): Closure
{
$dateRange = \sprintf(
'{%s}:{%s}',
\date('Y-m-d', \strtotime($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.
*/
Expand All @@ -76,4 +89,14 @@ private function getFossilChangesCountProcessBuilder(string $commitsSince): Clos
return new FossilChangesCountProcess($file, $date);
};
}

/**
* Returns a builder for NoVcsChangesCountProcess.
*/
private function getNoVcsChangesCountProcessBuilder(): Closure
{
return static function (File $file): ChangesCountInterface {
return new NoVcsChangesCountProcess($file);
};
}
}
57 changes: 57 additions & 0 deletions tests/EndToEnd/SubversionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Churn\Tests\EndToEnd;

use Churn\Command\RunCommand;
use Churn\Tests\BaseTestCase;
use InvalidArgumentException;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class SubversionTest extends BaseTestCase
{
/** @var CommandTester */
private $commandTester;

protected function setUp()
{
$application = new Application('churn-php', 'test');
$application->add(RunCommand::newInstance());
$command = $application->find('run');
$this->commandTester = new CommandTester($command);
}

protected function tearDown()
{
$this->commandTester = null;
}

/** @test */
public function it_works_with_subversion()
{
$exitCode = $this->commandTester->execute([
'paths' => [],
'--configuration' => '/tmp/test',
]);
$display = $this->commandTester->getDisplay();

$expected = "
___ _ _ __ __ ____ _ _ ____ _ _ ____
/ __)( )_( )( )( )( _ \( \( )___( _ \( )_( )( _ \
( (__ ) _ ( )(__)( ) / ) ((___))___/ ) _ ( )___/
\___)(_) (_)(______)(_)\_)(_)\_) (__) (_) (_)(__)
+-------------------+---------------+------------+-------+
| File | Times Changed | Complexity | Score |
+-------------------+---------------+------------+-------+
| /tmp/test/Foo.php | 2 | 1 | 1 |
| /tmp/test/Bar.php | 1 | 1 | 0.5 |
+-------------------+---------------+------------+-------+
";

$this->assertEquals(0, $exitCode);
$this->assertEquals($expected, $display);
}
}
2 changes: 0 additions & 2 deletions tests/docker/fossil/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,3 @@ RUN mkdir -p /tmp/test \
&& fossil commit -m "2nd commit"

COPY churn.yml /tmp/test/

CMD ["bash"]
2 changes: 0 additions & 2 deletions tests/docker/mercurial/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,3 @@ RUN cd /tmp \
&& hg --config ui.username="John Doe" commit Foo.php Bar.php -m "2nd commit"

COPY churn.yml /tmp/test/

CMD ["bash"]
29 changes: 29 additions & 0 deletions tests/docker/subversion/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM php:8.0-cli

# Requirements for running phpunit
RUN apt-get update && apt-get install -y git zip
RUN pecl install xdebug-3.0.2 && docker-php-ext-enable xdebug
ENV XDEBUG_MODE=coverage
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

# Build a subversion project
RUN apt-get install -y subversion

# See: https://subversion.apache.org/quick-start#setting-up-a-local-repo
RUN mkdir -p $HOME/.svnrepos/ \
&& svnadmin create ~/.svnrepos/repo \
&& svn mkdir -m "Create structure." file://$HOME/.svnrepos/repo/trunk file://$HOME/.svnrepos/repo/branches file://$HOME/.svnrepos/repo/tags \
&& mkdir -p /tmp/test \
&& cd /tmp/test \
&& svn checkout file://$HOME/.svnrepos/repo/trunk ./ \
&& svn add --force ./ \
&& svn commit -m "Initial import." \
&& touch Foo.php \
&& svn add Foo.php \
&& svn commit -m "First commit" \
&& echo '<?php class Foo {}' > Foo.php \
&& echo '<?php class Bar {}' > Bar.php \
&& svn add Bar.php \
&& svn commit -m "2nd commit"

COPY churn.yml /tmp/test/
3 changes: 3 additions & 0 deletions tests/docker/subversion/churn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vcs: subversion
directoriesToScan:
- /tmp/test

0 comments on commit 80d2d12

Please sign in to comment.