Skip to content

Commit 922439d

Browse files
committed
Fixes generated or modified header
1 parent 4b565f6 commit 922439d

10 files changed

+148
-105
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
88
## [Unreleased]
99

1010

11+
## [v5.2.1] - 2025-10-17
12+
13+
### Fixed
14+
- The correct file `HEADERS` (generated|modified) are written.
15+
1116
## [v5.2.0] - 2025-09-26
1217

1318
### Added
@@ -430,7 +435,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
430435

431436
- Initial release.
432437

433-
[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v5.2.0...HEAD
438+
[Unreleased]: https://github.com/raphaelstolt/lean-package-validator/compare/v5.2.1...HEAD
439+
[v5.2.1]: https://github.com/raphaelstolt/lean-package-validator/compare/v5.2.0...v5.2.1
434440
[v5.2.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v5.1.0...v5.2.0
435441
[v5.1.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v5.0.0...v5.1.0
436442
[v5.0.0]: https://github.com/raphaelstolt/lean-package-validator/compare/v4.7.1...v5.0.0

src/Analyser.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,7 @@ public function getExpectedGitattributesContent(array $postfixLessExportIgnores
597597
. $exportIgnoreContent;
598598
}
599599
} else {
600-
$content = "* text=auto eol=lf"
601-
. \str_repeat($this->preferredEol, 2)
602-
. $content;
600+
$content = "* text=auto eol=lf" . \str_repeat($this->preferredEol, 2) . $content;
603601
}
604602

605603
return $content;

src/Commands/ValidateCommand.php

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
288288
$verboseOutput = '+ Scanning directory ' . $directory . '.';
289289
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
290290

291-
// Print deprecation notices for legacy options but do NOT change exit code.
291+
// Print deprecation notices for legacy options but do NOT change the exit code.
292292
if ($input->hasOption('create') && (bool) $input->getOption('create')) {
293293
$output->writeln('<comment>The --create option is deprecated. Please use the dedicated <info>create</info> command.</comment>');
294294
}
@@ -306,7 +306,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
306306
$validateArchive = $input->getOption('validate-git-archive');
307307
$globPattern = $input->getOption('glob-pattern');
308308
$globPatternFile = (string) $input->getOption('glob-pattern-file');
309-
$omitHeader = $input->getOption('omit-header');
309+
$omitHeader = (boolean) $input->getOption('omit-header');
310+
310311
$showDifference = $input->getOption('diff');
311312
$reportStaleExportIgnores = $input->getOption('report-stale-export-ignores');
312313

@@ -455,26 +456,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int
455456

456457
$verboseOutput = '+ Checking .gitattribute file existence in ' . $directory . '.';
457458
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
459+
$outputContent = '';
458460

459461
if (!$this->analyser->hasGitattributesFile()) {
460-
$warning = 'Warning: There is no .gitattributes file present in '
461-
. $this->analyser->getDirectory() . '.';
462-
$outputContent = '<error>' . $warning . '</error>';
463-
464-
$expectedGitattributesFileContent = $this->analyser
465-
->getExpectedGitattributesContent();
462+
if ($createGitattributesFile === false) {
463+
$warning = 'Warning: There is no .gitattributes file present in '
464+
. $this->analyser->getDirectory() . '.';
465+
$outputContent.= '<error>' . $warning . '</error>';
466+
}
466467

467468
$verboseOutput = '+ Getting expected .gitattribute file content.';
468469
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
469470

471+
$expectedGitattributesFileContent = $this->analyser
472+
->getExpectedGitattributesContent();
473+
470474
if ($expectedGitattributesFileContent !== '') {
475+
471476
if ($createGitattributesFile || $overwriteGitattributesFile) {
472477
try {
473478
$outputContent .= $this->gitattributesFileRepository->createGitattributesFile(
474479
$expectedGitattributesFileContent,
475-
$omitHeader === false
480+
$omitHeader
476481
);
477-
478482
$output->writeln($outputContent);
479483

480484
return Command::SUCCESS;
@@ -562,17 +566,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
562566
}
563567
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
564568

565-
if ($omitHeader === false) {
566-
if (\str_contains($expectedGitattributesFileContent, GitattributesFileRepository::GENERATED_HEADER)) {
567-
$expectedGitattributesFileContent = \str_replace(
568-
GitattributesFileRepository::GENERATED_HEADER . PHP_EOL . PHP_EOL,
569-
'',
570-
$expectedGitattributesFileContent
571-
);
572-
}
573-
$expectedGitattributesFileContent = GitattributesFileRepository::MODIFIED_HEADER . PHP_EOL . PHP_EOL . $expectedGitattributesFileContent;
574-
}
575-
576569
$outputContent .= $this->gitattributesFileRepository->overwriteGitattributesFile(
577570
$expectedGitattributesFileContent
578571
);

src/GitattributesFileRepository.php

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,7 @@ public function createGitattributesFile(string $content, bool $withHeader = true
3131
{
3232
// Ensure the "generated by" header is present when requested.
3333
if ($withHeader) {
34-
$headerPrefix = self::GENERATED_HEADER . PHP_EOL . PHP_EOL;
35-
36-
if (!\str_starts_with($content, self::GENERATED_HEADER . PHP_EOL)
37-
&& !\str_starts_with($content, $headerPrefix)
38-
) {
39-
$content = $headerPrefix . $content;
40-
}
34+
$content = $this->applyOverwriteHeaderPolicy($content);
4135
}
4236

4337
$bytesWritten = file_put_contents(
@@ -95,27 +89,15 @@ public function applyOverwriteHeaderPolicy(string $contentToWrite): string
9589
$gitattributesPath = $this->analyser->getGitattributesFilePath();
9690

9791
if (!\is_file($gitattributesPath)) {
98-
return $contentToWrite;
92+
return self::GENERATED_HEADER . PHP_EOL . PHP_EOL . $contentToWrite;
9993
}
10094

101-
$presentContent = (string) @\file_get_contents($gitattributesPath);
102-
if ($presentContent === '') {
103-
return $contentToWrite;
95+
if (\str_contains($contentToWrite, self::GENERATED_HEADER)) {
96+
return \str_replace(self::GENERATED_HEADER, self::MODIFIED_HEADER, $contentToWrite);
10497
}
10598

106-
if (\str_contains($presentContent, self::GENERATED_HEADER)) {
107-
$generatedPrefix = self::GENERATED_HEADER . PHP_EOL;
108-
$modifiedPrefix = self::MODIFIED_HEADER . PHP_EOL;
109-
110-
// If the new content starts with the "generated by" header, replace it.
111-
if (\str_starts_with($contentToWrite, $generatedPrefix)) {
112-
return $modifiedPrefix . \substr($contentToWrite, \strlen($generatedPrefix));
113-
}
114-
115-
// If no header is present at the top, prepend the "partly modified" header.
116-
if (!\str_starts_with($contentToWrite, $modifiedPrefix)) {
117-
return self::MODIFIED_HEADER . PHP_EOL . PHP_EOL . $contentToWrite;
118-
}
99+
if ((\str_contains($contentToWrite, self::MODIFIED_HEADER) === false) && (\str_contains($contentToWrite, self::GENERATED_HEADER) === false)) {
100+
return self::MODIFIED_HEADER . PHP_EOL . PHP_EOL . $contentToWrite;
119101
}
120102

121103
return $contentToWrite;

tests/Commands/CreateCommandTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ public function failsIfGitattributesAlreadyExists(): void
103103
}
104104

105105
$gitattributesContent = <<<CONTENT
106-
* text=auto eol=lf
107106
108107
phpspec.yml.dist export-ignore
109108
specs/ export-ignore

tests/Commands/UpdateCommandTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ public function updatesExistingGitattributesAndReplacesHeader(): void
4848
$gitattributesContent = <<<CONTENT
4949
# This file was generated by the lean package validator (http://git.io/lean-package-validator).
5050
51-
* text=auto eol=lf
52-
5351
.gitattributes export-ignore
5452
.github/ export-ignore
5553
tests/ export-ignore

tests/Commands/ValidateCommandStdinOptionsTest.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public function stdinHonorsStrictOrderAndReportsInvalidOnShuffledOrder(): void
6161

6262
// Shuffled order: README before dotfiles, etc.
6363
$stdinContent = <<<GITATTR
64-
* text=auto eol=lf
6564
6665
README.md export-ignore
6766
tests/ export-ignore
@@ -94,7 +93,6 @@ public function stdinHonorsStrictOrderAndReportsValidOnExpectedOrder(): void
9493

9594
// Likely expected order: .gitattributes, .gitignore, README.md, tests/
9695
$stdinContent = <<<GITATTR
97-
* text=auto eol=lf
9896
9997
.gitattributes export-ignore
10098
.gitignore export-ignore
@@ -127,7 +125,6 @@ public function stdinHonorsEnforceAlignmentAndReportsValidOnExpectedOrder(): voi
127125

128126
// Likely expected order: .gitattributes, .gitignore, README.md, tests/
129127
$stdinContent = <<<GITATTR
130-
* text=auto eol=lf
131128
132129
.gitattributes export-ignore
133130
.gitignore export-ignore

tests/Commands/ValidateCommandTest.php

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Mockery\MockInterface;
99
use phpmock\functions\FixedValueFunction;
1010
use phpmock\MockBuilder;
11+
use phpmock\phpunit\PHPMock;
1112
use PHPUnit\Framework\Attributes\DataProvider;
1213
use PHPUnit\Framework\Attributes\Group;
1314
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
@@ -17,8 +18,10 @@
1718
use Stolt\LeanPackage\Archive;
1819
use Stolt\LeanPackage\Archive\Validator;
1920
use Stolt\LeanPackage\Commands\ValidateCommand;
21+
use Stolt\LeanPackage\Exceptions\GitattributesCreationFailed;
2022
use Stolt\LeanPackage\Exceptions\InvalidGlobPattern;
2123
use Stolt\LeanPackage\Exceptions\NoLicenseFilePresent;
24+
use Stolt\LeanPackage\GitattributesFileRepository;
2225
use Stolt\LeanPackage\Helpers\Str as OsHelper;
2326
use Stolt\LeanPackage\Presets\Finder;
2427
use Stolt\LeanPackage\Presets\PhpPreset;
@@ -33,6 +36,7 @@
3336
class ValidateCommandTest extends TestCase
3437
{
3538
use InteractsWithConsole;
39+
use PHPMock;
3640

3741
/**
3842
* Set up a test environment.
@@ -795,8 +799,8 @@ public function failingGitattributesFilesCreationReturnsExpectedStatusCode(): vo
795799

796800
$builder = new MockBuilder();
797801
$builder->setNamespace('Stolt\LeanPackage')
798-
->setName('file_put_contents')
799-
->setFunctionProvider(new FixedValueFunction(false));
802+
->setName('file_put_contents')
803+
->setFunctionProvider(new FixedValueFunction(false));
800804

801805
$mock = $builder->build();
802806
$mock->enable();
@@ -811,14 +815,14 @@ public function failingGitattributesFilesCreationReturnsExpectedStatusCode(): vo
811815

812816
$expectedDisplay = <<<CONTENT
813817
The --create option is deprecated. Please use the dedicated create command.
814-
Warning: There is no .gitattributes file present in {$this->temporaryDirectory}.
818+
815819
816820
Creation of .gitattributes file failed.
817821
818822
CONTENT;
819823

820824
$this->assertSame($expectedDisplay, $commandTester->getDisplay());
821-
$this->assertTrue($commandTester->getStatusCode() > Command::SUCCESS);
825+
$this->assertSame(Command::FAILURE, $commandTester->getStatusCode());
822826

823827
$mock->disable();
824828
}
@@ -842,21 +846,8 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates
842846
'--omit-header' => true
843847
]);
844848

845-
$expectedDisplay = <<<CONTENT
846-
The --create option is deprecated. Please use the dedicated create command.
847-
Warning: There is no .gitattributes file present in {$this->temporaryDirectory}.
848-
849-
Created a .gitattributes file with the shown content:
850-
* text=auto eol=lf
851-
852-
.gitattributes export-ignore
853-
CONDUCT.md export-ignore
854-
specs/ export-ignore
855-
856-
857-
CONTENT;
858-
859-
$this->assertEquals($expectedDisplay, $commandTester->getDisplay());
849+
$this->assertStringNotContainsString(GitattributesFileRepository::GENERATED_HEADER, $commandTester->getDisplay());
850+
$this->assertStringNotContainsString(GitattributesFileRepository::MODIFIED_HEADER, $commandTester->getDisplay());
860851
$commandTester->assertCommandIsSuccessful();
861852
$this->assertFileExists(
862853
WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes'
@@ -875,29 +866,17 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates
875866

876867
$command = $this->application->find('validate');
877868
$commandTester = new CommandTester($command);
869+
870+
$this->assertFileDoesNotExist(
871+
WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes'
872+
);
873+
878874
$commandTester->execute([
879875
'command' => $command->getName(),
880876
'directory' => WORKING_DIRECTORY,
881877
'--create' => true,
882878
]);
883879

884-
$expectedDisplay = <<<CONTENT
885-
The --create option is deprecated. Please use the dedicated create command.
886-
Warning: There is no .gitattributes file present in {$this->temporaryDirectory}.
887-
888-
Created a .gitattributes file with the shown content:
889-
# This file was generated by the lean package validator (http://git.io/lean-package-validator).
890-
891-
* text=auto eol=lf
892-
893-
.gitattributes export-ignore
894-
CONDUCT.md export-ignore
895-
specs/ export-ignore
896-
897-
898-
CONTENT;
899-
900-
$this->assertEquals($expectedDisplay, $commandTester->getDisplay());
901880
$commandTester->assertCommandIsSuccessful();
902881
$this->assertFileExists(
903882
WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes'
@@ -929,7 +908,6 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates
929908

930909
$expectedDisplay = <<<CONTENT
931910
The --create option is deprecated. Please use the dedicated create command.
932-
Warning: There is no .gitattributes file present in {$this->temporaryDirectory}.
933911
934912
Created a .gitattributes file with the shown content:
935913
# This file was generated by the lean package validator (http://git.io/lean-package-validator).
@@ -940,25 +918,18 @@ public function validateOnNonExistentGitattributesFilesWithCreationOptionCreates
940918
CONDUCT.md export-ignore
941919
specs/ export-ignore
942920
943-
944921
CONTENT;
945922

946-
$expectedGitattributesContent = <<<CONTENT
947-
# This file was generated by the lean package validator (http://git.io/lean-package-validator).
948-
949-
* text=auto eol=lf
950-
923+
$expectedGitattributesExportIgnores = <<<CONTENT
951924
.gitattributes export-ignore
952925
CONDUCT.md export-ignore
953926
specs/ export-ignore
954-
955927
CONTENT;
956928

957-
$this->assertEquals($expectedDisplay, $commandTester->getDisplay());
929+
$this->assertStringContainsString($expectedGitattributesExportIgnores, $commandTester->getDisplay());
958930
$commandTester->assertCommandIsSuccessful();
959-
$this->assertStringEqualsFile(
960-
WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes',
961-
$expectedGitattributesContent
931+
$this->assertFileExists(
932+
WORKING_DIRECTORY . DIRECTORY_SEPARATOR . '.gitattributes'
962933
);
963934
}
964935

@@ -1608,7 +1579,7 @@ public function incompleteGitattributesFileIsOverwritten(string $option): void
16081579
version-increase-command export-ignore
16091580
CONTENT;
16101581

1611-
$this->createTemporaryGitattributesFile($gitattributesContent);
1582+
$this->assertTrue($this->createTemporaryGitattributesFile($gitattributesContent));
16121583

16131584
$artifactFilenames = ['phpspec.yml.dist', 'version-increase-command'];
16141585

@@ -1617,6 +1588,16 @@ public function incompleteGitattributesFileIsOverwritten(string $option): void
16171588
['specs']
16181589
);
16191590

1591+
$header = GitattributesFileRepository::GENERATED_HEADER . PHP_EOL . PHP_EOL;
1592+
1593+
if ($option === '--overwrite') {
1594+
$header = GitattributesFileRepository::MODIFIED_HEADER . PHP_EOL;
1595+
}
1596+
1597+
if ($option === '--create') {
1598+
$header = GitattributesFileRepository::MODIFIED_HEADER . PHP_EOL . PHP_EOL;
1599+
}
1600+
16201601
$command = $this->application->find('validate');
16211602
$commandTester = new CommandTester($command);
16221603
$commandTester->execute([
@@ -1633,6 +1614,7 @@ public function incompleteGitattributesFileIsOverwritten(string $option): void
16331614
The present .gitattributes file is considered invalid.
16341615
16351616
Overwrote it with the shown content:
1617+
$header
16361618
* text=auto eol=lf
16371619
16381620
.gitattributes export-ignore

0 commit comments

Comments
 (0)