Skip to content

Commit 82a3244

Browse files
authored
Phar compilation (#77)
* Phar composer * Distribute as phar; add overridable config * phar
1 parent 4e2c715 commit 82a3244

File tree

10 files changed

+254
-168
lines changed

10 files changed

+254
-168
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ vendor
66
composer.lock
77
node_modules
88
.phpunit.cache
9-
coverage
9+
coverage
10+
build

README.md

Lines changed: 113 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ PHP 8.0 or above
1919
composer require riverwaysoft/php-converter --dev
2020
```
2121

22+
If the installation causes dependency conflicts you can use the [standalone Phar version](#phar-installation) of the package.
23+
2224
2) Mark a few classes with `#[Dto]` annotation to convert them into TypeScript or Dart
2325
```php
2426
use Riverwaysoft\PhpConverter\ClassFilter\Dto;
@@ -36,7 +38,7 @@ class UserOutput
3638

3739
4) Run CLI command to generate TypeScript
3840
```bash
39-
vendor/bin/php-converter-ts generate --from=/path/to/project/src --to=.
41+
vendor/bin/php-converter --from=/path/to/project/src --to=.
4042
```
4143

4244
You'll get file `generated.ts` with the following contents:
@@ -60,44 +62,44 @@ type UserOutput = {
6062
- Flexible class filters with an option to use your own filters
6163
6264
## Customize
63-
If you'd like to customize `php-converter-ts` you need to copy the generator script to your project folder:
65+
If you'd like to customize the conversion, you need to copy the config script to your project folder:
6466
6567
```
66-
cp vendor/bin/php-converter-ts bin/php-converter-ts
68+
cp vendor/bin/default-config.php config/php-converter-config.php
6769
```
6870
69-
Now you can start customizing the php-converter by editing the executable file.
71+
Now you can customize this config and run the php-converter via the following script:
72+
```bash
73+
vendor/bin/php-converter --from=/path/to/project/src --to=. --config=config/php-converter-config.php
74+
```
7075
7176
### How to customize generated output?
7277
By default `php-converter` writes all the types into one file. You can configure it to put each type / class in a separate file with all the required imports. Here is an example how to achieve it:
7378
7479
```diff
75-
+ $fileNameGenerator = new KebabCaseFileNameGenerator('.ts');
76-
77-
$application->add(
78-
new ConvertCommand(
79-
new Converter([
80-
new DtoVisitor(new PhpAttributeFilter('Dto')),
81-
]),
82-
new TypeScriptGenerator(
83-
- new SingleFileOutputWriter('generated.ts'),
84-
+ new EntityPerClassOutputWriter(
85-
+ $fileNameGenerator,
86-
+ new TypeScriptImportGenerator(
87-
+ $fileNameGenerator,
88-
+ new DtoTypeDependencyCalculator()
89-
+ )
90-
+ ),
91-
[
92-
new DateTimeTypeResolver(),
93-
new ClassNameTypeResolver(),
94-
],
95-
),
96-
new Filesystem(),
97-
new OutputDiffCalculator(),
98-
new FileSystemCodeProvider('/\.php$/'),
99-
)
100-
);
80+
return static function (PhpConverterConfig $config) {
81+
$config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
82+
83+
$config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
84+
85+
+ $fileNameGenerator = new KebabCaseFileNameGenerator('.ts');
86+
87+
$config->setLanguageGenerator(new TypeScriptGenerator(
88+
new SingleFileOutputWriter('generated.ts'),
89+
- new SingleFileOutputWriter('generated.ts'),
90+
+ new EntityPerClassOutputWriter(
91+
+ $fileNameGenerator,
92+
+ new TypeScriptImportGenerator(
93+
+ $fileNameGenerator,
94+
+ new DtoTypeDependencyCalculator()
95+
+ )
96+
+ ),
97+
[
98+
new DateTimeTypeResolver(),
99+
new ClassNameTypeResolver(),
100+
],
101+
));
102+
};
101103
```
102104

103105
Feel free to create your own OutputWriter.
@@ -106,25 +108,22 @@ Feel free to create your own OutputWriter.
106108
Suppose you don't want to mark each DTO individually with `#[Dto]` but want to convert all the files ending with "Dto" automatically:
107109

108110
```diff
109-
$application->add(
110-
new ConvertCommand(
111-
- new Converter([
112-
- new DtoVisitor(new PhpAttributeFilter('Dto')),
113-
- ]),
114-
+ new Converter([new DtoVisitor()]),
115-
new TypeScriptGenerator(
116-
new SingleFileOutputWriter('generated.ts'),
117-
[
118-
new DateTimeTypeResolver(),
119-
new ClassNameTypeResolver(),
120-
],
121-
),
122-
new Filesystem(),
123-
new OutputDiffCalculator(),
124-
- new FileSystemCodeProvider('/\.php$/'),
125-
+ new FileSystemCodeProvider('/Dto\.php$/'),
126-
)
127-
);
111+
112+
return static function (PhpConverterConfig $config) {
113+
- $config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
114+
+ $config->setCodeProvider(new FileSystemCodeProvider('/Dto\.php$/'));
115+
116+
- $config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
117+
+ $config->addVisitor(new DtoVisitor());
118+
119+
$config->setLanguageGenerator(new TypeScriptGenerator(
120+
new SingleFileOutputWriter('generated.ts'),
121+
[
122+
new DateTimeTypeResolver(),
123+
new ClassNameTypeResolver(),
124+
],
125+
));
126+
};
128127
```
129128

130129
You can even go further and use `NegationFilter` to exclude specific files as shown in [unit tests](https://github.com/riverwaysoft/php-converter/blob/a8d5df2c03303c02bc9148bd1d7822d7fe48c5d8/tests/EndToEndTest.php#L297).
@@ -135,16 +134,16 @@ You can even go further and use `NegationFilter` to exclude specific files as sh
135134
```diff
136135
+use Riverwaysoft\PhpConverter\Dto\PhpType\PhpBaseType;
137136

138-
$application->add(
139-
new ConvertCommand(
140-
new Converter([
141-
new DtoVisitor(new PhpAttributeFilter('Dto')),
142-
]),
143-
new TypeScriptGenerator(
144-
new SingleFileOutputWriter('generated.ts'),
145-
[
146-
new DateTimeTypeResolver(),
147-
new ClassNameTypeResolver(),
137+
return static function (PhpConverterConfig $config) {
138+
$config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
139+
140+
$config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
141+
142+
$config->setLanguageGenerator(new TypeScriptGenerator(
143+
new SingleFileOutputWriter('generated.ts'),
144+
[
145+
new DateTimeTypeResolver(),
146+
new ClassNameTypeResolver(),
148147
+ new InlineTypeResolver([
149148
+ // Convert libphonenumber object to a string
150149
+ // PhpBaseType is used to support both Dart/TypeScript
@@ -155,40 +154,32 @@ $application->add(
155154
+ // Convert Doctrine Embeddable to an existing Dto marked as #[Dto]
156155
+ 'SomeDoctrineEmbeddable' => 'SomeDoctrineEmbeddableDto',
157156
+ ])
158-
],
159-
),
160-
new Filesystem(),
161-
new OutputDiffCalculator(),
162-
new FileSystemCodeProvider('/\.php$/'),
163-
)
164-
);
157+
],
158+
));
159+
};
165160
```
166161

167162
### How to customize generated output file?
168163

169164
You may want to apply some transformations on the resulted file with types. For example, you may want to format it with tool of your choice or prepend code with a warning like "// The file was autogenerated, don't edit it manually". To add such a warning you can already use the built-in extension:
170165

171166
```diff
172-
$application->add(
173-
new ConvertCommand(
174-
new Converter([
175-
new DtoVisitor(new PhpAttributeFilter('Dto')),
176-
]),
177-
new TypeScriptGenerator(
178-
new SingleFileOutputWriter('generated.ts'),
179-
[
180-
new DateTimeTypeResolver(),
181-
new ClassNameTypeResolver(),
182-
],
183-
+ new OutputFilesProcessor([
184-
+ new PrependAutogeneratedNoticeFileProcessor(),
185-
+ ]),
186-
),
187-
new Filesystem(),
188-
new OutputDiffCalculator(),
189-
new FileSystemCodeProvider('/\.php$/'),
190-
)
191-
);
167+
return static function (PhpConverterConfig $config) {
168+
$config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
169+
170+
$config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
171+
172+
$config->setLanguageGenerator(new TypeScriptGenerator(
173+
new SingleFileOutputWriter('generated.ts'),
174+
[
175+
new DateTimeTypeResolver(),
176+
new ClassNameTypeResolver(),
177+
],
178+
+ new OutputFilesProcessor([
179+
+ new PrependAutogeneratedNoticeFileProcessor(),
180+
+ ]),
181+
));
182+
};
192183
```
193184

194185
Feel free to create your own processor based on [PrependAutogeneratedNoticeFileProcessor](https://github.com/riverwaysoft/php-converter/blob/26ee25f07ac97a942e1327165424fc65777b80b0/src/OutputWriter/OutputProcessor/PrependAutogeneratedNoticeFileProcessor.php) source.
@@ -226,27 +217,23 @@ class PrettierFormatProcessor implements SingleOutputFileProcessorInterface
226217
Then add it to the list:
227218

228219
```diff
229-
$application->add(
230-
new ConvertCommand(
231-
new Converter([
232-
new DtoVisitor(new PhpAttributeFilter('Dto')),
233-
]),
234-
new TypeScriptGenerator(
235-
new SingleFileOutputWriter('generated.ts'),
236-
[
237-
new DateTimeTypeResolver(),
238-
new ClassNameTypeResolver(),
239-
],
240-
+ new OutputFilesProcessor([
241-
+ new PrependAutogeneratedNoticeFileProcessor(),
242-
+ new PrettierFormatProcessor(),
243-
+ ]),
244-
),
245-
new Filesystem(),
246-
new OutputDiffCalculator(),
247-
new FileSystemCodeProvider('/\.php$/'),
248-
)
249-
);
220+
return static function (PhpConverterConfig $config) {
221+
$config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
222+
223+
$config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
224+
225+
$config->setLanguageGenerator(new TypeScriptGenerator(
226+
new SingleFileOutputWriter('generated.ts'),
227+
[
228+
new DateTimeTypeResolver(),
229+
new ClassNameTypeResolver(),
230+
],
231+
+ new OutputFilesProcessor([
232+
+ new PrependAutogeneratedNoticeFileProcessor(),
233+
+ new PrettierFormatProcessor(),
234+
+ ]),
235+
));
236+
};
250237
```
251238

252239
### How to add support for other languages?
@@ -292,13 +279,25 @@ composer test
292279
- Unlike [spatie/typescript-transformer](https://github.com/spatie/typescript-transformer) `php-converter` supports not only TypeScript but also Dart. Support for other languages can be easily added by implementing LanguageInterface. `php-converter` can also output generated types / classes into different files.
293280
- Unlike [grpc](https://github.com/grpc/grpc/tree/v1.40.0/examples/php) `php-converter` doesn't require to modify your app or install some extensions.
294281

282+
## Phar installation
283+
284+
PHAR files, similar to JAR files in Java, bundle a PHP application and its dependencies into a single file. This provides the isolation of dependencies. Each PHAR can include its specific version of dependencies, avoiding conflicts with other packages on the same project. To download `phar` version of this package go to releases and download the `.phar` file from there. Static analyzers like PHPStan will complain if you use classes from the PHAR in your code, so you'd need to tell a static analyzer where to find these classes. Example for PHPStan:
285+
286+
```
287+
// phpstan.neon
288+
289+
parameters:
290+
bootstrapFiles:
291+
- phar://bin/php-converter.phar/vendor/autoload.php
292+
```
293+
295294
## Contributing
296295

297296
Please see [CONTRIBUTING](./CONTRIBUTING.md) for details.
298297

299298
## Development
300299

301-
The information is for the package developers.
300+
The information is for the package contributors.
302301

303302
### Work with a local copy of `php-converter` inside your project
304303

@@ -328,3 +327,9 @@ Generate Xdebug profiler output:
328327
`php -d xdebug.mode=profile -d xdebug.output_dir=. bin/php-converter generate --from=./ --to=./assets/ -v -xdebug`
329328

330329
Then open the result .cachegrind file in PHPStorm -> Tools -> Analyze XDebug Profiler Snapshot
330+
331+
### Code coverage
332+
333+
1) Run tests with code coverage: `composer run test:with-coverage`
334+
2) Check coverage level: `composer run test:coverage-level`
335+
3) Browser generated HTML report: `npm run coverage-server`

bin/build.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
rm -rf build && \
6+
mkdir build && \
7+
cp -r src build/src && \
8+
cp -r bin build/bin && \
9+
cp -r LICENSE build/LICENSE && \
10+
cp -r composer.json build/composer.json && \
11+
cp -r composer.lock build/composer.lock && \
12+
composer install -d build/ --no-dev && \
13+
php -d phar.readonly=Off tools/phar-composer-1.4.0.phar build build/
14+
mv php-converter.phar build/

bin/default-config.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Riverwaysoft\PhpConverter\Ast\DtoVisitor;
6+
use Riverwaysoft\PhpConverter\ClassFilter\PhpAttributeFilter;
7+
use Riverwaysoft\PhpConverter\CodeProvider\FileSystemCodeProvider;
8+
use Riverwaysoft\PhpConverter\Config\PhpConverterConfig;
9+
use Riverwaysoft\PhpConverter\Language\TypeScript\TypeScriptGenerator;
10+
use Riverwaysoft\PhpConverter\Language\UnknownTypeResolver\ClassNameTypeResolver;
11+
use Riverwaysoft\PhpConverter\Language\UnknownTypeResolver\DateTimeTypeResolver;
12+
use Riverwaysoft\PhpConverter\OutputWriter\SingleFileOutputWriter\SingleFileOutputWriter;
13+
14+
return static function (PhpConverterConfig $config) {
15+
$config->setCodeProvider(new FileSystemCodeProvider('/\.php$/'));
16+
17+
$config->addVisitor(new DtoVisitor(new PhpAttributeFilter('Dto')));
18+
19+
$config->setLanguageGenerator(new TypeScriptGenerator(
20+
new SingleFileOutputWriter('generated.ts'),
21+
[
22+
new DateTimeTypeResolver(),
23+
new ClassNameTypeResolver(),
24+
],
25+
));
26+
};

bin/php-converter

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
declare(strict_types=1);
5+
6+
require_once __DIR__ . '/../vendor/autoload.php';
7+
8+
use Riverwaysoft\PhpConverter\Cli\ConvertCommand;
9+
use Symfony\Component\Console\Application;
10+
11+
$application = new Application();
12+
13+
$application->add(new ConvertCommand());
14+
$application->setDefaultCommand(ConvertCommand::getDefaultName());
15+
16+
$application->run();

0 commit comments

Comments
 (0)