Skip to content

Commit edc4fbe

Browse files
committed
Adds the --keep-readme and --keep-glob-pattern options
1 parent 9f5df2a commit edc4fbe

File tree

6 files changed

+330
-8
lines changed

6 files changed

+330
-8
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ The `--keep-license` option will allow a license file in the release/dist archiv
123123
lean-package-validator validate [<directory>] --keep-license
124124
```
125125

126+
The `--keep-readme` option will allow a README file in the release/dist archive file which is per default ommitted.
127+
128+
``` bash
129+
lean-package-validator validate [<directory>] --keep-readme
130+
```
131+
132+
The `--keep-glob-pattern` option allows to keep matching files in the release/dist archive file which are per default ommitted.
133+
134+
``` bash
135+
lean-package-validator validate [<directory>] --keep-glob-pattern '{LICENSE.*,README.*,docs*}'
136+
```
137+
126138
The `--align-export-ignores|-a` option will align the created or overwritten export-ignores for a better readability.
127139

128140
``` bash

src/Analyser.php

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ class Analyser
102102
*/
103103
private bool $keepLicense = false;
104104

105+
/**
106+
* Whether to exclude a README file from the export-ignores
107+
* or not.
108+
*
109+
* @var boolean
110+
*/
111+
private bool $keepReadme = false;
112+
113+
114+
/**
115+
* Pattern to exclude from the export-ignores.
116+
*
117+
* @var string
118+
*/
119+
private string $keepGlobPattern = '';
120+
105121
/**
106122
* Whether to align the export-ignores on create or overwrite
107123
* or not.
@@ -205,21 +221,22 @@ public function setGlobPatternFromFile(string $file): Analyser
205221
}
206222

207223
/**
208-
* Guard the set glob pattern.
224+
* Guard the given glob pattern.
209225
*
210-
* @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern
226+
* @param string $pattern
227+
* @throws InvalidGlobPattern
211228
* @return void
212229
*/
213-
private function guardGlobPattern(): void
230+
private function guardGlobPattern(string $pattern): void
214231
{
215232
$invalidGlobPattern = false;
216233

217-
if (\substr($this->globPattern, 0) !== '{'
218-
&& (\substr($this->globPattern, -1) !== '}' && \substr($this->globPattern, -2) !== '}*')) {
234+
if (\substr($pattern, 0) !== '{'
235+
&& (\substr($pattern, -1) !== '}' && \substr($pattern, -2) !== '}*')) {
219236
$invalidGlobPattern = true;
220237
}
221238

222-
$bracesContent = \trim(\substr($this->globPattern, 1, -1));
239+
$bracesContent = \trim(\substr($pattern, 1, -1));
223240

224241
if (empty($bracesContent)) {
225242
$invalidGlobPattern = true;
@@ -250,7 +267,7 @@ private function guardGlobPattern(): void
250267
public function setGlobPattern($pattern): Analyser
251268
{
252269
$this->globPattern = \trim($pattern);
253-
$this->guardGlobPattern();
270+
$this->guardGlobPattern($this->globPattern);
254271

255272
return $this;
256273
}
@@ -376,6 +393,53 @@ public function isKeepLicenseEnabled(): bool
376393
return $this->keepLicense === true;
377394
}
378395

396+
/**
397+
* Keep README file in releases.
398+
*
399+
* @return Analyser
400+
*/
401+
public function keepReadme(): Analyser
402+
{
403+
$this->keepReadme = true;
404+
405+
return $this;
406+
}
407+
408+
/**
409+
* Guard for not export-ignoring README file.
410+
*
411+
* @return boolean
412+
*/
413+
public function isKeepReadmeEnabled(): bool
414+
{
415+
return $this->keepReadme === true;
416+
}
417+
418+
/**
419+
* Sets the glob pattern for not export-ignoring license files.
420+
*
421+
* @param string $globPattern
422+
* @throws InvalidGlobPattern
423+
* @return Analyser
424+
*/
425+
public function setKeepGlobPattern(string $globPattern): Analyser
426+
{
427+
$this->guardGlobPattern($globPattern);
428+
$this->keepGlobPattern = $globPattern;
429+
430+
return $this;
431+
}
432+
433+
/**
434+
* Guard for not export-ignoring glob pattern.
435+
*
436+
* @return boolean
437+
*/
438+
public function isKeepGlobPatternSet(): bool
439+
{
440+
return $this->keepGlobPattern !== '';
441+
}
442+
379443
/**
380444
* Align export-ignores.
381445
*
@@ -635,6 +699,24 @@ public function collectExpectedExportIgnores(): array
635699
$expectedExportIgnores = $licenseLessExpectedExportIgnores;
636700
}
637701

702+
if ($this->isKeepReadmeEnabled()) {
703+
$readmeLessExpectedExportIgnores = [];
704+
\array_filter($expectedExportIgnores, function ($exportIgnore) use (
705+
&$readmeLessExpectedExportIgnores
706+
) {
707+
if (!\preg_match('/(Readme.*)/i', $exportIgnore)) {
708+
$readmeLessExpectedExportIgnores[] = $exportIgnore;
709+
}
710+
});
711+
712+
$expectedExportIgnores = $readmeLessExpectedExportIgnores;
713+
}
714+
715+
if ($this->isKeepGlobPatternSet()) {
716+
$excludes = Glob::globArray($this->keepGlobPattern, $expectedExportIgnores);
717+
$expectedExportIgnores = \array_diff($expectedExportIgnores, $excludes);
718+
}
719+
638720
return \array_unique($expectedExportIgnores);
639721
}
640722

src/Commands/ValidateCommand.php

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ protected function configure(): void
9999
$globPatternFileDescription = 'Use this file with glob patterns '
100100
. 'to match artifacts which should be export-ignored';
101101

102-
$keepLicenseDescription = 'Do not export-ignore license file';
102+
$keepLicenseDescription = 'Do not export-ignore the license file';
103+
$keepReadmeDescription = 'Do not export-ignore the README file';
104+
$keepGlobPatternDescription = 'Do not export-ignore matching glob pattern e.g. <comment>{LICENSE.*,README.*,docs*}</comment>';
103105

104106
$alignExportIgnoresDescription = 'Align export-ignores on create or overwrite';
105107

@@ -143,6 +145,18 @@ protected function configure(): void
143145
InputOption::VALUE_NONE,
144146
$keepLicenseDescription
145147
);
148+
$this->addOption(
149+
'keep-readme',
150+
null,
151+
InputOption::VALUE_NONE,
152+
$keepReadmeDescription
153+
);
154+
$this->addOption(
155+
'keep-glob-pattern',
156+
null,
157+
InputOption::VALUE_NONE,
158+
$keepGlobPatternDescription
159+
);
146160
$this->addOption(
147161
'align-export-ignores',
148162
'a',
@@ -245,6 +259,35 @@ protected function execute(InputInterface $input, OutputInterface $output): int
245259
$this->analyser->keepLicense();
246260
}
247261

262+
$keepReadme = (boolean) $input->getOption('keep-readme');
263+
264+
if ($keepReadme) {
265+
$verboseOutput = '+ Keeping the README file.';
266+
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
267+
268+
$this->analyser->keepReadme();
269+
}
270+
271+
$keepGlobPattern = (string) $input->getOption('keep-glob-pattern');
272+
273+
if ($keepGlobPattern !== '') {
274+
$verboseOutput = \sprintf('+ Keeping files matching the glob pattern <info>%s</info>.', $keepGlobPattern);
275+
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
276+
try {
277+
$this->analyser->setKeepGlobPattern($keepGlobPattern);
278+
} catch (InvalidGlobPattern $e) {
279+
$warning = "Warning: The provided glob pattern "
280+
. "'$keepGlobPattern' is considered invalid.";
281+
$outputContent = '<error>' . $warning . '</error>';
282+
$output->writeln($outputContent);
283+
284+
$output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG);
285+
286+
return Command::FAILURE;
287+
}
288+
}
289+
290+
248291
$alignExportIgnores = $input->getOption('align-export-ignores');
249292

250293
if ($alignExportIgnores) {

src/Glob.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,34 @@ public static function glob($pattern, $flags = 0, $forceFallback = false)
5656
return static::systemGlob($pattern, $flags);
5757
}
5858

59+
/**
60+
* Find array elements matching a pattern.
61+
*
62+
* @param $pattern
63+
* @param array $array
64+
* @param $flags
65+
* @return array
66+
*/
67+
public static function globArray($pattern, array $array, $flags = FNM_CASEFOLD)
68+
{
69+
$pattern = \str_replace(['{', '}'], '', $pattern);
70+
71+
$patternParts = \explode(',', $pattern);
72+
73+
foreach ($patternParts as $index => $patternPart) {
74+
$matches[] = \array_filter($array, function ($val) use ($patternPart, $flags) {
75+
return \fnmatch($patternPart, $val, $flags);
76+
});
77+
}
78+
79+
$excludes = [];
80+
foreach ($matches as $index => $value) {
81+
$excludes[] = \array_values($value)[0];
82+
}
83+
84+
return $excludes;
85+
}
86+
5987
/**
6088
* Use the glob function provided by the system.
6189
*

tests/AnalyserTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,77 @@ public function licenseFileIsNotExportIgnored(): void
10851085
);
10861086
}
10871087

1088+
#[Test]
1089+
#[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/47')]
1090+
public function readmeFileIsNotExportIgnored(): void
1091+
{
1092+
$artifactFilenames = [
1093+
'LICENSE.txt',
1094+
'README.md',
1095+
'phpspec.yml.dist',
1096+
];
1097+
1098+
$this->createTemporaryFiles(
1099+
$artifactFilenames,
1100+
['specs']
1101+
);
1102+
1103+
$expectedGitattributesContent = <<<CONTENT
1104+
* text=auto eol=lf
1105+
1106+
.gitattributes export-ignore
1107+
LICENSE.txt export-ignore
1108+
phpspec.yml.dist export-ignore
1109+
specs/ export-ignore
1110+
1111+
CONTENT;
1112+
1113+
$analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->keepReadme();
1114+
$actualGitattributesContent = $analyser->getExpectedGitattributesContent();
1115+
1116+
$this->assertTrue($analyser->isKeepReadmeEnabled());
1117+
$this->assertEquals(
1118+
$expectedGitattributesContent,
1119+
$actualGitattributesContent
1120+
);
1121+
}
1122+
1123+
/**
1124+
* @throws InvalidGlobPattern
1125+
*/
1126+
#[Test]
1127+
public function filesMatchingKeepGlobPatternAreNotExportIgnored(): void
1128+
{
1129+
$artifactFilenames = [
1130+
'LICENSE.txt',
1131+
'README.rst',
1132+
'phpspec.yml.dist',
1133+
];
1134+
1135+
$this->createTemporaryFiles(
1136+
$artifactFilenames,
1137+
['specs', 'docs']
1138+
);
1139+
1140+
$expectedGitattributesContent = <<<CONTENT
1141+
* text=auto eol=lf
1142+
1143+
.gitattributes export-ignore
1144+
phpspec.yml.dist export-ignore
1145+
specs/ export-ignore
1146+
1147+
CONTENT;
1148+
1149+
$analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->setKeepGlobPattern('{LICENSE.*,README.*,docs*}');
1150+
$actualGitattributesContent = $analyser->getExpectedGitattributesContent();
1151+
1152+
$this->assertTrue($analyser->isKeepGlobPatternSet());
1153+
$this->assertEquals(
1154+
$expectedGitattributesContent,
1155+
$actualGitattributesContent
1156+
);
1157+
}
1158+
10881159
#[Test]
10891160
#[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/24')]
10901161
public function directoriesOnlyExportIgnoredOnce(): void

0 commit comments

Comments
 (0)