Skip to content

Commit

Permalink
Merge pull request #22 from mborne/issue_20
Browse files Browse the repository at this point in the history
Add option --include-if-has-file=the-given-file
  • Loading branch information
mborne authored Aug 25, 2018
2 parents ddbed16 + b33d801 commit 5bfadc2
Show file tree
Hide file tree
Showing 15 changed files with 354 additions and 35 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"psr-4": {"": "src/"}
},
"autoload-dev": {
"psr-4": {"MBO\\SatisGitlab\\": "test/functional"}
"psr-4": {"Tests\\SatisGitlab\\": "tests"}
},
"bin": [
"bin/satis-gitlab"
Expand Down
7 changes: 2 additions & 5 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@
>

<testsuites>
<testsuite name="satis-gitlab-functional">
<directory>./tests/functional</directory>
</testsuite>
<testsuite name="satis-gitlab-unit">
<directory>./tests/unit</directory>
<testsuite name="satis-gitlab">
<directory>./tests</directory>
</testsuite>
</testsuites>

Expand Down
56 changes: 31 additions & 25 deletions src/MBO/SatisGitlab/Command/GitlabToConfigCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use MBO\SatisGitlab\Git\ProjectInterface;
use MBO\SatisGitlab\Git\ClientOptions;
use MBO\SatisGitlab\Git\GitlabProject;
use MBO\SatisGitlab\Filter\FilterCollection;
use MBO\SatisGitlab\Filter\IncludeIfHasFileFilter;



Expand Down Expand Up @@ -48,12 +50,15 @@ protected function configure() {
->addArgument('gitlab-token')

/*
* Project listing options
* Project listing options (git level)
*/
->addOption('projectFilter', 'p', InputOption::VALUE_OPTIONAL, 'filter for projects', null)
// ignored projects/namespaces

/*
* Project filters
*/
->addOption('ignore', 'i', InputOption::VALUE_REQUIRED, 'ignore project according to a regexp, for ex : "(^phpstorm|^typo3\/library)"', null)

->addOption('include-if-has-file',null,InputOption::VALUE_REQUIRED, 'include in satis config if project contains a given file, for ex : ".satisinclude"', null)
/*
* satis config generation options
*/
Expand Down Expand Up @@ -91,10 +96,29 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$logger
);


$outputFile = $input->getOption('output');

// warning : this one is a "git client filter"
$projectFilter = $input->getOption('projectFilter');
$ignore = $input->getOption('ignore');

/*
* Create project filters according to input arguments
*/
$filterCollection = new FilterCollection($logger);
/* ignore option */
if ( ! empty($input->getOption('ignore')) ){
$filterCollection->addFilter(new IgnoreRegexpFilter(
$input->getOption('ignore')
));
}
/* include-if-has-file option */
if ( ! empty($input->getOption('include-if-has-file')) ){
$filterCollection->addFilter(new IncludeIfHasFileFilter(
$client,
$input->getOption('include-if-has-file'),
$logger
));
}

/*
* Create configuration builder
Expand Down Expand Up @@ -156,8 +180,8 @@ protected function execute(InputInterface $input, OutputInterface $output) {
foreach ($projects as $project) {
$projectUrl = $project->getHttpUrl();

/* filter according to ignore option */
if ( $this->isIgnored($project, $ignore) ){
/* filter according to command line options */
if ( ! $filterCollection->isAccepted($project) ){
$logger->info(sprintf("Ignoring project %s", $project->getName()));
continue;
}
Expand Down Expand Up @@ -226,24 +250,6 @@ protected function createProjectMessage(
);
}

/**
* Test if project is ignored according to ignore option
*
* @param GitlabProject $project
* @param string $ignore
* @return boolean
*/
protected function isIgnored(GitlabProject $project, $ignore){
if ( empty($ignore) ){
return false;
}
if ( preg_match("/$ignore/", $project->getName() ) ){
return true;
}else{
return false;
}
}

/**
* Create console logger
* @param OutputInterface $output
Expand Down
58 changes: 58 additions & 0 deletions src/MBO/SatisGitlab/Filter/FilterCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace MBO\SatisGitlab\Filter;

use Psr\Log\LoggerInterface;
use MBO\SatisGitlab\Git\ProjectInterface;

/**
* Compose a list of filter to simplify command line integration
*/
class FilterCollection implements ProjectFilterInterface {

/**
* @var ProjectFilterInterface[]
*/
private $filters;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger){
$this->filters = array();
$this->logger = $logger;
}

/**
* Add a filter to the collection
*
* @param ProjectFilterInterface $filter
* @return void
*/
public function addFilter(ProjectFilterInterface $filter){
$this->filters[] = $filter;
}

/**
* {@inheritDoc}
*/
public function isAccepted(ProjectInterface $project){
foreach ( $this->filters as $filter ){
if ( ! $filter->isAccepted($project) ){
$this->logger->debug(sprintf(
"[%s]Ignoring project %s",
get_class($filter),
$project->getName()
));
return false;
}
}
return true;
}
}

35 changes: 35 additions & 0 deletions src/MBO/SatisGitlab/Filter/IgnoreRegexpFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace MBO\SatisGitlab\Filter;

