Commit 04251478 authored by Daniel Hürtgen's avatar Daniel Hürtgen

Merge branch '30-implement-phpcodesniffer-standards-finder-service' into 'develop'

Implement PHPCodeSniffer Standards Finder Service

Closes #30

See merge request !32
parents 6b920417 c7a9432f
Pipeline #150 failed with stage
in 3 minutes and 58 seconds
......@@ -22,21 +22,26 @@ namespace Higidi\ComposerPhpCSStandardsPlugin;
*/
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Installer\BinaryInstaller;
use Composer\Installer\LibraryInstaller;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Util\Filesystem;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standard;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Finder;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Standard;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standards;
use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
use Symfony\Component\Finder\Finder;
class Installer extends LibraryInstaller
{
const TYPE = 'phpcodesniffer-standard';
/**
* @var Finder
*/
protected $finder;
/**
* Initializes library installer.
*
......@@ -53,9 +58,11 @@ class Installer extends LibraryInstaller
Composer $composer,
$type = self::TYPE,
Filesystem $filesystem = null,
BinaryInstaller $binaryInstaller = null
BinaryInstaller $binaryInstaller = null,
Finder $finder
) {
parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller);
$this->finder = $finder ?: new Finder();
}
/**
......@@ -199,17 +206,7 @@ class Installer extends LibraryInstaller
*/
protected function findStandards($basePath)
{
$standards = new Standards();
$finder = new Finder();
$finder
->in($basePath . '/**/Standards/*/')
->files()->name('ruleset.xml');
foreach ($finder as $ruleSetFile) {
$standard = new Standard($ruleSetFile->getPath());
$standards->addStandard($standard);
}
return $standards;
return $this->finder->in($basePath);
}
/**
......
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standards;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Factory;
use Higidi\ComposerPhpCSStandardsPlugin\Symfony\Finder\Factory as FinderFactory;
use Symfony\Component\Finder\Finder as SymfonyFinder;
/**
* Standards finder class.
*/
class Finder
{
/**
* @var FinderFactory
*/
protected $finderFactory;
/**
* @var Factory
*/
protected $factory;
/**
* @param FinderFactory|null $finderFactory
* @param Factory|null $factory
*/
public function __construct(FinderFactory $finderFactory = null, Factory $factory = null)
{
$this->finderFactory = $finderFactory ?: new FinderFactory();
$this->factory = $factory ?: new Factory();
}
/**
* Find and return PHPCodeSniffer standards.
*
* @param string $path
* @return Standards
*/
public function in($path)
{
$finder = $this->getSymfonyFinder()
->in($path)
->files()
->name('ruleset.xml')
->sortByName();
$paths = iterator_to_array($finder, false);
$paths = array_map(
function (\SplFileInfo $file) {
return $file->getPath();
},
$paths
);
return $this->createStandardsFromPaths($paths);
}
/**
* Creates new symfony finder instance.
*
* @return SymfonyFinder
*/
protected function getSymfonyFinder()
{
return $this->finderFactory->create();
}
/**
* Creates PHPCodeSniffer standards from paths.
*
* @param array $path
* @return Standards
*/
protected function createStandardsFromPaths(array $paths)
{
return $this->factory->create($paths);
}
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Factory as StandardFactory;
/**
* Standards class factory.
*/
class Factory
{
/**
* @var StandardFactory
*/
protected $standardFactory;
/**
* @param StandardFactory|null $standardFactory
*/
public function __construct(StandardFactory $standardFactory = null)
{
$this->standardFactory = $standardFactory ?: new StandardFactory();
}
/**
* Creates PHPCodeSniffer standards from paths.
*
* @param array $paths Paths with PHPCodeSniffer standard paths.
* @return Standards PHPCodeSniffer standards object.
*/
public function create(array $paths)
{
$standards = new Standards();
foreach ($paths as $path) {
$standards->addStandard($this->standardFactory->create($path));
}
return $standards;
}
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Exception;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* Invalid standard exception.
*/
class InvalidStandardException extends \InvalidArgumentException
{
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Exception;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* Standard path access denied exception.
*/
class StandardPathAccessDeniedException extends \UnexpectedValueException
{
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* Standards class factory.
*/
class Factory
{
/**
* Creates PHPCodeSniffer standard from path.
*
* @param string $path Path to the PHPCodeSniffer standard.
* @return Standard PHPCodeSniffer standard object.
*/
public function create($path)
{
return new Standard($path);
}
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer;
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
......@@ -21,7 +21,13 @@ namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer;
* 02110-1301, USA.
*/
class Standard
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Exception\InvalidStandardException;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\Exception\StandardPathAccessDeniedException;
/**
* Class for PHPCodeSniffer standards.
*/
class Standard implements StandardInterface
{
const RULESET_FILENAME = 'ruleset.xml';
......@@ -41,19 +47,30 @@ class Standard
protected $ruleSetXmlPath;
/**
* @param $path
* @param string $path
*/
public function __construct($path)
{
$path = rtrim($path, DIRECTORY_SEPARATOR);
$pathParts = explode(DIRECTORY_SEPARATOR, $path);
$this->name = array_pop($pathParts);
$this->path = $path;
$this->ruleSetXmlPath = $path . DIRECTORY_SEPARATOR . 'ruleset.xml';
if (!is_readable($path)) {
throw new StandardPathAccessDeniedException(
sprintf('Standard path "%s" is not accessable.', $path)
);
}
$this->path = realpath($path);
$this->name = basename($this->path);
$this->ruleSetXmlPath = $path . DIRECTORY_SEPARATOR . static::RULESET_FILENAME;
if (!is_readable($this->ruleSetXmlPath)) {
throw new InvalidStandardException(
sprintf('Standard "%s" doesn\'t contain a "ruleset.xml" file.', $this->name)
);
}
}
/**
* @return string
* Get the name of the PHPCodeSniffer standard.
*
* @return string The name of the PHPCodeSniffer standard.
*/
public function getName()
{
......@@ -61,7 +78,9 @@ class Standard
}
/**
* @return string
* Get the path to PHPCodeSniffer standard.
*
* @return string The path to the PHPCodeSniffer standard.
*/
public function getPath()
{
......@@ -69,7 +88,9 @@ class Standard
}
/**
* @return string
* Get the path to the PHPCodeSniffer ruleset.xml file.
*
* @return string The path to the PHPCodeSniffer ruleset.xml file.
*/
public function getRuleSetXmlPath()
{
......
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* Interface for PHPCodeSniffer standards.
*/
interface StandardInterface
{
/**
* Get the name of the PHPCodeSniffer standard.
*
* @return string The name of the PHPCodeSniffer standard.
*/
public function getName();
/**
* Get the path to PHPCodeSniffer standard.
*
* @return string The path to the PHPCodeSniffer standard.
*/
public function getPath();
/**
* Get the path to the PHPCodeSniffer ruleset.xml file.
*
* @return string The path to the PHPCodeSniffer ruleset.xml file.
*/
public function getRuleSetXmlPath();
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer;
namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
......@@ -21,16 +21,18 @@ namespace Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer;
* 02110-1301, USA.
*/
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Standard\StandardInterface;
class Standards implements \Iterator
{
/**
* @var array|Standard[]
* @var StandardInterface[]
*/
protected $standards;
/**
* @param array $standards
* @param StandardInterface[] $standards
*/
public function __construct(array $standards = array())
{
......@@ -40,10 +42,10 @@ class Standards implements \Iterator
}
/**
* @param Standard $standard
* @param StandardInterface $standard
* @return $this
*/
public function addStandard(Standard $standard)
public function addStandard(StandardInterface $standard)
{
$this->standards[$standard->getName()] = $standard;
......@@ -51,7 +53,7 @@ class Standards implements \Iterator
}
/**
* @param string|Standard $standard
* @param string|StandardInterface $standard
* @return bool
*/
public function hasStandard($standard)
......@@ -60,7 +62,7 @@ class Standards implements \Iterator
}
/**
* @param string|Standard $standard
* @param string|StandardInterface $standard
* @return $this
*/
public function removeStandard($standard)
......@@ -73,8 +75,8 @@ class Standards implements \Iterator
}
/**
* @param string|Standard $standard
* @return Standard|null
* @param string|StandardInterface $standard
* @return StandardInterface|null
*/
public function getStandard($standard)
{
......@@ -86,7 +88,7 @@ class Standards implements \Iterator
}
/**
* @return array|Standard[]
* @return array|StandardInterface[]
*/
public function getStandards()
{
......@@ -94,12 +96,12 @@ class Standards implements \Iterator
}
/**
* @param string|Standard $standard
* @param string|StandardInterface $standard
* @return string
*/
protected function getStandardName($standard)
{
if ($standard instanceof Standard) {
if ($standard instanceof StandardInterface) {
return $standard->getName();
}
......@@ -109,7 +111,7 @@ class Standards implements \Iterator
/**
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
* @return Standard Can return any type.
* @return StandardInterface Can return any type.
* @since 5.0.0
*/
public function current()
......
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\Symfony\Finder;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Symfony\Component\Finder\Finder;
/**
* Symfony finder factory class.
*/
class Factory
{
/**
* Creates new symfony finder instance.
*
* @return Finder
*/
public function create()
{
return Finder::create();
}
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\Tests\Integration\PHPCodeSniffer\Standard;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Finder;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Factory;
/**
* Integration test case for class \Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Finder
*/
class FinderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Finder
*/
protected $fixture;
/**
* @var Factory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $standardsFactoryMock;
protected function setUp()
{
parent::setUp();
$this->standardsFactoryMock = $this->getMock(
'Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Factory',
array(),
array(),
'',
false
);
$this->fixture = new Finder(null, $this->standardsFactoryMock);
}
protected function tearDown()
{
parent::tearDown();
unset($this->fixture);
unset($this->standardsFactoryMock);
}
public function testFinder()
{
$path = realpath(implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', '..', '..', 'Fixtures', 'Standards')));
$expected = array(
$path . DIRECTORY_SEPARATOR . 'Standard1',
$path . DIRECTORY_SEPARATOR . 'Standard2',
$path . DIRECTORY_SEPARATOR . 'Standard3',
);
$this->standardsFactoryMock
->expects($this->once())
->method('create')
->with($expected);
$this->fixture->in($path);
}
}
<?php
namespace Higidi\ComposerPhpCSStandardsPlugin\Tests\Unit\PHPCodeSniffer\Standards\Standard;
/*
* Copyright (C) 2017 Daniel Hürtgen <daniel@higidi.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Finder;
use Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Standards\Factory;
use Higidi\ComposerPhpCSStandardsPlugin\Symfony\Finder\Factory as SymfonyFinderFactory;
use Symfony\Component\Finder\Finder as SymfonyFinder;
/**
* Test case for class \Higidi\ComposerPhpCSStandardsPlugin\PHPCodeSniffer\Finder
*/
class FinderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Finder
*/
protected $classUnderTesting;
/**
* @var SymfonyFinderFactory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $symfonyFinderFactoryMock;
/**
* @var SymfonyFinder|\PHPUnit_Framework_MockObject_MockObject
*/
protected $symfonyFinderMock;
/**
* @var Factory|\PHPUnit_Framework_MockObject_MockObject
*/
protected $standardsFactoryMock;
protected function setUp()
{
parent::setUp();
$this->symfonyFinderFactoryMock = $this->getMock(
'Higidi\ComposerPhpCSStandardsPlugin\Symfony\Finder\Factory'