Skip to content

Commit 1d6ff79

Browse files
author
DDEV User
committed
merge in main of grumphp-bom-task
2 parents dac0c26 + e8f8f39 commit 1d6ff79

15 files changed

+1021
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Run grumphp with different versions
2+
on: [push]
3+
jobs:
4+
test:
5+
runs-on: ubuntu-latest
6+
strategy:
7+
fail-fast: false
8+
matrix:
9+
php: ['8.1', '8.2', '8.3']
10+
container:
11+
image: kanti/buildy:${{ matrix.php }}
12+
steps:
13+
- uses: actions/checkout@v4
14+
- run: git config --global --add safe.directory /__w/grumphp-bom-task/grumphp-bom-task
15+
- run: COMPOSER_ROOT_VERSION=dev-main composer install --no-progress --no-scripts -n
16+
- run: ./vendor/bin/grumphp run

packages/grumphp-bom-task/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor/
2+
composer.lock
3+
var/

packages/grumphp-bom-task/LICENSE.txt

+674
Large diffs are not rendered by default.

packages/grumphp-bom-task/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[![Packagist](https://img.shields.io/packagist/v/pluswerk/grumphp-bom-task.svg?style=flat-square)](https://packagist.org/packages/pluswerk/grumphp-bom-task)
2+
[![Packagist](https://img.shields.io/packagist/l/pluswerk/grumphp-bom-task.svg?style=flat-square)](https://opensource.org/licenses/LGPL-3.0)
3+
[![Travis](https://img.shields.io/travis/Kanti/LJSON.svg?style=flat-square)](https://travis-ci.org/Pluswerk/grumphp-bom-task)
4+
[![Code Climate](https://img.shields.io/codeclimate/maintainability/pluswerk/grumphp-bom-task.svg?style=flat-square)](https://codeclimate.com/github/pluswerk/grumphp-bom-task)
5+
[![SymfonyInsight Grade](https://img.shields.io/symfony/i/grade/69cf4b58-b856-4f79-a3da-a89291eae102.svg?style=flat-square)](https://insight.symfony.com/projects/69cf4b58-b856-4f79-a3da-a89291eae102)
6+
7+
# grumphp-bom-task
8+
9+
Force files to have no BOM via GrumPHP
10+
11+
### grumphp.yml:
12+
13+
````yml
14+
parameters:
15+
tasks:
16+
plus_bom_fixer:
17+
triggered_by: [php, css, scss, less, json, sql, yml, txt]
18+
extensions:
19+
- PLUS\GrumPHPBomTask\ExtensionLoader
20+
````
21+
22+
### Upgrade from andersundsehr/grumphp-bom-task
23+
24+
If you come from [andersundsehr/grumphp-bom-task](https://github.com/andersundsehr/grumphp-bom-task), change the extensions Loader path in the grumphp.yml file.
25+
26+
from:
27+
28+
````yml
29+
parameters:
30+
tasks:
31+
aus_bom_fixer:
32+
triggered_by: [php, css, scss, less, json, sql, yml, txt]
33+
extensions:
34+
- AUS\GrumPHPBomTask\ExtensionLoader
35+
````
36+
37+
to:
38+
39+
````yml
40+
parameters:
41+
tasks:
42+
plus_bom_fixer:
43+
triggered_by: [php, css, scss, less, json, sql, yml, txt]
44+
extensions:
45+
- PLUS\GrumPHPBomTask\ExtensionLoader
46+
````
47+
48+
### Composer
49+
50+
``composer require --dev pluswerk/grumphp-bom-task``
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
PLUS\GrumPHPBomTask\BomFixerTask:
3+
class: PLUS\GrumPHPBomTask\BomFixerTask
4+
arguments:
5+
- '@process_builder'
6+
- '@formatter.raw_process'
7+
tags:
8+
- {name: grumphp.task, task: plus_bom_fixer}

packages/grumphp-bom-task/bin/fixbom

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
$currentScriptName = array_shift($argv); // remove the name of the current script
5+
if (empty($argv)) {
6+
echo "use fixbom like this:" . PHP_EOL;
7+
echo $currentScriptName . " file1 [file2 ...]" . PHP_EOL;
8+
}
9+
foreach ($argv as $execFile) {
10+
if (!is_file($execFile)) {
11+
echo "\e[1;33mfile not found '" . $execFile . "'\e[0m" . PHP_EOL;
12+
continue;
13+
}
14+
$fileContent = file_get_contents($execFile);
15+
$bom = pack('H*', 'EFBBBF');
16+
$fileContentWithoutBom = preg_replace("/^$bom/", '', $fileContent);
17+
18+
if ($fileContentWithoutBom !== $fileContent) {
19+
$fileGroup = filegroup($execFile);
20+
$filePerm = fileperms($execFile) & 0777;
21+
unlink($execFile);
22+
file_put_contents($execFile, $fileContentWithoutBom);
23+
chgrp($execFile, $fileGroup);
24+
chmod($execFile, $filePerm);
25+
26+
echo "\033[0;32mBOM was removed from file '" . $execFile . "'\033[0m" . PHP_EOL;
27+
}
28+
}
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "pluswerk/grumphp-bom-task",
3+
"description": "Force files to have no BOM",
4+
"license": "LGPL-3.0-or-later",
5+
"type": "library",
6+
"authors": [
7+
{
8+
"name": "Matthias Vogel",
9+
"email": "m.vogel@andersundsehr.com",
10+
"homepage": "https://www.andersundsehr.com"
11+
}
12+
],
13+
"support": {
14+
"issues": "https://github.com/pluswerk/grumphp-bom-task/issues"
15+
},
16+
"require": {
17+
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
18+
"phpro/grumphp": "^2.0.0"
19+
},
20+
"require-dev": {
21+
"pluswerk/grumphp-config": "^6.8.0"
22+
},
23+
"autoload": {
24+
"psr-4": {
25+
"PLUS\\GrumPHPBomTask\\": "src/"
26+
}
27+
},
28+
"bin": [
29+
"bin/fixbom"
30+
],
31+
"config": {
32+
"allow-plugins": {
33+
"ergebnis/composer-normalize": true,
34+
"phpro/grumphp": true,
35+
"phpstan/extension-installer": true,
36+
"pluswerk/grumphp-config": true
37+
}
38+
},
39+
"extra": {
40+
"branch-alias": {
41+
"dev-main": "8.0.x-dev"
42+
}
43+
}
44+
}

packages/grumphp-bom-task/grumphp.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
imports:
2+
- { resource: vendor/pluswerk/grumphp-config/grumphp.yml }
3+
parameters:
4+
convention.process_timeout: 240
5+
convention.security_checker_blocking: true
6+
convention.jsonlint_ignore_pattern: { }
7+
convention.xmllint_ignore_pattern: { }
8+
convention.yamllint_ignore_pattern: { }
9+
convention.phpcslint_ignore_pattern: { }
10+
convention.phpcslint_exclude: { }
11+
convention.xlifflint_ignore_pattern: { }
12+
convention.rector_ignore_pattern: { }
13+
convention.rector_enabled: true
14+
convention.rector_config: rector.php
15+
convention.rector_clear-cache: false
16+
convention.phpstan_level: null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
parameters:
2+
ignoreErrors: []
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
includes:
2+
- phpstan-baseline.neon
3+
- vendor/andersundsehr/phpstan-git-files/extension.php
4+
5+
parameters:
6+
level: 8
7+
reportUnmatchedIgnoredErrors: false

packages/grumphp-bom-task/rector.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PLUS\GrumPHPConfig\RectorSettings;
6+
use Rector\Config\RectorConfig;
7+
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
8+
9+
return static function (RectorConfig $rectorConfig): void {
10+
$rectorConfig->parallel();
11+
$rectorConfig->importNames();
12+
$rectorConfig->importShortClasses();
13+
$rectorConfig->cacheClass(FileCacheStorage::class);
14+
$rectorConfig->cacheDirectory('./var/cache/rector');
15+
16+
$rectorConfig->paths(
17+
array_filter(explode("\n", (string)shell_exec("git ls-files | xargs ls -d 2>/dev/null | grep -E '\.(php|html|typoscript)$'")))
18+
);
19+
20+
// define sets of rules
21+
$rectorConfig->sets(
22+
[
23+
...RectorSettings::sets(true),
24+
...RectorSettings::setsTypo3(false),
25+
]
26+
);
27+
28+
// remove some rules
29+
// ignore some files
30+
$rectorConfig->skip(
31+
[
32+
...RectorSettings::skip(),
33+
...RectorSettings::skipTypo3(),
34+
35+
/**
36+
* rector should not touch these files
37+
*/
38+
//__DIR__ . '/src/Example',
39+
//__DIR__ . '/src/Example.php',
40+
]
41+
);
42+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PLUS\GrumPHPBomTask;
6+
7+
use Symfony\Component\Finder\SplFileInfo;
8+
use GrumPHP\Runner\TaskResult;
9+
use GrumPHP\Runner\TaskResultInterface;
10+
use GrumPHP\Task\Config\ConfigOptionsResolver;
11+
use GrumPHP\Task\Config\EmptyTaskConfig;
12+
use GrumPHP\Task\Config\TaskConfigInterface;
13+
use GrumPHP\Task\Context\ContextInterface;
14+
use GrumPHP\Task\Context\GitPreCommitContext;
15+
use GrumPHP\Task\Context\RunContext;
16+
use GrumPHP\Task\TaskInterface;
17+
use Symfony\Component\OptionsResolver\OptionsResolver;
18+
19+
final class BomFixerTask implements TaskInterface
20+
{
21+
private EmptyTaskConfig|TaskConfigInterface $config;
22+
23+
public function __construct()
24+
{
25+
$this->config = new EmptyTaskConfig();
26+
}
27+
28+
public static function getConfigurableOptions(): ConfigOptionsResolver
29+
{
30+
$resolver = new OptionsResolver();
31+
$resolver->setDefaults(
32+
[
33+
'triggered_by' => ['php', 'css', 'scss', 'less', 'json', 'sql', 'yml', 'txt'],
34+
]
35+
);
36+
37+
$resolver->addAllowedTypes('triggered_by', ['array']);
38+
return ConfigOptionsResolver::fromOptionsResolver($resolver);
39+
}
40+
41+
public function getConfig(): TaskConfigInterface
42+
{
43+
return $this->config;
44+
}
45+
46+
public function withConfig(TaskConfigInterface $config): TaskInterface
47+
{
48+
$new = clone $this;
49+
$new->config = $config;
50+
51+
return $new;
52+
}
53+
54+
public function canRunInContext(ContextInterface $context): bool
55+
{
56+
return $context instanceof RunContext || $context instanceof GitPreCommitContext;
57+
}
58+
59+
public function run(ContextInterface $context): TaskResultInterface
60+
{
61+
$files = $context->getFiles()->extensions($this->config->getOptions()['triggered_by']);
62+
if (0 === count($files)) {
63+
return TaskResult::createSkipped($this, $context);
64+
}
65+
66+
if (is_file('./vendor/bin/fixbom')) {
67+
$fixCommand = './vendor/bin/fixbom';
68+
} elseif (is_file('./bin/fixbom')) {
69+
$fixCommand = './bin/fixbom';
70+
} else {
71+
$fixCommand = 'fixbom';
72+
}
73+
74+
$shouldGetFixedLog = [];
75+
/** @var SplFileInfo $file */
76+
foreach ($files as $file) {
77+
$execFile = $file->getPathname();
78+
if ($this->isFileWithBOM($execFile)) {
79+
$shouldGetFixedLog[] = $execFile . ' has BOM and should be fixed';
80+
$fixCommand .= " '" . $execFile . "'";
81+
}
82+
}
83+
84+
if (count($shouldGetFixedLog) > 0) {
85+
$errorMessage = implode(PHP_EOL, $shouldGetFixedLog) . PHP_EOL
86+
. 'you can use this to fix them:' . PHP_EOL
87+
. $fixCommand;
88+
return TaskResult::createFailed($this, $context, $errorMessage);
89+
}
90+
91+
return TaskResult::createPassed($this, $context);
92+
}
93+
94+
private function isFileWithBOM(string $filename): bool
95+
{
96+
return $this->fileInfoSearch($filename, 'BOM');
97+
}
98+
99+
private function fileInfoSearch(string $filename, string $search): bool
100+
{
101+
$output = [];
102+
exec('file "' . $filename . '"', $output, $returnVar);
103+
if ($returnVar !== 0) {
104+
return false;
105+
}
106+
107+
if (empty($output[0])) {
108+
return false;
109+
}
110+
111+
return str_contains($output[0], $search);
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PLUS\GrumPHPBomTask;
6+
7+
use Iterator;
8+
use GrumPHP\Extension\ExtensionInterface;
9+
10+
final class ExtensionLoader implements ExtensionInterface
11+
{
12+
public function imports(): Iterator
13+
{
14+
yield __DIR__ . '/../Services.yaml';
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Data
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Data

0 commit comments

Comments
 (0)