-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCliPipeFormatter.php
More file actions
111 lines (103 loc) · 3.67 KB
/
Copy pathCliPipeFormatter.php
File metadata and controls
111 lines (103 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php declare(strict_types=1);
namespace uuf6429\PhpCsFixerBlockstring\Formatter;
use uuf6429\PhpCsFixerBlockstring\InterpolationCodec\CodecInterface;
use uuf6429\PhpCsFixerBlockstring\LineEndingNormalizer\DefaultNormalizer;
use uuf6429\PhpCsFixerBlockstring\LineEndingNormalizer\NormalizerInterface;
use uuf6429\PhpCsFixerBlockstring\Process\ProcessFactoryInterface;
use uuf6429\PhpCsFixerBlockstring\Process\SymfonyProcessFactory;
/**
* It's no secret that the best formatting tools are not directly available in PHP. This formatter off-loads formatting
* to such external executables.
*
* Example:
*
* ```php
* return (new PhpCsFixer\Config())
* ->registerCustomFixers([new BlockStringFixer()])
* ->setRules([
* BlockStringFixer::NAME => BlockStringFixer::config([
* 'J' => new CliPipeFormatter(
* // Either a version as a string, or the command to get the version (as an array).
* versionValueOrCommand: '1.0',
* // An array defining the external command to do the formatting.
* formatCommand: ['cmd' => 'jfmt -'],
* // A codec for handling placeholers in template strings; depends on the content being formatted.
* interpolationCodec: new PlainStringCodec(),
* // A normalizer for handling end-of-line characters.
* lineEndingNormalizer: null,
* // Factory for creating processes. Defaults to Symfony process factory.
* processFactory: null,
* )
* ]),
* ]);
* ```
*
* The command definition (for version detection or formatting) is an array with the following structure:
*
* - `cmd` `array`/`string`: The command line e.g. `'jfmt --format'` or `['jfmt', '--format']`.
* - `cwd` (optional) `string`: The current working directory of the command.
* - `env` (optional) `array` of `string` keys and values: Environment variables to pass to the command.
*
* @phpstan-type TVersion string
* @phpstan-type TCommand array{cmd: string|list<string>, cwd?: string, env?: array<string, string>}
*/
class CliPipeFormatter extends AbstractStringFormatter
{
/**
* @readonly
* @var TCommand
*/
private array $formatter;
/**
* @readonly
*/
private ProcessFactoryInterface $processFactory;
/**
* @param TVersion|TCommand $versionValueOrCommand Either the version (as a string) or a command to retrieve the
* version (as an array).
* @param TCommand $formatCommand A command, as an array, to perform the formatting.
*/
public function __construct(
$versionValueOrCommand,
array $formatCommand,
?CodecInterface $interpolationCodec = null,
?NormalizerInterface $lineEndingNormalizer = null,
?ProcessFactoryInterface $processFactory = null
) {
$this->formatter = $formatCommand;
$this->processFactory = $processFactory ?? new SymfonyProcessFactory();
parent::__construct(
sprintf(
'%s: %s v%s',
static::class,
is_array($this->formatter['cmd'])
? implode(' ', $this->formatter['cmd'])
: $this->formatter['cmd'],
is_string($versionValueOrCommand)
? $versionValueOrCommand
: $this->exec($versionValueOrCommand, null)
),
$interpolationCodec,
$lineEndingNormalizer ?? new DefaultNormalizer(DefaultNormalizer::LF, DefaultNormalizer::NO_CHANGE)
);
}
/**
* @param TCommand $spec
*/
protected function exec(array $spec, ?string $input): string
{
return $this->processFactory
->create(
$spec['cmd'],
$spec['cwd'] ?? null,
$spec['env'] ?? null,
$input
)
->mustRun()
->getOutput();
}
protected function formatContent(string $original): string
{
return $this->exec($this->formatter, $original);
}
}