Skip to content

Commit 0d1a3c3

Browse files
committed
TASK: Support wildcards and multiple packages seperated by comma
Also the options `generateClass` and `generateInterface` are removed
1 parent 2697f13 commit 0d1a3c3

File tree

4 files changed

+100
-85
lines changed

4 files changed

+100
-85
lines changed

Classes/Command/NodetypeObjectsCommandController.php

Lines changed: 96 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,100 +35,118 @@ public function injectPackageManager(PackageManager $packageManager): void
3535
}
3636

3737
/**
38-
* Remove all *NodeObject.php and *NodeInterface.php from the NodeTypes folder of the specified package
38+
* Remove all *NodeObject.php and *NodeInterface.php from the NodeTypes folder of the specified packages
3939
*
40-
* @param string $packageKey PackageKey to store the classes in
40+
* @param string $packageKeys PackageKey or Pattern, can be used seperated by comma
4141
* @return void
4242
*/
43-
public function cleanCommand(string $packageKey): void
43+
public function cleanCommand(string $packageKeys): void
4444
{
45-
if ($this->packageManager->isPackageAvailable($packageKey)) {
46-
$package = $this->packageManager->getPackage($packageKey);
47-
} else {
48-
$this->output->outputLine("Unknown package " . $packageKey);
49-
$this->quit(1);
50-
}
51-
if (!$package instanceof FlowPackageInterface) {
52-
$this->output->outputLine($packageKey . " is not a Flow package");
45+
$packages = $this->findPackagesByPackageKeyPattern($packageKeys);
46+
47+
if (empty($packages)) {
48+
$this->output->outputLine('No packages found for packageKeys <error>"%s"</error>:', [$packageKeys]);
5349
$this->quit(1);
50+
} else {
51+
$keys = array_map(fn (FlowPackageInterface $package) => $package->getPackageKey(), $packages);
52+
$this->output->outputLine('Removing NodeObjects and NodeInterfaces from packages <info>"%s"</info>:', [implode(', ', $keys)]);
5453
}
5554

56-
$packagePath = $package->getPackagePath();
57-
$files = Files::readDirectoryRecursively($packagePath . DIRECTORY_SEPARATOR . 'NodeTypes', 'NodeObject.php');
58-
if (is_array($files)) {
59-
foreach ($files as $file) {
60-
if (is_file($file)) {
61-
unlink($file);
55+
foreach ($packages as $package) {
56+
$packagePath = $package->getPackagePath();
57+
if (!file_exists($packagePath . DIRECTORY_SEPARATOR . 'NodeTypes')) {
58+
continue;
59+
}
60+
61+
$files = Files::readDirectoryRecursively($packagePath . DIRECTORY_SEPARATOR . 'NodeTypes', 'NodeObject.php');
62+
if (is_array($files)) {
63+
foreach ($files as $file) {
64+
if (is_file($file)) {
65+
unlink($file);
66+
}
67+
$this->outputLine(' - ' . $file);
6268
}
63-
$this->outputLine(' - ' . $file);
6469
}
65-
}
66-
$files = Files::readDirectoryRecursively($packagePath . DIRECTORY_SEPARATOR . 'NodeTypes', 'NodeInterface.php');
67-
if (is_array($files)) {
68-
foreach ($files as $file) {
69-
if (is_file($file)) {
70-
unlink($file);
70+
$files = Files::readDirectoryRecursively($packagePath . DIRECTORY_SEPARATOR . 'NodeTypes', 'NodeInterface.php');
71+
if (is_array($files)) {
72+
foreach ($files as $file) {
73+
if (is_file($file)) {
74+
unlink($file);
75+
}
76+
$this->outputLine(' - ' . $file);
7177
}
72-
$this->outputLine(' - ' . $file);
7378
}
7479
}
7580
}
7681

7782
/**
7883
* Create new NodeTypeObjects for the selected Package
7984
*
80-
* @param string $packageKey PackageKey
85+
* @param string $packageKeys PackageKey or Pattern, can be used seperated comma
8186
*/
82-
public function buildCommand(string $packageKey): void
87+
public function buildCommand(string $packageKeys): void
8388
{
84-
$package = $this->getPackage($packageKey);
89+
$packages = $this->findPackagesByPackageKeyPattern($packageKeys);
90+
91+
if (empty($packages)) {
92+
$this->output->outputLine('No packages found for packageKeys <error>"%s"</error>:', [$packageKeys]);
93+
$this->quit(1);
94+
} else {
95+
$keys = array_map(fn (FlowPackageInterface $package) => $package->getPackageKey(), $packages);
96+
$this->output->outputLine('Building NodeObjects and NodeInterfaces for packages <info>"%s"</info>:', [implode(', ', $keys)]);
97+
}
8598

8699
$nodeTypes = $this->nodeTypeManager->getNodeTypes(true);
87-
$nameSpecifications = [];
88100

89-
foreach ($nodeTypes as $nodeType) {
90-
if (!str_starts_with($nodeType->getName(), $packageKey . ':')) {
91-
continue;
101+
// loop 1 collect all nodetypes so in run two we know which interfaces exist
102+
$nameSpecifications = [];
103+
foreach ($packages as $package) {
104+
foreach ($nodeTypes as $nodeType) {
105+
if (!str_starts_with($nodeType->getName(), $package->getPackageKey() . ':')) {
106+
continue;
107+
}
108+
$nameSpecifications[ $nodeType->getName() ] = NodeTypeObjectNameSpecification::createFromPackageAndNodeType($package, $nodeType);
92109
}
93-
$nameSpecifications[$nodeType->getName()] = NodeTypeObjectNameSpecification::createFromPackageAndNodeType($package, $nodeType);
94110
}
95-
96111
$nameSpecificationsCollection = new NodeTypeObjectNameSpecificationCollection(...$nameSpecifications);
97112

98-
foreach ($nodeTypes as $nodeType) {
99-
if (!str_starts_with($nodeType->getName(), $packageKey . ':')) {
100-
continue;
101-
}
102-
103-
$specification = NodeTypeObjectSpecification::createFromPackageAndNodeType($package, $nodeType, $nameSpecificationsCollection);
113+
// loop 2 build interfaces and objects
114+
foreach ($packages as $package) {
115+
foreach ($nodeTypes as $nodeType) {
116+
if (!str_starts_with($nodeType->getName(), $package->getPackageKey() . ':')) {
117+
continue;
118+
}
104119

105-
Files::createDirectoryRecursively($specification->names->directory);
120+
$specification = NodeTypeObjectSpecification::createFromPackageAndNodeType($package, $nodeType, $nameSpecificationsCollection);
106121

107-
if ($specification->names->className) {
108-
file_put_contents(
109-
$specification->names->directory . DIRECTORY_SEPARATOR . $specification->names->className . '.php',
110-
$specification->toPhpClassString()
111-
);
112-
$this->outputLine(' - ' . $specification->names->nodeTypeName . ' -> ' . $specification->names->className);
113-
}
122+
Files::createDirectoryRecursively($specification->names->directory);
123+
$generatedFiles = [];
124+
if ($specification->names->className) {
125+
file_put_contents(
126+
$specification->names->directory . DIRECTORY_SEPARATOR . $specification->names->className . '.php',
127+
$specification->toPhpClassString()
128+
);
129+
$generatedFiles[] = $specification->names->phpNamespace . '\\' . $specification->names->className;
130+
}
131+
if ($specification->names->interfaceName) {
132+
file_put_contents(
133+
$specification->names->directory . DIRECTORY_SEPARATOR . $specification->names->interfaceName . '.php',
134+
$specification->toPhpInterfaceString()
135+
);
136+
$generatedFiles[] = $specification->names->phpNamespace . '\\' . $specification->names->interfaceName;
137+
}
114138

115-
if ($specification->names->interfaceName) {
116-
file_put_contents(
117-
$specification->names->directory . DIRECTORY_SEPARATOR . $specification->names->interfaceName . '.php',
118-
$specification->toPhpInterfaceString()
119-
);
120-
$this->outputLine(' - ' . $specification->names->nodeTypeName . ' -> ' . $specification->names->interfaceName);
139+
$this->outputLine(' - ' . $specification->names->nodeTypeName . ' -> <info>' . implode(', ', $generatedFiles) . '</info>');
121140
}
122141
}
123142
}
124143

125144
/**
126145
* @param string $packageKey
127-
* @return mixed|FlowPackageInterface|GenericPackage|\Neos\Flow\Package\PackageInterface
128146
* @throws \Neos\Flow\Cli\Exception\StopCommandException
129147
* @throws \Neos\Flow\Package\Exception\UnknownPackageException
130148
*/
131-
protected function getPackage(string $packageKey): mixed
149+
protected function getPackage(string $packageKey): FlowPackageInterface & GenericPackage
132150
{
133151
if ($this->packageManager->isPackageAvailable($packageKey)) {
134152
$package = $this->packageManager->getPackage($packageKey);
@@ -170,4 +188,26 @@ protected function getPackage(string $packageKey): mixed
170188
}
171189
return $package;
172190
}
191+
192+
/**
193+
* @param string $packageKeys
194+
* @return FlowPackageInterface[]
195+
*/
196+
protected function findPackagesByPackageKeyPattern(string $packageKeys): array
197+
{
198+
$packageKeyPatterns = explode(',', $packageKeys);
199+
200+
$allFlowPackages = $this->packageManager->getFlowPackages();
201+
202+
$packages = [];
203+
foreach ($allFlowPackages as $flowPackage) {
204+
foreach ($packageKeyPatterns as $packageKeyPattern) {
205+
if (fnmatch($packageKeyPattern, $flowPackage->getPackageKey())) {
206+
$packages[ $flowPackage->getPackageKey() ] = $flowPackage;
207+
break;
208+
}
209+
}
210+
}
211+
return $packages;
212+
}
173213
}

Classes/Domain/NodeTypeObjectNameSpecification.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function __construct(
1616
public string $nodeTypeName,
1717
public string $phpNamespace,
1818
public ?string $className,
19-
public ?string $interfaceName
19+
public string $interfaceName
2020
) {
2121
}
2222

@@ -43,16 +43,12 @@ public static function createFromPackageAndNodeType(
4343
. ($localNamespace ? str_replace('.', DIRECTORY_SEPARATOR, $localNamespace) . DIRECTORY_SEPARATOR : '')
4444
. $localName;
4545

46-
if ($nodeType->getConfiguration('options.nodeTypeObjects.generateClass') === true) {
47-
$className = str_replace('.', '\\', $localName) . 'NodeObject';
48-
} else {
46+
if ($nodeType->isAbstract()) {
4947
$className = null;
50-
}
51-
if ($nodeType->getConfiguration('options.nodeTypeObjects.generateInterface') === true) {
52-
$interfaceName = str_replace('.', '\\', $localName) . 'NodeInterface';
5348
} else {
54-
$interfaceName = null;
49+
$className = str_replace('.', '\\', $localName) . 'NodeObject';
5550
}
51+
$interfaceName = str_replace('.', '\\', $localName) . 'NodeInterface';
5652

5753
return new self(
5854
$directory,

README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,6 @@ The following preconditions have to be met for a package to use NodeTypeObjects.
1818
- The pattern `*NodeTypeObject.php` is added to `.gitignore` to avoid committing the generated files.
1919
- The commands `nodetypeobjects:build` and `nodetypeobjects:clean` are integrated into build processes and watchers
2020

21-
The NodeTypes have to opt in into the generation via the following setting
22-
23-
```yaml
24-
Vendor.Site:
25-
options:
26-
27-
nodeTypeObjects:
28-
# classes are generated for nodetypes with generateClass:true
29-
generateClass: true
30-
31-
# interfaces are generated for all nodetypes with generateInterface:true
32-
generateInterface: true
33-
```
34-
3521
## Usage
3622

3723
The package defines the following cli commands

Tests/Unit/NodeTypeObjectNameSpecificationTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,6 @@ public function testDetectionOfNamesFromPackageAndNodeType(): void
2020
// nodetype has a name and
2121
$nodeType = $this->createMock(NodeType::class);
2222
$nodeType->expects(self::any())->method('getName')->willReturn('Vendor.Example:Foo.Bar');
23-
$nodeType->expects(self::any())->method('getConfiguration')->willReturnCallback(
24-
fn($path) => match($path) {
25-
'options.nodeTypeObjects.generateClass' => true,
26-
'options.nodeTypeObjects.generateInterface' => true,
27-
default => $this->fail(),
28-
}
29-
);
3023

3124
$specification = NodeTypeObjectNameSpecification::createFromPackageAndNodeType(
3225
$package,

0 commit comments

Comments
 (0)