-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a site spec parser and tests for same.
- Loading branch information
1 parent
5836287
commit 0d8108c
Showing
4 changed files
with
330 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<?php | ||
namespace Drush\SiteAlias; | ||
|
||
class SiteSpecParserTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @dataProvider parserTestValues | ||
*/ | ||
public function testSiteSpecParser( | ||
$spec, | ||
$expected) | ||
{ | ||
$root = dirname(__DIR__) . '/fixtures/sites/d8'; | ||
$parser = new SiteSpecParser($root); | ||
|
||
$result = $parser->parse($spec); | ||
if (isset($result['root'])) { | ||
$result['root'] = preg_replace('%.*/fixtures/%', '/fixtures/', $result['root']); | ||
} | ||
$this->assertEquals($expected, $result); | ||
} | ||
|
||
/** | ||
* @dataProvider validSiteSpecs | ||
*/ | ||
public function testValidSiteSpecs($spec) | ||
{ | ||
$this->isSpecValid($spec, true); | ||
} | ||
|
||
/** | ||
* @dataProvider invalidSiteSpecs | ||
*/ | ||
public function testInvalidSiteSpecs($spec) | ||
{ | ||
$this->isSpecValid($spec, false); | ||
} | ||
|
||
protected function isSpecValid($spec, $expected) | ||
{ | ||
$parser = new SiteSpecParser(); | ||
|
||
$result = $parser->valid($spec); | ||
$this->assertEquals($expected, $result); | ||
} | ||
|
||
public static function validSiteSpecs() | ||
{ | ||
return [ | ||
[ '/path/to/drupal#sitename' ], | ||
[ 'user@server/path/to/drupal#sitename' ], | ||
[ 'user@server/path/to/drupal' ], | ||
[ 'user@server#sitename' ], | ||
[ '#sitename' ], | ||
]; | ||
} | ||
|
||
public static function invalidSiteSpecs() | ||
{ | ||
return [ | ||
[ 'sitename' ], | ||
[ '@/#' ], | ||
[ 'user@#sitename' ], | ||
[ '@server/path/to/drupal#sitename' ], | ||
[ 'user@server/path/to/drupal#' ], | ||
[ 'user@server/path/to/drupal#sitename!' ], | ||
[ 'user@server/path/to/drupal##sitename' ], | ||
[ 'user#server/path/to/drupal#sitename' ], | ||
]; | ||
} | ||
|
||
public static function parserTestValues() | ||
{ | ||
return [ | ||
[ | ||
'user@server/path#somemultisite', | ||
[ | ||
'remote-user' => 'user', | ||
'remote-server' => 'server', | ||
'root' => '/path', | ||
'sitename' => 'somemultisite', | ||
], | ||
], | ||
|
||
[ | ||
'user@server/path', | ||
[ | ||
'remote-user' => 'user', | ||
'remote-server' => 'server', | ||
'root' => '/path', | ||
'sitename' => 'default', | ||
], | ||
], | ||
|
||
[ | ||
'/path#somemultisite', | ||
[ | ||
'remote-user' => '', | ||
'remote-server' => '', | ||
'root' => '/path', | ||
'sitename' => 'somemultisite', | ||
], | ||
], | ||
|
||
[ | ||
'#somemultisite', | ||
[ | ||
], | ||
], | ||
|
||
[ | ||
'#mymultisite', | ||
[ | ||
'remote-user' => '', | ||
'remote-server' => '', | ||
'root' => '/fixtures/sites/d8', | ||
'sitename' => 'mymultisite', | ||
], | ||
], | ||
|
||
]; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
<?php | ||
namespace Drush\SiteAlias; | ||
|
||
/** | ||
* Parse a string that contains a site specification. | ||
* | ||
* Site specifications contain some of the following elements: | ||
* - remote-user | ||
* - remote-server | ||
* - path | ||
* - sitename | ||
*/ | ||
class SiteSpecParser | ||
{ | ||
protected $root; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param string $root | ||
* Drupal root (if provided) | ||
*/ | ||
public function __construct($root = '') | ||
{ | ||
$this->root = $root; | ||
} | ||
|
||
/** | ||
* Parse a site specification | ||
* | ||
* @param string $spec | ||
* A site specification in one of the accepted forms: | ||
* - /path/to/drupal#sitename | ||
* - user@server/path/to/drupal#sitename | ||
* - user@server/path/to/drupal | ||
* - user@server#sitename | ||
* or, a site name: | ||
* - #sitename | ||
* @return array | ||
* A site specification array with the specified components filled in: | ||
* - remote-user | ||
* - remote-server | ||
* - path | ||
* - sitename | ||
* or, an empty array if the provided parameter is not a valid site spec. | ||
*/ | ||
public function parse($spec) | ||
{ | ||
return $this->validate($this->match($spec)); | ||
} | ||
|
||
/** | ||
* Determine if the provided specification is value. | ||
* | ||
* @param string $spec | ||
* @see parse() | ||
* @return bool | ||
*/ | ||
public function valid($spec) | ||
{ | ||
$result = $this->match($spec); | ||
return !empty($result); | ||
} | ||
|
||
/** | ||
* Return the set of regular expression patterns that match the available | ||
* site specification formats. | ||
* | ||
* @return array | ||
* key: site specification regex | ||
* value: an array mapping from site specification component names to | ||
* the elements in the 'matches' array containing the data for that element. | ||
*/ | ||
protected function patterns() | ||
{ | ||
return [ | ||
// /path/to/drupal#sitename | ||
'%^(/[^#]*)#([a-zA-Z0-9_-]+)$%' => [ | ||
'root' => 1, | ||
'sitename' => 2, | ||
], | ||
// user@server/path/to/drupal#sitename | ||
'%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)(/[^#]*)#([a-zA-Z0-9_-]+)$%' => [ | ||
'remote-user' => 1, | ||
'remote-server' => 2, | ||
'root' => 3, | ||
'sitename' => 4, | ||
], | ||
// user@server/path/to/drupal | ||
'%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)(/[^#]*)$%' => [ | ||
'remote-user' => 1, | ||
'remote-server' => 2, | ||
'root' => 3, | ||
'sitename' => 'default', // Or '2' if sitename should be 'server' | ||
], | ||
// user@server#sitename | ||
'%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)#([a-zA-Z0-9_-]+)$%' => [ | ||
'remote-user' => 1, | ||
'remote-server' => 2, | ||
'sitename' => 3, | ||
], | ||
// #sitename | ||
'%^#([a-zA-Z0-9_-]+)$%' => [ | ||
'sitename' => 1, | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Run through all of the available regex patterns and determine if | ||
* any match the provided specification. | ||
* | ||
* @return array | ||
* @see parse() | ||
*/ | ||
protected function match($spec) | ||
{ | ||
foreach ($this->patterns() as $regex => $map) { | ||
if (preg_match($regex, $spec, $matches)) { | ||
return $this->mapResult($map, $matches); | ||
} | ||
} | ||
return []; | ||
} | ||
|
||
/** | ||
* Inflate the provided array so that it always contains the required | ||
* elements. | ||
* | ||
* @return array | ||
* @see parse() | ||
*/ | ||
protected function defaults($result = []) | ||
{ | ||
$result += [ | ||
'remote-user' => '', | ||
'remote-server' => '', | ||
'root' => '', | ||
'sitename' => '', | ||
]; | ||
|
||
return $result; | ||
} | ||
|
||
/** | ||
* Take the data from the matches from the regular expression and | ||
* plug them into the result array per the info in the provided map. | ||
* | ||
* @param array $map | ||
* An array mapping from result key to matches index. | ||
* @param array $matches | ||
* The matched strings returned from preg_match | ||
* @return array | ||
* @see parse() | ||
*/ | ||
protected function mapResult($map, $matches) | ||
{ | ||
$result = []; | ||
|
||
foreach ($map as $key => $index) { | ||
$value = is_string($index) ? $index : $matches[$index]; | ||
$result[$key] = $value; | ||
} | ||
|
||
if (empty($result)) { | ||
return []; | ||
} | ||
|
||
return $this->defaults($result); | ||
} | ||
|
||
/** | ||
* Validate the provided result. If the result is local, then it must | ||
* have a 'root'. If it does not, then fill in the root that was provided | ||
* to us in our consturctor. | ||
* | ||
* @param array $result | ||
* @see parse() result. | ||
* @return array | ||
* @see parse() | ||
*/ | ||
protected function validate($result) | ||
{ | ||
if (empty($result) || !empty($result['remote-server'])) { | ||
return $result; | ||
} | ||
|
||
if (empty($result['root'])) { | ||
// TODO: should these throw an exception, so the user knows | ||
// why their site spec was invalid? | ||
if (empty($this->root) || !is_dir($this->root)) { | ||
return []; | ||
} | ||
|
||
$path = $this->root . '/sites/' . $result['sitename']; | ||
if (!is_dir($path)) { | ||
return []; | ||
} | ||
|
||
$result['root'] = $this->root; | ||
return $result; | ||
} | ||
|
||
return $result; | ||
} | ||
} |