Skip to content

Commit b9d76a3

Browse files
committed
Update documentation
1 parent 80a029f commit b9d76a3

File tree

2 files changed

+99
-64
lines changed

2 files changed

+99
-64
lines changed

MIGRATION.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ None
1212

1313
### Backward Incompatible Changes
1414

15-
- The value of `ignore-paths` is no longer a pattern, it is now relative to the `composer.json` file. The `{vendor}` placeholder can be used as a placeholder for the absolute path to the vendor directory.
15+
- The paths defined by the `include` and `exclude` directives are relative to the `composer.json` file. The `{vendor}` placeholder is replaced by the absolute path to the vendor directory.
1616

1717
### Deprecated Features
1818

19-
None
19+
- The `ignore-paths` directive has been replaced by `exclude`.
2020

2121
### Other Changes
2222

23-
None
23+
- The plugin no longer use a file cache by default. To persist a cache between runs, set the environment variable `COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE` to `1`, `yes`, or `true`.
2424

2525

2626

README.md

Lines changed: 96 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
[![Downloads](https://img.shields.io/packagist/dt/olvlvl/composer-attribute-collector.svg)](https://packagist.org/packages/olvlvl/composer-attribute-collector)
77

88
composer-attribute-collector is a plugin for [Composer][]. Its ambition is to provide a convenient
9-
and near zero-cost way to retrieve targets of PHP 8 attributes. In order to do that, after the
10-
autoloader has been dumped, the plugin collects attribute targets and generates a static file.
11-
Later, these targets can be retrieved through a convenient interface.
9+
and near zero-cost way to retrieve targets of PHP 8 attributes. After the autoloader has been
10+
dumped, the plugin collects attribute targets and generates a static file. Later, these targets can
11+
be retrieved through a convenient interface, without involving reflexion.
12+
13+
1214

1315
#### Features
1416

@@ -17,7 +19,7 @@ Later, these targets can be retrieved through a convenient interface.
1719
- No impact on performance
1820
- No dependency (except Composer of course)
1921
- A single interface to get attribute targets: classes, methods, and properties
20-
- 3 types of cache speed up generation by limiting updates to changed files
22+
- Can cache discoveries to speed up consecutive runs.
2123

2224

2325

@@ -71,25 +73,26 @@ var_dump($attributes->propertyAttributes);
7173

7274

7375

74-
#### Installation
76+
## Getting started
77+
78+
79+
### Installation
7580

76-
```bash
81+
```shell
7782
composer require olvlvl/composer-attribute-collector
7883
```
7984

80-
The plugin is currently experimental and its interface subject to change. Also, it only supports
81-
class and method targets. Please [contribute](CONTRIBUTING.md) if you're interested in shaping its
82-
future.
85+
The plugin is currently experimental and its interface subject to change. At the moment, it only
86+
supports class, method, and property targets. Please [contribute](CONTRIBUTING.md) if you're interested in
87+
shaping its future.
8388

84-
**Note:** The plugin creates a `.composer-attribute-collector` directory to store caches, you might
85-
want to add it to your `.gitignore` file.
8689

8790

88-
#### Sample configuration
91+
### Sample configuration
8992

90-
The plugin only inspects paths and files specified in the configuration, that's usually your "src"
91-
directory. Add this section to your `composer.json` file to enable the generation of the attributes
92-
file on autoload dump.
93+
The plugin only inspects paths and files specified in the configuration with the direction
94+
`include`. That's usually your "src" directory. Add this section to your `composer.json` file to
95+
enable the generation of the attributes file on autoload dump.
9396

9497
Check the [Configuration options](#configuration) for more details.
9598

@@ -107,28 +110,10 @@ Check the [Configuration options](#configuration) for more details.
107110

108111

109112

113+
### Autoloading
110114

111-
## Frequently Asked Questions
112-
113-
**Do I need to generate an optimized autoloader?**
114-
115-
You don't need to generate an optimized autoloader for this to work. The plugin uses code similar
116-
to Composer to find classes. Anything that works with Composer should work with the plugin.
117-
118-
**Can I use the plugin during development?**
119-
120-
Yes, you can use the plugin during development, but keep in mind the attributes file is only
121-
generated after the autoloader is dumped. If you modify attributes you'll have to run
122-
`composer dump` to refresh the attributes file.
123-
124-
As a workaround you could have watchers on the directories that contain classes with attributes to
125-
run `XDEBUG_MODE=off composer dump` when you make changes. [PhpStorm offers file watchers][phpstorm-watchers]. You could also use [spatie/file-system-watcher][], it only requires PHP.
126-
127-
128-
129-
## Autoloading
130-
131-
You can require the attributes file as shown in the usage example, but it's preferable to use Composer's autoloading feature:
115+
You can require the attributes file using `require_once 'vendor/attributes.php';` but you might
116+
prefer using Composer's autoloading feature:
132117

133118
```json
134119
{
@@ -144,7 +129,7 @@ You can require the attributes file as shown in the usage example, but it's pref
144129

145130
## Configuration
146131

147-
### Excluding paths or files ([root-only][])
132+
### Including paths or files ([root-only][])
148133

149134
Use the `include` property to define the paths or files to inspect for attributes. Without this
150135
property, the attributes file will be empty.
@@ -177,29 +162,61 @@ replaced with the path to the vendor folder.
177162
"extra": {
178163
"composer-attribute-collector": {
179164
"exclude": [
180-
"path-or-file/to/ignore"
165+
"path-or-file/to/exclude"
181166
]
182167
}
183168
}
184169
}
185170
```
186171

172+
### Cache discoveries between runs
187173

174+
The plugin is able to maintain a cache to reuse discoveries between runs. To enable the cache,
175+
set the environment variable `COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE` to `1`, `yes`, or `true`.
176+
Cache items are persisted in the `.composer-attribute-collector` directory, you might want to add
177+
it to your `.gitignore` file.
188178

189-
## Test drive with a Symfony app
190179

191-
You can try the plugin with a fresh installation of Symfony.
192180

193-
Use the `symfony` command to create a new project. If you don't have it yet, you can [download it](https://symfony.com/download).
181+
## Frequently Asked Questions
182+
183+
**Do I need to generate an optimized autoloader?**
184+
185+
You don't need to generate an optimized autoloader for this to work. The plugin uses code similar
186+
to Composer to find classes. Anything that works with Composer should work with the plugin.
187+
188+
**Can I use the plugin during development?**
194189

195-
```bash
196-
symfony new --webapp my_project
190+
Yes, you can use the plugin during development, but keep in mind the attributes file is only
191+
generated after the autoloader is dumped. If you modify attributes you'll have to run
192+
`composer dump` to refresh the attributes file.
193+
194+
As a workaround you could have watchers on the directories that contain classes with attributes to
195+
run `XDEBUG_MODE=off composer dump` when you make changes. [PhpStorm offers file watchers][phpstorm-watchers]. You could also use [spatie/file-system-watcher][], it only requires PHP. If the plugin is too slow for your liking,
196+
try running the command with `COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE=yes`, it will enable caching
197+
and speed up consecutive runs.
198+
199+
200+
201+
## Test drive with the Symfony Demo
202+
203+
You can try the plugin with a fresh installation of the [Symfony Demo Application](https://github.com/symfony/demo).
204+
205+
After you followed the instruction to install the demo, get into the project's directory and install the plugin. You'll be asked if you trust the plugin and wish to activate it. If you wish to continue, choose `y`.
206+
207+
```shell
208+
composer require olvlvl/composer-attribute-collector
197209
```
198210

199-
Add the `composer-attribute-collector` node to `extra` in the `composer.json` file:
211+
Add the `composer-attribute-collector` node to `extra` and the autoload item to the `composer.json` file:
200212

201213
```json
202214
{
215+
"autoload": {
216+
"files": [
217+
"vendor/attributes.php"
218+
]
219+
},
203220
"extra": {
204221
"composer-attribute-collector": {
205222
"include": [
@@ -210,34 +227,52 @@ Add the `composer-attribute-collector` node to `extra` in the `composer.json` fi
210227
}
211228
```
212229

213-
Now get into that project and install the plugin. You'll be asked if you trust the plugin and wish
214-
to activate it. If you wish to continue, choose `y`.
230+
Now dump the autoload:
215231

216-
```bash
217-
cd my_project
218-
composer require olvlvl/composer-attribute-collector
232+
```shell
233+
composer dump
219234
```
220235

221-
The plugin should have generated the file `vendor/attributes.php`. It should look something like
222-
this excerpt:
236+
You should see log messages similar to this:
237+
238+
```
239+
Generating autoload files
240+
Generating attributes file
241+
Generated attributes file in 9.137 ms
242+
Generated autoload files
243+
```
244+
245+
The plugin should have generated the file `vendor/attributes.php`. Let's see if we can get the controller methods tagged as routes. Create a PHP file with the following content and run it:
223246

224247
```php
225248
<?php
226249

227-
// attributes.php @generated by https://github.com/olvlvl/composer-attribute-collector
250+
use olvlvl\ComposerAttributeCollector\Attributes;
251+
use Symfony\Component\Routing\Annotation\Route;
228252

229-
namespace olvlvl\ComposerAttributeCollector;
253+
require_once 'vendor/autoload.php';
230254

231-
Attributes::with(fn () => new Collection(
232-
targetClasses: [
233-
\Symfony\Component\Console\Attribute\AsCommand::class => [
234-
[ ['lint:yaml', 'Lint a YAML file and outputs encountered errors'], \Symfony\Component\Yaml\Command\LintCommand::class ],
235-
[ ['server:dump', 'Start a dump server that collects and displays dumps in a single place'], \Symfony\Component\VarDumper\Command\ServerDumpCommand::class ],
236-
[ ['debug:validator', 'Display validation constraints for classes'], \Symfony\Component\Validator\Command\DebugCommand::class ],
237-
[ ['translation:pull', 'Pull translations from a given provider.'], \Symfony\Component\Translation\Command\TranslationPullCommand::class ],
255+
$targets = Attributes::filterTargetMethods(
256+
Attributes::predicateForAttributeInstanceOf(Route::class)
257+
);
258+
259+
foreach ($targets as $target) {
260+
echo "action: $target->class#$target->name, path: {$target->attribute->getPath()}\n";
261+
}
262+
```
263+
264+
You should see an output similar to the following excerpt:
265+
266+
```
267+
action: App\Controller\BlogController#index, path: /
268+
action: App\Controller\BlogController#index, path: /rss.xml
269+
action: App\Controller\BlogController#index, path: /page/{page<[1-9]\d{0,8}>}
270+
action: App\Controller\BlogController#postShow, path: /posts/{slug}
271+
action: App\Controller\BlogController#commentNew, path: /comment/{postSlug}/new
272+
action: App\Controller\BlogController#search, path: /search
238273
```
239274

240-
We also have [a repository to test the Symfony usecase](https://github.com/olvlvl/composer-attribute-collector-usecase-symfony).
275+
The demo application configured with the plugin is [available on GitHub](https://github.com/olvlvl/composer-attribute-collector-usecase-symfony).
241276

242277

243278

0 commit comments

Comments
 (0)