Skip to content

Commit 779bc87

Browse files
committed
updates
1 parent 97ae0b7 commit 779bc87

3 files changed

Lines changed: 53 additions & 26 deletions

File tree

chorale.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: 1
2+
repo_host: git@github.com
3+
repo_vendor: SonsOfPHP
4+
repo_name_template: '{name:kebab}.git'
5+
default_repo_template: '{repo_host}:{repo_vendor}/{repo_name_template}'
6+
default_branch: main
7+
splitter: splitsh
8+
tag_strategy: inherit-monorepo-tag
9+
rules:
10+
keep_history: true
11+
skip_if_unchanged: true
12+
require_files:
13+
- composer.json
14+
- LICENSE
15+
patterns:
16+
-
17+
match: 'src/**'
18+
include:
19+
- '**'

rector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
earlyReturn: true,
3535
strictBooleans: true,
3636
phpunitCodeQuality: true,
37-
phpunit: true,
37+
//phpunit: true,
3838
)
3939
->withImportNames(
4040
importShortClasses: false,

tools/chorale/src/Console/SetupCommand.php

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
use Chorale\Discovery\PatternMatcherInterface;
1717
use Chorale\IO\JsonReporterInterface;
1818
use Chorale\Repo\RepoResolverInterface;
19-
use Chorale\Rules\ConflictDetectorInterface;
2019
use Chorale\Rules\RequiredFilesCheckerInterface;
2120
use Chorale\Telemetry\RunSummaryInterface;
22-
use Symfony\Component\Console\Attribute\AsCommand;
2321
use Symfony\Component\Console\Command\Command;
2422
use Symfony\Component\Console\Input\InputInterface;
2523
use Symfony\Component\Console\Input\InputOption;
24+
use Symfony\Component\Console\Output\OutputInterface;
2625
use Symfony\Component\Console\Question\ConfirmationQuestion;
2726
use Symfony\Component\Console\Style\SymfonyStyle;
2827

2928
//#[AsCommand(name: 'setup')]
3029
final class SetupCommand extends Command
3130
{
3231
protected static $defaultName = 'setup';
32+
3333
protected static $defaultDescription = 'Create or update chorale.yaml by scanning src/ and applying defaults.';
3434

3535
public function __construct(
@@ -44,7 +44,6 @@ public function __construct(
4444
private readonly RepoResolverInterface $resolver,
4545
private readonly PackageIdentityInterface $identity,
4646
private readonly RequiredFilesCheckerInterface $requiredFiles,
47-
private readonly ConflictDetectorInterface $conflicts,
4847
private readonly JsonReporterInterface $jsonReporter,
4948
private readonly RunSummaryInterface $summary,
5049
private readonly ComposerMetadataInterface $composerMeta,
@@ -70,14 +69,14 @@ protected function configure(): void
7069
// ─────────────────────────────────────────────────────────────────────────────
7170
// Orchestrator
7271
// ─────────────────────────────────────────────────────────────────────────────
73-
protected function execute(InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output): int
72+
protected function execute(InputInterface $input, OutputInterface $output): int
7473
{
7574
$io = $this->styleFactory->create($input, $output);
7675
$opts = $this->gatherOptions($input);
7776

7877
[$config, $firstRun] = $this->loadOrSeedConfig($opts['root']);
7978

80-
if ($msgs = $this->validateSchema($config, $opts['strict'])) {
79+
if (($msgs = $this->validateSchema($config)) !== []) {
8180
$this->printIssues($io, $msgs);
8281
if ($opts['strict']) {
8382
$io->error('Strict mode: schema validation failed.');
@@ -101,6 +100,7 @@ protected function execute(InputInterface $input, \Symfony\Component\Console\Out
101100
$found = $this->scanner->scan($opts['root'], $r, $opts['paths']);
102101
$discPaths = array_merge($discPaths, $found);
103102
}
103+
104104
$discPaths = array_values(array_unique($discPaths));
105105
sort($discPaths);
106106

@@ -155,6 +155,7 @@ protected function execute(InputInterface $input, \Symfony\Component\Console\Out
155155
$tot['issues'] ?? 0,
156156
$tot['conflicts'] ?? 0
157157
));
158+
$io->note('You can run this command as many times as you want. Run this after you create a new package.');
158159
return 0;
159160
}
160161

@@ -227,18 +228,12 @@ private function loadOrSeedConfig(string $root): array
227228
}
228229

229230
/** @return list<string> */
230-
private function validateSchema(array $config, bool $strict): array
231+
private function validateSchema(array $config): array
231232
{
232233
// Keeping this simple (we already do type checks in SchemaValidator)
233234
return $this->schemaValidator->validate($config, 'tools/chorale/config/chorale.schema.yaml');
234235
}
235236

236-
/** @return list<string> */
237-
private function discoverPaths(string $root, array $paths): array
238-
{
239-
return $this->scanner->scan($root, $paths);
240-
}
241-
242237
private function printIssues(SymfonyStyle $io, array $messages): void
243238
{
244239
foreach ($messages as $m) {
@@ -251,6 +246,7 @@ private function confirmWrite(SymfonyStyle $io, array $opts): bool
251246
if ($opts['write'] || $opts['acceptAll'] || $opts['nonInteractive']) {
252247
return true;
253248
}
249+
254250
$helper = $this->getHelper('question');
255251
$confirm = new ConfirmationQuestion('Proceed? [Y/n] ', true);
256252

@@ -260,20 +256,22 @@ private function confirmWrite(SymfonyStyle $io, array $opts): bool
260256
/** @return list<string> e.g. ["src","packages"] */
261257
private function determineRoots(array $patterns, string $root): array
262258
{
263-
if ($patterns) {
259+
if ($patterns !== []) {
264260
$roots = [];
265261
foreach ($patterns as $p) {
266262
$m = (string) ($p['match'] ?? '');
267263
if ($m === '') {
268264
continue;
269265
}
266+
270267
// root is first segment before slash
271268
$seg = explode('/', ltrim($m, '/'), 2)[0] ?? '';
272269
if ($seg !== '' && !in_array($seg, $roots, true)) {
273270
$roots[] = $seg;
274271
}
275272
}
276-
return $roots ?: ['src']; // safe fallback if patterns are odd
273+
274+
return $roots !== [] ? $roots : ['src']; // safe fallback if patterns are odd
277275
}
278276

279277
// First run: probe both src and packages
@@ -284,6 +282,7 @@ private function determineRoots(array $patterns, string $root): array
284282
$roots[] = $cand;
285283
}
286284
}
285+
287286
return $roots;
288287
}
289288

@@ -297,6 +296,7 @@ private function displayNameFor(string $projectRoot, string $pkgPath): string
297296
$last = str_contains($name, '/') ? substr($name, strrpos($name, '/') + 1) : $name;
298297
return $last;
299298
}
299+
300300
return basename($pkgPath);
301301
}
302302

@@ -330,7 +330,7 @@ private function classifyAll(string $root, array $defaults, array $patterns, arr
330330
foreach ($byPath as $oldPath => $target) {
331331
if (!in_array($oldPath, $discovered, true)) {
332332
// If target points to a path that no longer exists but a new path with same identity does, propose rename
333-
$maybe = $this->findRenameTarget($root, $oldPath, $target, $defaults, $patterns, $discovered);
333+
$maybe = $this->findRenameTarget($oldPath, $target, $defaults, $patterns, $discovered);
334334
if ($maybe !== null) {
335335
$groups['renamed'][] = $maybe;
336336
}
@@ -370,11 +370,13 @@ private function classifyOne(string $root, string $pkgPath, array $defaults, arr
370370
// Truly untracked: no pattern covers it
371371
return ['group' => 'new', 'data' => ['path' => $pkgPath, 'repo' => $repo, 'package' => $pkgName, 'reason' => 'no-pattern']];
372372
}
373+
373374
// Covered by pattern → OK
374375
$ok = ['path' => $pkgPath, 'repo' => $repo, 'covered_by_pattern' => true, 'package' => $pkgName];
375-
if ($conflictData) {
376+
if ($conflictData !== null && $conflictData !== []) {
376377
$ok['conflict'] = $conflictData['patterns'];
377378
}
379+
378380
return ['group' => 'ok', 'data' => $ok];
379381
}
380382

@@ -399,9 +401,10 @@ private function classifyOne(string $root, string $pkgPath, array $defaults, arr
399401

400402

401403
$ok = ['path' => $pkgPath, 'repo' => $repo, 'package' => $pkgName];
402-
if ($conflictData) {
404+
if ($conflictData !== null && $conflictData !== []) {
403405
$ok['conflict'] = $conflictData['patterns'];
404406
}
407+
405408
return ['group' => 'ok', 'data' => $ok];
406409
}
407410

@@ -413,7 +416,7 @@ private function classifyOne(string $root, string $pkgPath, array $defaults, arr
413416
* @param list<string> $discovered
414417
* @return array<string,mixed>|null
415418
*/
416-
private function findRenameTarget(string $root, string $oldPath, array $target, array $defaults, array $patterns, array $discovered): ?array
419+
private function findRenameTarget(string $oldPath, array $target, array $defaults, array $patterns, array $discovered): ?array
417420
{
418421
$oldRepo = $this->resolver->resolve($defaults, $this->firstPatternFor($patterns, $oldPath), $target, $oldPath, basename($oldPath));
419422
$oldId = $this->identity->identityFor($oldPath, $oldRepo);
@@ -430,6 +433,7 @@ private function findRenameTarget(string $root, string $oldPath, array $target,
430433
];
431434
}
432435
}
436+
433437
return null;
434438
}
435439

@@ -464,7 +468,7 @@ private function buildActions(array $groups, array $existingTargets): array
464468

465469
foreach ($groups['new'] as $row) {
466470
// New only occurs when no pattern covers it → we must add a target (or new pattern, future)
467-
$actions[] = ['type' => 'add-target', 'path' => $row['path'], 'name' => basename($row['path'])];
471+
$actions[] = ['type' => 'add-target', 'path' => $row['path'], 'name' => basename((string) $row['path'])];
468472
}
469473

470474
foreach ($groups['renamed'] as $row) {
@@ -512,6 +516,7 @@ private function applyActions(array $config, array $actions): array
512516
break;
513517
}
514518
}
519+
515520
unset($t);
516521
}
517522
}
@@ -533,29 +538,32 @@ private function renderHumanReport(SymfonyStyle $io, array $groups): void
533538
$io->section('Auto-discovery (src/)');
534539

535540
$this->printGroup($io, 'OK', $groups['ok'], function (array $r): string {
536-
$suffix = !empty($r['covered_by_pattern']) ? ' (pattern)' : '';
541+
$suffix = empty($r['covered_by_pattern']) ? '' : ' (pattern)';
537542
if (!empty($r['conflict'])) {
538543
$suffix .= sprintf(' (conflict: patterns %s)', implode(',', (array) $r['conflict']));
539544
}
545+
540546
return sprintf('%s%s', $r['package'], $suffix);
541547
});
542548

543-
$this->printGroup($io, 'NEW', $groups['new'], fn(array $r) => sprintf('%s → %s (no matching pattern)', $r['path'], $r['repo']));
544-
$this->printGroup($io, 'RENAMED', $groups['renamed'], fn(array $r) => sprintf('%s → %s', $r['from'], $r['to']));
549+
$this->printGroup($io, 'NEW', $groups['new'], fn(array $r): string => sprintf('%s → %s (no matching pattern)', $r['path'], $r['repo']));
550+
$this->printGroup($io, 'RENAMED', $groups['renamed'], fn(array $r): string => sprintf('%s → %s', $r['from'], $r['to']));
545551
$this->printGroup($io, 'DRIFT', $groups['drift'], fn(array $r) => $r['path']);
546-
$this->printGroup($io, 'ISSUES', $groups['issues'], fn(array $r) => sprintf('%s (missing: %s)', $r['path'], implode(', ', (array) ($r['missing'] ?? []))));
547-
$this->printGroup($io, 'CONFLICTS', $groups['conflicts'], fn(array $r) => sprintf('%s (patterns: %s)', $r['path'], implode(', ', (array) ($r['patterns'] ?? []))));
552+
$this->printGroup($io, 'ISSUES', $groups['issues'], fn(array $r): string => sprintf('%s (missing: %s)', $r['path'], implode(', ', (array) ($r['missing'] ?? []))));
553+
$this->printGroup($io, 'CONFLICTS', $groups['conflicts'], fn(array $r): string => sprintf('%s (patterns: %s)', $r['path'], implode(', ', (array) ($r['patterns'] ?? []))));
548554
}
549555

550556
private function printGroup(SymfonyStyle $io, string $title, array $rows, callable $fmt): void
551557
{
552558
if ($rows === []) {
553559
return;
554560
}
555-
$io->writeln("<info>{$title}</info>");
561+
562+
$io->writeln(sprintf('<info>%s</info>', $title));
556563
foreach ($rows as $r) {
557564
$io->writeln('' . $fmt($r));
558565
}
566+
559567
$io->newLine();
560568
}
561569
}

0 commit comments

Comments
 (0)