Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to identify callable by either name or order #54

Closed
wants to merge 1 commit into from

Conversation

llaville
Copy link

Hello,

With this PR I will allow to identify list of callables, either by order (int: default behavior), but also by a name (string: new behavior).

Hope you will be agree with my proposal.
I'm begin with Pest on this PR. So, if we can do better tests, I'll happy to hear you !

And now a use case to proove a real use case (at least for me). Based on https://github.com/composer-unused/symbol-parser project.

I want to retrieve all symbols (classes, interfaces, functions, constants) from a data source (file list get by the Symfony Finder).
But rather to use task order to identify values in $results array, I wanted to have an array with each file name of the data source as task identifer.

WDYT about this proposal ?

My Use Case
<?php declare(strict_types=1);

use Bartlett\Sandbox\Service\Profiler;
use Bartlett\Sandbox\Service\SourceProvider;
use ComposerUnused\SymbolParser\Parser\PHP\ConsumedSymbolCollector;
use ComposerUnused\SymbolParser\Parser\PHP\Strategy\UsedExtensionSymbolStrategy;
use ComposerUnused\SymbolParser\Parser\PHP\SymbolNameParser;
use PhpParser\NodeVisitor\NameResolver;
use PhpParser\ParserFactory;
use Psr\Log\NullLogger;
use Spatie\Fork\Fork;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Stopwatch\Stopwatch;

require __DIR__ . '/../../vendor/autoload.php';

$stopWatch = new Stopwatch();

$commandName = basename(__FILE__);

$out = new ConsoleOutput();
$section1 = $out->section();

$profiler = new Profiler($stopWatch, $section1);
$profiler->onConsoleCommand($commandName);

// --------------------------------------------------------------------------------------------------------------------
$section1->writeln("Begin Line >>>");

$dataSource = __DIR__ . '/../php-compatinfo/vendors/bartlett/php-compatinfo-db/src/Presentation';

$finder = SourceProvider::getFinder($dataSource, []);

$symbolParser = new SymbolNameParser(
    (new ParserFactory())->create(ParserFactory::ONLY_PHP7),
    new NameResolver(),
    new ConsumedSymbolCollector(
        [
            new UsedExtensionSymbolStrategy(
                get_loaded_extensions(),
                new NullLogger()
            ),
        ]
    )
);

$callables = [];

foreach ($finder as $fileInfo) {
    $taskId = $fileInfo->getRelativePathname();
    $callables[] = function () use($fileInfo, $symbolParser) {
        return iterator_to_array(
            $symbolParser->parseSymbolNames($fileInfo->getContents())
        );
    };
}

$results = Fork::new()
    ->before(null, fn($task) => $section1->writeln(sprintf('Task %s : %s', $task->order(), $task->name())))
    ->run(...$callables)
;

var_dump($results);

$section1->writeln("End line <<<");
// --------------------------------------------------------------------------------------------------------------------

