Skip to content

Commit

Permalink
Adds the --keep-readme and --keep-glob-pattern options
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelstolt committed Nov 11, 2024
1 parent 9f5df2a commit 8aaf671
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 8 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ The `--keep-license` option will allow a license file in the release/dist archiv
lean-package-validator validate [<directory>] --keep-license
```

The `--keep-readme` option will allow a README file in the release/dist archive file which is per default ommitted.

``` bash
lean-package-validator validate [<directory>] --keep-readme
```

The `--keep-glob-pattern` option allows to keep matching files in the release/dist archive file which are per default ommitted.

``` bash
lean-package-validator validate [<directory>] --keep-glob-pattern '{LICENSE.*,README.*,docs*}'
```

The `--align-export-ignores|-a` option will align the created or overwritten export-ignores for a better readability.

``` bash
Expand Down
96 changes: 89 additions & 7 deletions src/Analyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ class Analyser
*/
private bool $keepLicense = false;

/**
* Whether to exclude a README file from the export-ignores
* or not.
*
* @var boolean
*/
private bool $keepReadme = false;


/**
* Pattern to exclude from the export-ignores.
*
* @var string
*/
private string $keepGlobPattern = '';

/**
* Whether to align the export-ignores on create or overwrite
* or not.
Expand Down Expand Up @@ -205,21 +221,22 @@ public function setGlobPatternFromFile(string $file): Analyser
}

/**
* Guard the set glob pattern.
* Guard the given glob pattern.
*
* @throws \Stolt\LeanPackage\Exceptions\InvalidGlobPattern
* @param string $pattern
* @throws InvalidGlobPattern
* @return void
*/
private function guardGlobPattern(): void
private function guardGlobPattern(string $pattern): void
{
$invalidGlobPattern = false;

if (\substr($this->globPattern, 0) !== '{'
&& (\substr($this->globPattern, -1) !== '}' && \substr($this->globPattern, -2) !== '}*')) {
if (\substr($pattern, 0) !== '{'
&& (\substr($pattern, -1) !== '}' && \substr($pattern, -2) !== '}*')) {
$invalidGlobPattern = true;
}

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

if (empty($bracesContent)) {
$invalidGlobPattern = true;
Expand Down Expand Up @@ -250,7 +267,7 @@ private function guardGlobPattern(): void
public function setGlobPattern($pattern): Analyser
{
$this->globPattern = \trim($pattern);
$this->guardGlobPattern();
$this->guardGlobPattern($this->globPattern);

return $this;
}
Expand Down Expand Up @@ -376,6 +393,53 @@ public function isKeepLicenseEnabled(): bool
return $this->keepLicense === true;
}

/**
* Keep README file in releases.
*
* @return Analyser
*/
public function keepReadme(): Analyser
{
$this->keepReadme = true;

return $this;
}

/**
* Guard for not export-ignoring README file.
*
* @return boolean
*/
public function isKeepReadmeEnabled(): bool
{
return $this->keepReadme === true;
}

/**
* Sets the glob pattern for not export-ignoring license files.
*
* @param string $globPattern
* @throws InvalidGlobPattern
* @return Analyser
*/
public function setKeepGlobPattern(string $globPattern): Analyser
{
$this->guardGlobPattern($globPattern);
$this->keepGlobPattern = $globPattern;

return $this;
}

/**
* Guard for not export-ignoring glob pattern.
*
* @return boolean
*/
public function isKeepGlobPatternSet(): bool
{
return $this->keepGlobPattern !== '';
}

/**
* Align export-ignores.
*
Expand Down Expand Up @@ -635,6 +699,24 @@ public function collectExpectedExportIgnores(): array
$expectedExportIgnores = $licenseLessExpectedExportIgnores;
}

if ($this->isKeepReadmeEnabled()) {
$readmeLessExpectedExportIgnores = [];
\array_filter($expectedExportIgnores, function ($exportIgnore) use (
&$readmeLessExpectedExportIgnores
) {
if (!\preg_match('/(Readme.*)/i', $exportIgnore)) {
$readmeLessExpectedExportIgnores[] = $exportIgnore;
}
});

$expectedExportIgnores = $readmeLessExpectedExportIgnores;
}

if ($this->isKeepGlobPatternSet()) {
$excludes = Glob::globArray($this->keepGlobPattern, $expectedExportIgnores);
$expectedExportIgnores = \array_diff($expectedExportIgnores, $excludes);
}

return \array_unique($expectedExportIgnores);
}

Expand Down
45 changes: 44 additions & 1 deletion src/Commands/ValidateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ protected function configure(): void
$globPatternFileDescription = 'Use this file with glob patterns '
. 'to match artifacts which should be export-ignored';

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

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

Expand Down Expand Up @@ -143,6 +145,18 @@ protected function configure(): void
InputOption::VALUE_NONE,
$keepLicenseDescription
);
$this->addOption(
'keep-readme',
null,
InputOption::VALUE_NONE,
$keepReadmeDescription
);
$this->addOption(
'keep-glob-pattern',
null,
InputOption::VALUE_NONE,
$keepGlobPatternDescription
);
$this->addOption(
'align-export-ignores',
'a',
Expand Down Expand Up @@ -245,6 +259,35 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->analyser->keepLicense();
}

$keepReadme = (boolean) $input->getOption('keep-readme');

if ($keepReadme) {
$verboseOutput = '+ Keeping the README file.';
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);

$this->analyser->keepReadme();
}

$keepGlobPattern = (string) $input->getOption('keep-glob-pattern');

if ($keepGlobPattern !== '') {
$verboseOutput = \sprintf('+ Keeping files matching the glob pattern <info>%s</info>.', $keepGlobPattern);
$output->writeln($verboseOutput, OutputInterface::VERBOSITY_VERBOSE);
try {
$this->analyser->setKeepGlobPattern($keepGlobPattern);
} catch (InvalidGlobPattern $e) {
$warning = "Warning: The provided glob pattern "
. "'$keepGlobPattern' is considered invalid.";
$outputContent = '<error>' . $warning . '</error>';
$output->writeln($outputContent);

$output->writeln($e->getMessage(), OutputInterface::VERBOSITY_DEBUG);

return Command::FAILURE;
}
}


$alignExportIgnores = $input->getOption('align-export-ignores');

if ($alignExportIgnores) {
Expand Down
28 changes: 28 additions & 0 deletions src/Glob.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,34 @@ public static function glob($pattern, $flags = 0, $forceFallback = false)
return static::systemGlob($pattern, $flags);
}

/**
* Find array elements matching a pattern.
*
* @param string $pattern
* @param array $array
* @param int $flags
* @return array
*/
public static function globArray(string $pattern, array $array, int $flags = FNM_CASEFOLD)
{
$pattern = \str_replace(['{', '}'], '', $pattern);

$patternParts = \explode(',', $pattern);

foreach ($patternParts as $index => $patternPart) {
$matches[] = \array_filter($array, function ($val) use ($patternPart, $flags) {
return \fnmatch($patternPart, $val, $flags);
});
}

$excludes = [];
foreach ($matches as $index => $value) {
$excludes[] = \array_values($value)[0];
}

return $excludes;
}

/**
* Use the glob function provided by the system.
*
Expand Down
71 changes: 71 additions & 0 deletions tests/AnalyserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,77 @@ public function licenseFileIsNotExportIgnored(): void
);
}

#[Test]
#[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/47')]
public function readmeFileIsNotExportIgnored(): void
{
$artifactFilenames = [
'LICENSE.txt',
'README.md',
'phpspec.yml.dist',
];

$this->createTemporaryFiles(
$artifactFilenames,
['specs']
);

$expectedGitattributesContent = <<<CONTENT
* text=auto eol=lf
.gitattributes export-ignore
LICENSE.txt export-ignore
phpspec.yml.dist export-ignore
specs/ export-ignore
CONTENT;

$analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->keepReadme();
$actualGitattributesContent = $analyser->getExpectedGitattributesContent();

$this->assertTrue($analyser->isKeepReadmeEnabled());
$this->assertEquals(
$expectedGitattributesContent,
$actualGitattributesContent
);
}

/**
* @throws InvalidGlobPattern
*/
#[Test]
public function filesMatchingKeepGlobPatternAreNotExportIgnored(): void
{
$artifactFilenames = [
'LICENSE.txt',
'README.rst',
'phpspec.yml.dist',
];

$this->createTemporaryFiles(
$artifactFilenames,
['specs', 'docs']
);

$expectedGitattributesContent = <<<CONTENT
* text=auto eol=lf
.gitattributes export-ignore
phpspec.yml.dist export-ignore
specs/ export-ignore
CONTENT;

$analyser = (new Analyser(new Finder(new PhpPreset())))->setDirectory($this->temporaryDirectory)->setKeepGlobPattern('{LICENSE.*,README.*,docs*}');
$actualGitattributesContent = $analyser->getExpectedGitattributesContent();

$this->assertTrue($analyser->isKeepGlobPatternSet());
$this->assertEquals(
$expectedGitattributesContent,
$actualGitattributesContent
);
}

#[Test]
#[Ticket('https://github.com/raphaelstolt/lean-package-validator/issues/24')]
public function directoriesOnlyExportIgnoredOnce(): void
Expand Down
Loading

0 comments on commit 8aaf671

Please sign in to comment.