use MBO\SatisGitlab\Git\ProjectInterface;

/**
* Ignore project according to a regular expression
*/
class IgnoreRegexpFilter implements ProjectFilterInterface {

/**
* @var string
*/
protected $ignoreRegexp;

public function __construct($ignoreRegexp)
{
assert(!empty($ignoreRegexp));
$this->ignoreRegexp = $ignoreRegexp;
}

/**
* {@inheritDoc}
*/
public function isAccepted(ProjectInterface $project)
{
if ( preg_match("/$this->ignoreRegexp/", $project->getName() ) ){
return false;
}else{
return true;
}
}

}
60 changes: 60 additions & 0 deletions src/MBO/SatisGitlab/Filter/IncludeIfHasFileFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace MBO\SatisGitlab\Filter;

use MBO\SatisGitlab\Git\ProjectInterface;
use MBO\SatisGitlab\Git\ClientInterface as GitClientInterface;
use Psr\Log\LoggerInterface;

/**
* Accept projects if git contains a given file
*
* TODO add mock based unit tests
*/
class IncludeIfHasFileFilter implements ProjectFilterInterface {

/**
* @var GitClientInterface
*/
protected $gitClient;

/**
* @var string
*/
protected $filePath;

public function __construct(
GitClientInterface $gitClient,
$filePath,
LoggerInterface $logger
)
{
$this->gitClient = $gitClient;
$this->filePath = $filePath;
$this->logger = $logger;
}

/**
* {@inheritDoc}
*/
public function isAccepted(ProjectInterface $project)
{
try {
$this->gitClient->getRawFile(
$project,
$this->filePath,
$project->getDefaultBranch()
);
return true;
}catch(\Exception $e){
$this->logger->debug(sprintf(
'%s (branch %s) : file %s not found',
$project->getName(),
$project->getDefaultBranch(),
$this->filePath
));
return false;
}
}

}
21 changes: 21 additions & 0 deletions src/MBO/SatisGitlab/Filter/ProjectFilterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace MBO\SatisGitlab\Filter;

use MBO\SatisGitlab\Git\ProjectInterface;


/**
* Test if a project should be included in satis config (regexp, )
*/
interface ProjectFilterInterface {

/**
* Returns true if the project should be included in satis configuration
*
* @param ProjectInterface $project
* @return boolean
*/
public function isAccepted(ProjectInterface $project);

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use PHPUnit\Framework\TestCase;
namespace Tests\SatisGitlab\Command;

use Tests\SatisGitlab\TestCase;

use Symfony\Component\Console\Tester\CommandTester;
use MBO\SatisGitlab\Command\GitlabToConfigCommand;
Expand Down Expand Up @@ -35,6 +37,7 @@ public function testWithFilter(){
'gitlab-url' => 'http://gitlab.com',
'gitlab-token' => $gitlabToken,
'--projectFilter' => 'sample-composer',
'--include-if-has-file' => 'README.md',
'--output' => $this->outputFile
));

Expand Down
File renamed without changes.
69 changes: 69 additions & 0 deletions tests/Filter/FilterCollectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Tests\SatisGitlab\Filter;

use Tests\SatisGitlab\TestCase;

use Psr\Log\NullLogger;

use MBO\SatisGitlab\Filter\FilterCollection;
use MBO\SatisGitlab\Git\ProjectInterface;
use MBO\SatisGitlab\Filter\ProjectFilterInterface;

/**
* Test FilterCollection
*/
class FilterCollectionTest extends TestCase {

public function testEmpty(){
$filterCollection = new FilterCollection(new NullLogger());
$project = $this->createMockProject('test');
$this->assertTrue($filterCollection->isAccepted($project));
}

/**
* Create a fake project filter returning true or false
*
* @param boolean $accepted
* @return ProjectFilterInterface
*/
private function createMockFilter($accepted){
$filter = $this->getMockBuilder(ProjectFilterInterface::class)
->getMock()
;
$filter->expects($this->any())
->method('isAccepted')
->willReturn($accepted)
;
return $filter;
}


public function testOneTrue(){
$filterCollection = new FilterCollection(new NullLogger());
$filterCollection->addFilter($this->createMockFilter(true));
$project = $this->createMockProject('test');
$this->assertTrue($filterCollection->isAccepted($project));
}

public function testOneFalse(){
$filterCollection = new FilterCollection(new NullLogger());
$filterCollection->addFilter($this->createMockFilter(false));
$project = $this->createMockProject('test');
$this->assertFalse($filterCollection->isAccepted($project));
}

/**
* Check that isAccepted is unanymous
*/
public function testTrueFalseTrue(){
$filterCollection = new FilterCollection(new NullLogger());
$filterCollection->addFilter($this->createMockFilter(true));
$filterCollection->addFilter($this->createMockFilter(false));
$filterCollection->addFilter($this->createMockFilter(true));
$project = $this->createMockProject('test');
$this->assertFalse($filterCollection->isAccepted($project));
}

}

Loading

0 comments on commit 5bfadc2

Please sign in to comment.