proof of concept

This commit is contained in:
Damian Mooyman 2016-09-12 17:37:50 +12:00
parent cb59153dd0
commit d715b1a779
2 changed files with 93 additions and 12 deletions

15
.editorconfig Normal file
View File

@ -0,0 +1,15 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# PHP PSR-2 Coding Standards
# http://www.php-fig.org/psr/psr-2/
root = true
[*.php]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

View File

@ -9,6 +9,11 @@ use Composer\IO\IOInterface;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface; use Composer\Repository\InstalledRepositoryInterface;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use FilesystemIterator;
use Iterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use RegexIterator;
class RecipeInstaller extends LibraryInstaller { class RecipeInstaller extends LibraryInstaller {
public function __construct( public function __construct(
@ -25,19 +30,80 @@ class RecipeInstaller extends LibraryInstaller {
{ {
parent::install($repo, $package); parent::install($repo, $package);
// Install recipe skeleton // Copy project files to root
var_dump("Package info:\n"); $destinationPath = getcwd();
var_dump($package); $name = $package->getName();
var_dump($this->getInstallPath($package)); $extra = $package->getExtra();
var_dump($package->getExtra()); if (isset($extra['project-files'])) {
$this->installProjectFiles($name, $this->getInstallPath($package), $destinationPath, $extra['project-files']);
var_dump("Repo info:\n");
var_dump($repo);
if(file_exists('composer.json')) {
var_dump(file_get_contents('composer.json'));
} }
}
var_dump("Installer info:\n"); /**
var_dump($this); * Install project files in the specified directory
*
* @param string $recipe Recipe name
* @param string $sourceRoot Base of source files (no trailing slash)
* @param string $destinationRoot Base of destination directory (no trailing slash)
* @param array $filePatterns List of file patterns in wildcard format (e.g. `code/My*.php`)
*/
public function installProjectFiles($recipe, $sourceRoot, $destinationRoot, $filePatterns)
{
$fileIterator = $this->getFileIterator($sourceRoot, $filePatterns);
foreach($fileIterator as $path => $info) {
$relativePath = substr($path, strlen($sourceRoot));
$destination = $destinationRoot . $relativePath;
// Only copy non-existent files
if (file_exists($destination)) {
continue;
}
$this->io->write("Installing recipe <info>$recipe</info> file <info>$relativePath</info>");
$this->filesystem->ensureDirectoryExists(dirname($destination));
file_put_contents($destination, file_get_contents($path));
}
}
/**
* Get iterator of matching source files to copy
*
* @param string $sourceRoot Root directory of sources (no trailing slash)
* @param array $patterns List of wildcard patterns to match
* @return Iterator File iterator, where key is path and value is file info object
*/
public function getFileIterator($sourceRoot, $patterns) {
// Build regexp pattern
$expressions = [];
foreach($patterns as $pattern) {
$expressions[] = $this->globToRegexp($pattern);
}
$regExp = '#' . $this->globToRegexp($sourceRoot . '/').'(('.implode(')|(', $expressions).'))#';
// Build directory iterator
$directoryIterator = new RecursiveDirectoryIterator(
$sourceRoot,
FilesystemIterator::SKIP_DOTS
| FilesystemIterator::UNIX_PATHS
| FilesystemIterator::KEY_AS_PATHNAME
| FilesystemIterator::CURRENT_AS_FILEINFO
);
// Return filtered iterator
$iterator = new RecursiveIteratorIterator($directoryIterator);
return new RegexIterator($iterator, $regExp);
}
/**
* Convert glob pattern to regexp
*
* @param string $glob
* @return string
*/
protected function globToRegexp($glob) {
$sourceParts = explode('*', $glob);
$regexParts = array_map(function($part) {
return preg_quote($part, '#');
}, $sourceParts);
return implode('(.+)', $regexParts);
} }
} }