Skip to content

Commit

Permalink
Merge pull request #160 from prolic/vfs
Browse files Browse the repository at this point in the history
add vfs autoloader
  • Loading branch information
prolic authored Jun 30, 2021
2 parents e448fc4 + 9681f0c commit a5b01f3
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 104 deletions.
1 change: 0 additions & 1 deletion bin/fpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env php

<?php
include 'fpp.php';
130 changes: 30 additions & 100 deletions bin/fpp.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,43 @@
namespace Fpp;

use Nette\PhpGenerator\PsrPrinter;
use function Pair;
use Phunkie\Types\Pair;
use org\bovigo\vfs\vfsStream;

if (! isset($argv[1])) {
echo 'Missing input directory or file argument';
exit(1);
}

$path = $argv[1];

$pwd = \realpath(\getcwd());
$path1 = \realpath(__DIR__ . '/../../../../');
$path2 = \realpath(__DIR__ . '/../');
$vendorName = 'vendor';

if (\file_exists($composerPath = "$pwd/composer.json")) {
$composerJson = \json_decode(\file_get_contents($composerPath), true);
$vendorName = isset($composerJson['config']['vendor-dir']) ? $composerJson['config']['vendor-dir'] : $vendorName;
foreach ([$path1, $path2] as $path) {
if (\file_exists($composerPath = "$path/composer.json")) {
$composerJson = \json_decode(\file_get_contents($composerPath), true);
$vendorName = isset($composerJson['config']['vendor-dir']) ? $composerJson['config']['vendor-dir'] : $vendorName;
}

break;
}

if (! \file_exists("$pwd/$vendorName/autoload.php")) {
if (! \file_exists("$path/$vendorName/autoload.php")) {
echo "\033[1;31mYou need to set up the project dependencies using the following commands: \033[0m" . PHP_EOL;
echo 'curl -s http://getcomposer.org/installer | php' . PHP_EOL;
echo 'php composer.phar install' . PHP_EOL;
exit(1);
}

$autoloader = require "$pwd/$vendorName/autoload.php";

$prefixesPsr4 = $autoloader->getPrefixesPsr4();
$prefixesPsr0 = $autoloader->getPrefixes();
$autoloader = require "$path/$vendorName/autoload.php";

$locatePsrPath = function (string $classname) use ($prefixesPsr4, $prefixesPsr0): string {
return locatePsrPath($prefixesPsr4, $prefixesPsr0, $classname);
};

if (\file_exists("$pwd/$vendorName/prolic/fpp/autoload.php")) {
$fppAutoloader = "$pwd/$vendorName/prolic/fpp/autoload.php";
if (\file_exists("$path/$vendorName/prolic/fpp/autoload.php")) {
$fppAutoloader = "$path/$vendorName/prolic/fpp/autoload.php";
} else {
$fppAutoloader = "$pwd/autoload.php";
$fppAutoloader = "$path/autoload.php";
}

require_once $fppAutoloader;

$config = [
'use_strict_types' => true,
'source' => '.',
'target' => 'composer', // composer or vfs
'success_msg' => 'Successfully generated and written to disk',
'printer' => fn () => (new PsrPrinter())->setTypeResolving(false),
'file_parser' => parseFile,
'comment' => 'Generated by prolic/fpp - do not edit !!!',
Expand Down Expand Up @@ -88,6 +81,9 @@
return [
'use_strict_types' => true,
'source' => '.',
'target' => 'composer', // composer or vfs
'success_msg' => 'Successfully generated and written to disk',
'printer' => fn () => (new PsrPrinter())->setTypeResolving(false),
'file_parser' => parseFile,
'comment' => 'Generated by prolic/fpp - do not edit !!!', // put `null` to disable
Expand All @@ -109,88 +105,22 @@
CODE;

\file_put_contents("$pwd/fpp-config.php", $file);
\file_put_contents("$path/fpp-config.php", $file);

echo "Default configuration written to $pwd/fpp-config.php\n";
echo "Default configuration written to $path/fpp-config.php\n";
exit(0);
}

if (\file_exists("$pwd/fpp-config.php")) {
$config = require "$pwd/fpp-config.php";
if (\file_exists("$path/fpp-config.php")) {
$config = require "$path/fpp-config.php";
}

$config = Configuration::fromArray($config);

$parser = \array_reduce(
\array_filter(
$config->types(),
fn (TypeConfiguration $c) => $c->parse() !== null
),
fn (Parser $p, TypeConfiguration $c) => $p->or($c->parse()()),
zero()
);

$definitions = \array_map(
fn ($f) => Pair(($config->fileParser())($parser)->run(\file_get_contents($f)), $f),
scan(
$path
)
);

$definitions = \array_map(
function (Pair $p) {
$parsed = $p->_1;
$filename = $p->_2;

$p = $parsed[0];

if ($p->_2 !== '') {
echo "\033[1;31mSyntax error at file: $filename\033[0m" . PHP_EOL;
echo $p->_2;
exit(1);
}

return $p->_1;
},
$definitions
);

$definitions = \array_reduce(
$definitions,
fn (array $l, array $nds) => \array_merge($l, $nds),
[]
);

$definitions = \array_reduce(
$definitions,
function (array $ds, array $nds) {
foreach ($nds as $n => $d) {
$ds[$n] = $d;
}

return $ds;
},
[],
);

$dumpedDefinitions = [];

foreach ($definitions as $name => $definition) {
$dumpedDefinitions[$name] = dump($definition, $definitions, $config);
}

foreach ($dumpedDefinitions as $name => $files) {
foreach ($files as $fqcn => $code) {
$filename = $locatePsrPath($fqcn);
$directory = \dirname($filename);
$locatePath = $config->target() === 'vfs'
? $config->locatePathFromVfs(vfsStream::setup('quote-exchange-vfs'))
: $config->locatePathFromComposer($autoloader);

if (! \is_dir($directory)) {
\mkdir($directory, 0777, true);
}

\file_put_contents($filename, $code);
}
}
runFpp($config, $config->source(), $locatePath);

echo "Successfully generated and written to disk\n";
exit(0);
echo $config->successMessage() . "\n";
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"php": "^7.4",
"phunkie/phunkie": "^0.11.1",
"nette/php-generator": "^3.4.0",
"nette/utils": "^3.1.2"
"nette/utils": "^3.1.2",
"mikey179/vfsstream": "^1.6.8"
},
"require-dev": {
"kahlan/kahlan": "^4.7.5",
Expand Down
59 changes: 57 additions & 2 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,42 @@
namespace Fpp;

use Closure;
use Composer\Autoload\ClassLoader;
use InvalidArgumentException;
use org\bovigo\vfs\vfsStreamDirectory;
use RuntimeException;

class Configuration
{
private const availableTargets = ['composer', 'vfs'];

private bool $useStrictTypes;
private string $source;
private string $target;
private string $successMessage;
private Closure $printer;
private Closure $fileParser;
private ?string $comment;
/** @var array<class-string,TypeConfiguration> */
private array $types;

/** @param array<class-string,TypeConfiguration> $types */
public function __construct(bool $useStrictTypes, callable $printer, callable $fileParser, ?string $comment, array $types)
public function __construct(bool $useStrictTypes, string $source, string $target, string $successMessage, callable $printer, callable $fileParser, ?string $comment, array $types)
{
if (! \in_array($target, self::availableTargets)) {
throw new InvalidArgumentException(
\sprintf(
'Target must be one of %s, %s given',
\implode(' or ', self::availableTargets),
$target
)
);
}

$this->useStrictTypes = $useStrictTypes;
$this->source = $source;
$this->target = $target;
$this->successMessage = $successMessage;
$this->printer = Closure::fromCallable($printer);
$this->fileParser = Closure::fromCallable($fileParser);
$this->comment = $comment;
Expand All @@ -37,14 +57,17 @@ public function __construct(bool $useStrictTypes, callable $printer, callable $f

public static function fromArray(array $data): self
{
if (! isset($data['use_strict_types'], $data['printer'], $data['file_parser'], $data['comment'], $data['types'])) {
if (! isset($data['use_strict_types'], $data['source'], $data['target'], $data['success_msg'], $data['printer'], $data['file_parser'], $data['comment'], $data['types'])) {
throw new InvalidArgumentException(
'Missing keys in array configuration'
);
}

return new self(
$data['use_strict_types'],
$data['source'],
$data['target'],
$data['success_msg'],
$data['printer'],
$data['file_parser'],
$data['comment'],
Expand Down Expand Up @@ -147,6 +170,38 @@ public function useStrictTypes(): bool
return $this->useStrictTypes;
}

public function source(): string
{
return $this->source;
}

public function target(): string
{
return $this->target;
}

public function locatePathFromComposer(ClassLoader $classLoader): Closure
{
$prefixesPsr4 = $classLoader->getPrefixesPsr4();
$prefixesPsr0 = $classLoader->getPrefixes();

return function (string $classname) use ($prefixesPsr4, $prefixesPsr0): string {
return locatePsrPath($prefixesPsr4, $prefixesPsr0, $classname);
};
}

public function locatePathFromVfs(vfsStreamDirectory $directory): Closure
{
return function (string $classname) use ($directory) {
return $directory->url() . DIRECTORY_SEPARATOR . \strtr($classname, '\\', DIRECTORY_SEPARATOR) . '.php';
};
}

public function successMessage(): string
{
return $this->successMessage;
}

public function printer(): Closure
{
return $this->printer;
Expand Down
92 changes: 92 additions & 0 deletions src/Functions/fpp.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,100 @@
use Fpp\Type\Data\Data;
use Fpp\Type\Enum\Enum;
use Nette\PhpGenerator\PhpFile;
use org\bovigo\vfs\vfsStreamDirectory;
use Phunkie\Types\Pair;

const runFpp = 'Fpp\runFpp';

function runFpp(Configuration $config, string $path, \Closure $locatePath)
{
$parser = \array_reduce(
\array_filter(
$config->types(),
fn (TypeConfiguration $c) => $c->parse() !== null
),
fn (Parser $p, TypeConfiguration $c) => $p->or($c->parse()()),
zero()
);

$definitions = \array_map(
fn ($f) => Pair(($config->fileParser())($parser)->run(\file_get_contents($f)), $f),
scan(
$path
)
);

$definitions = \array_map(
function (Pair $p) {
$parsed = $p->_1;
$filename = $p->_2;

$p = $parsed[0];

if ($p->_2 !== '') {
echo "\033[1;31mSyntax error at file: $filename\033[0m" . PHP_EOL;
echo $p->_2;
exit(1);
}

return $p->_1;
},
$definitions
);

$definitions = \array_reduce(
$definitions,
fn (array $l, array $nds) => \array_merge($l, $nds),
[]
);

$definitions = \array_reduce(
$definitions,
function (array $ds, array $nds) {
foreach ($nds as $n => $d) {
$ds[$n] = $d;
}

return $ds;
},
[],
);

$dumpedDefinitions = [];

foreach ($definitions as $name => $definition) {
$dumpedDefinitions[$name] = dump($definition, $definitions, $config);
}

foreach ($dumpedDefinitions as $name => $files) {
foreach ($files as $fqcn => $code) {
$filename = $locatePath($fqcn);
$directory = \dirname($filename);

if (! \is_dir($directory)) {
\mkdir($directory, 0777, true);
}

\file_put_contents($filename, $code);
}
}
}

const registerVfsAutoloader = 'Fpp\registerVfsAutoloader';

function registerVfsAutoloader(vfsStreamDirectory $vfs)
{
\spl_autoload_register(
function (string $className) use ($vfs) {
$file = $vfs->url() . DIRECTORY_SEPARATOR . \strtr($className, '\\', DIRECTORY_SEPARATOR) . '.php';

if (\file_exists($file)) {
require_once $file;
}
}
);
}

const flatMap = 'Fpp\flatMap';

function flatMap(callable $f, array $arr): array
Expand Down

0 comments on commit a5b01f3

Please sign in to comment.