Skip to content

Commit

Permalink
Merge pull request #365 from reliforp/improve-speedscope-converter
Browse files Browse the repository at this point in the history
Add a configuration option to the speedscope converter for the handling of utf8 errors
  • Loading branch information
sj-i authored Nov 25, 2023
2 parents 7bc890e + 2ee8a85 commit 961e084
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 4 deletions.
11 changes: 9 additions & 2 deletions src/Command/Converter/SpeedscopeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Reli\Command\Converter;

use Reli\Converter\PhpSpyCompatibleParser;
use Reli\Converter\Speedscope\Settings\SpeedscopeConverterSettingsFromConsoleInput;
use Reli\Converter\Speedscope\SpeedscopeConverter;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -24,6 +25,7 @@ final class SpeedscopeCommand extends Command
public function __construct(
private SpeedscopeConverter $speedscope_converter,
private PhpSpyCompatibleParser $parser,
private SpeedscopeConverterSettingsFromConsoleInput $settings_from_console_input,
) {
parent::__construct();
}
Expand All @@ -33,16 +35,21 @@ public function configure(): void
$this->setName('converter:speedscope')
->setDescription('convert traces to the speedscope file format')
;
$this->settings_from_console_input->setOptions($this);
}

public function execute(InputInterface $input, OutputInterface $output): int
{
$settings = $this->settings_from_console_input->createSettings($input);

$output->write(
\json_encode(
$this->speedscope_converter->collectFrames(
$this->parser->parseFile(STDIN)
$this->parser->parseFile(STDIN),
$settings,
),
)
JSON_THROW_ON_ERROR | $settings->utf8_error_handling_type->toFlag(),
),
);
return 0;
}
Expand Down
22 changes: 22 additions & 0 deletions src/Converter/Speedscope/Settings/SpeedscopeConverterSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/**
* This file is part of the reliforp/reli-prof package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Reli\Converter\Speedscope\Settings;

final class SpeedscopeConverterSettings
{
public function __construct(
public Utf8ErrorHandlingType $utf8_error_handling_type,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* This file is part of the reliforp/reli-prof package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Reli\Converter\Speedscope\Settings;

use Reli\Inspector\Settings\InspectorSettingsException;

final class SpeedscopeConverterSettingsException extends InspectorSettingsException
{
public const UNSUPPORTED_UTF8_ERROR_HANDLING = 1;

protected const ERRORS = [
self::UNSUPPORTED_UTF8_ERROR_HANDLING => 'unsupported utf8 error handling type is specified',
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/**
* This file is part of the reliforp/reli-prof package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Reli\Converter\Speedscope\Settings;

use PhpCast\Cast;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;

final class SpeedscopeConverterSettingsFromConsoleInput
{
/** @codeCoverageIgnore */
public function setOptions(Command $command): void
{
$command
->addOption(
'utf8-errors',
null,
InputOption::VALUE_REQUIRED,
'utf8 error handling type (ignore|substitute|fail)',
'ignore'
);
;
}

public function createSettings(InputInterface $input): SpeedscopeConverterSettings
{
return new SpeedscopeConverterSettings(
$this->utf8ErrorHandlingTypeFromString(
Cast::toString($input->getOption('utf8-errors'))
),
);
}

private function utf8ErrorHandlingTypeFromString(string $input): Utf8ErrorHandlingType
{
return match ($input) {
'substitute' => Utf8ErrorHandlingType::Substitute,
'ignore' => Utf8ErrorHandlingType::Ignore,
'fail' => Utf8ErrorHandlingType::Fail,
default => throw SpeedscopeConverterSettingsException::create(
SpeedscopeConverterSettingsException::UNSUPPORTED_UTF8_ERROR_HANDLING
),
};
}
}
30 changes: 30 additions & 0 deletions src/Converter/Speedscope/Settings/Utf8ErrorHandlingType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/**
* This file is part of the reliforp/reli-prof package.
*
* (c) sji <sji@sj-i.dev>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Reli\Converter\Speedscope\Settings;

enum Utf8ErrorHandlingType
{
case Ignore;
case Substitute;
case Fail;

public function toFlag(): int
{
return match ($this) {
self::Ignore => \JSON_INVALID_UTF8_IGNORE,
self::Substitute => \JSON_INVALID_UTF8_SUBSTITUTE,
self::Fail => 0,
};
}
}
8 changes: 6 additions & 2 deletions src/Converter/Speedscope/SpeedscopeConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
namespace Reli\Converter\Speedscope;

use Reli\Converter\ParsedCallTrace;
use Reli\Converter\Speedscope\Settings\SpeedscopeConverterSettings;

class SpeedscopeConverter
{
/** @param iterable<ParsedCallTrace> $call_frames */
public function collectFrames(iterable $call_frames): array
{
public function collectFrames(
iterable $call_frames,
SpeedscopeConverterSettings $settings,
): array {
$mapper = fn(array $value): string | false => \json_encode(
$value,
$settings->utf8_error_handling_type->toFlag()
);
$trace_map = [];
$result_frames = [];
Expand Down

0 comments on commit 961e084

Please sign in to comment.