$profiler->onConsoleTerminate($commandName);
Tasks identified by order : `$callables[]` syntax in PHP script
Begin Line >>>
Task 0 : 0
Task 1 : 1
Task 2 : 2
Task 3 : 3
Task 4 : 4
Task 5 : 5
Task 6 : 6
Task 7 : 7
Task 8 : 8
Task 9 : 9
Task 10 : 10
Task 11 : 11
Task 12 : 12
Task 13 : 13
Task 14 : 14
Task 15 : 15
Task 16 : 16
Task 17 : 17
Task 18 : 18
Task 19 : 19
Task 20 : 20
Task 21 : 21
/shared/backups/bartlett/sandbox/src/fork/consumed_symbols.php:63:
array(22) {
  [1] =>
  array(0) {
  }
  [4] =>
  array(2) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(11) "array_shift"
  }
  [10] =>
  array(3) {
    [0] =>
    string(4) "Phar"
    [1] =>
    string(8) "in_array"
    [2] =>
    string(9) "get_class"
  }
  [0] =>
  array(3) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(11) "PHP_VERSION"
    [2] =>
    string(9) "php_uname"
  }
  [6] =>
  array(1) {
    [0] =>
    string(7) "sprintf"
  }
  [9] =>
  array(1) {
    [0] =>
    string(4) "trim"
  }
  [2] =>
  array(1) {
    [0] =>
    string(7) "sprintf"
  }
  [7] =>
  array(7) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(6) "substr"
    [2] =>
    string(5) "ltrim"
    [3] =>
    string(5) "count"
    [4] =>
    string(15) "str_starts_with"
    [5] =>
    string(7) "stripos"
    [6] =>
    string(11) "str_replace"
  }
  [14] =>
  array(0) {
  }
  [3] =>
  array(10) {
    [0] =>
    string(3) "min"
    [1] =>
    string(19) "DIRECTORY_SEPARATOR"
    [2] =>
    string(13) "func_num_args"
    [3] =>
    string(12) "func_get_arg"
    [4] =>
    string(8) "is_array"
    [5] =>
    string(12) "array_values"
    [6] =>
    string(8) "wordwrap"
    [7] =>
    string(7) "sprintf"
    [8] =>
    string(9) "array_map"
    [9] =>
    string(8) "vsprintf"
  }
  [8] =>
  array(9) {
    [0] =>
    string(11) "json_encode"
    [1] =>
    string(17) "JSON_PRETTY_PRINT"
    [2] =>
    string(7) "sprintf"
    [3] =>
    string(5) "count"
    [4] =>
    string(7) "natsort"
    [5] =>
    string(12) "array_values"
    [6] =>
    string(6) "strpos"
    [7] =>
    string(4) "trim"
    [8] =>
    string(6) "substr"
  }
  [11] =>
  array(0) {
  }
  [12] =>
  array(3) {
    [0] =>
    string(4) "date"
    [1] =>
    string(4) "trim"
    [2] =>
    string(10) "strtolower"
  }
  [15] =>
  array(2) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(5) "count"
  }
  [19] =>
  array(0) {
  }
  [5] =>
  array(6) {
    [0] =>
    string(9) "array_map"
    [1] =>
    string(10) "strcasecmp"
    [2] =>
    string(10) "phpversion"
    [3] =>
    string(15) "version_compare"
    [4] =>
    string(7) "sprintf"
    [5] =>
    string(5) "count"
  }
  [20] =>
  array(0) {
  }
  [13] =>
  array(2) {
    [0] =>
    string(4) "trim"
    [1] =>
    string(7) "sprintf"
  }
  [21] =>
  array(0) {
  }
  [16] =>
  array(2) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(11) "array_shift"
  }
  [18] =>
  array(3) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(4) "trim"
    [2] =>
    string(11) "array_shift"
  }
  [17] =>
  array(10) {
    [0] =>
    string(4) "trim"
    [1] =>
    string(7) "sprintf"
    [2] =>
    string(5) "count"
    [3] =>
    string(12) "array_unique"
    [4] =>
    string(7) "explode"
    [5] =>
    string(5) "ksort"
    [6] =>
    string(12) "SORT_NATURAL"
    [7] =>
    string(13) "method_exists"
    [8] =>
    string(7) "implode"
    [9] =>
    string(13) "array_unshift"
  }
}
End line <<<

Time: 235 ms, Memory: 14.00Mb
Tasks identified by name : `$callables[$taskId]` syntax in PHP script
Begin Line >>>
Task 0 : Console/Output/PrintDiagnose.php
Task 1 : Console/Output/Output.php
Task 2 : Console/Application.php
Task 3 : Console/Style.php
Task 4 : Console/Command/CreateCommand.php
Task 5 : Console/Command/ListCommand.php
Task 6 : Console/Command/AboutCommand.php
Task 7 : Console/Command/Debug/ContainerDebugCommand.php
Task 8 : Console/Command/DoctorCommand.php
Task 9 : Console/Command/BuildCommand.php
Task 10 : Console/Command/FactoryCommandLoader.php
Task 11 : Console/Command/AbstractCommand.php
Task 12 : Console/Command/ReleaseCommand.php
Task 13 : Console/Command/PolyfillCommand.php
Task 14 : Console/Command/CommandInterface.php
Task 15 : Console/Command/DiagnoseCommand.php
Task 16 : Console/Command/NewCommand.php
Task 17 : Console/Command/ShowCommand.php
Task 18 : Console/Command/InitCommand.php
Task 19 : Console/StyleInterface.php
Task 20 : Console/ApplicationInterface.php
Task 21 : Console/Input/Input.php
/shared/backups/bartlett/sandbox/src/fork/consumed_symbols.php:65:
array(22) {
  'Console/Output/Output.php' =>
  array(0) {
  }
  'Console/Command/FactoryCommandLoader.php' =>
  array(3) {
    [0] =>
    string(4) "Phar"
    [1] =>
    string(8) "in_array"
    [2] =>
    string(9) "get_class"
  }
  'Console/Application.php' =>
  array(1) {
    [0] =>
    string(7) "sprintf"
  }
  'Console/Output/PrintDiagnose.php' =>
  array(3) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(11) "PHP_VERSION"
    [2] =>
    string(9) "php_uname"
  }
  'Console/Style.php' =>
  array(10) {
    [0] =>
    string(3) "min"
    [1] =>
    string(19) "DIRECTORY_SEPARATOR"
    [2] =>
    string(13) "func_num_args"
    [3] =>
    string(12) "func_get_arg"
    [4] =>
    string(8) "is_array"
    [5] =>
    string(12) "array_values"
    [6] =>
    string(8) "wordwrap"
    [7] =>
    string(7) "sprintf"
    [8] =>
    string(9) "array_map"
    [9] =>
    string(8) "vsprintf"
  }
  'Console/Command/AboutCommand.php' =>
  array(1) {
    [0] =>
    string(7) "sprintf"
  }
  'Console/Command/ListCommand.php' =>
  array(6) {
    [0] =>
    string(9) "array_map"
    [1] =>
    string(10) "strcasecmp"
    [2] =>
    string(10) "phpversion"
    [3] =>
    string(15) "version_compare"
    [4] =>
    string(7) "sprintf"
    [5] =>
    string(5) "count"
  }
  'Console/Command/CreateCommand.php' =>
  array(2) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(11) "array_shift"
  }
  'Console/Command/BuildCommand.php' =>
  array(1) {
    [0] =>
    string(4) "trim"
  }
  'Console/Command/CommandInterface.php' =>
  array(0) {
  }
  'Console/Command/ReleaseCommand.php' =>
  array(3) {
    [0] =>
    string(4) "date"
    [1] =>
    string(4) "trim"
    [2] =>
    string(10) "strtolower"
  }
  'Console/Command/AbstractCommand.php' =>
  array(0) {
  }
  'Console/Command/DoctorCommand.php' =>
  array(9) {
    [0] =>
    string(11) "json_encode"
    [1] =>
    string(17) "JSON_PRETTY_PRINT"
    [2] =>
    string(7) "sprintf"
    [3] =>
    string(5) "count"
    [4] =>
    string(7) "natsort"
    [5] =>
    string(12) "array_values"
    [6] =>
    string(6) "strpos"
    [7] =>
    string(4) "trim"
    [8] =>
    string(6) "substr"
  }
  'Console/Command/DiagnoseCommand.php' =>
  array(2) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(5) "count"
  }
  'Console/ApplicationInterface.php' =>
  array(0) {
  }
  'Console/Input/Input.php' =>
  array(0) {
  }
  'Console/Command/Debug/ContainerDebugCommand.php' =>
  array(7) {
    [0] =>
    string(7) "sprintf"
    [1] =>
    string(6) "substr"
    [2] =>
    string(5) "ltrim"
    [3] =>
    string(5) "count"
    [4] =>
    string(15) "str_starts_with"
    [5] =>
    string(7) "stripos"
    [6] =>
    string(11) "str_replace"
  }
  'Console/Command/NewCommand.php' =>
  array(2) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(11) "array_shift"
  }
  'Console/StyleInterface.php' =>
  array(0) {
  }
  'Console/Command/PolyfillCommand.php' =>
  array(2) {
    [0] =>
    string(4) "trim"
    [1] =>
    string(7) "sprintf"
  }
  'Console/Command/InitCommand.php' =>
  array(3) {
    [0] =>
    string(6) "getenv"
    [1] =>
    string(4) "trim"
    [2] =>
    string(11) "array_shift"
  }
  'Console/Command/ShowCommand.php' =>
  array(10) {
    [0] =>
    string(4) "trim"
    [1] =>
    string(7) "sprintf"
    [2] =>
    string(5) "count"
    [3] =>
    string(12) "array_unique"
    [4] =>
    string(7) "explode"
    [5] =>
    string(5) "ksort"
    [6] =>
    string(12) "SORT_NATURAL"
    [7] =>
    string(13) "method_exists"
    [8] =>
    string(7) "implode"
    [9] =>
    string(13) "array_unshift"
  }
}
End line <<<

Time: 239 ms, Memory: 14.00Mb

@llaville
Copy link
Author

If you want to give it a try, source code is now available on my repo (https://github.com/llaville/sandbox/commit/44137f7c39d330f32db7d7d125dd761ec6214eb8)

Once all dependencies installed (with composer update), the console launcher bin/sandbox provides 2, 3 use cases :

  • play:fork:usage run the basic fork usage example
  • play:fork:symbol-parser:uc1 is the proof of concept that task naming identification works
  • play:fork:symbol-parser:uc2 is an alternative pretty equivalent to previous one

@freekmurze
Copy link
Member

Very nice! Could you also update the readme?

@llaville
Copy link
Author

Very nice! Could you also update the readme?

I prefer to let you do it.

@llaville
Copy link
Author

What's your status about this PR ?

@freekmurze
Copy link
Member

I prefer you update the readme, after that I'll do a review 👍

@llaville llaville closed this Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants