diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml
new file mode 100644
index 0000000..4782236
--- /dev/null
+++ b/.github/workflows/code-analysis.yaml
@@ -0,0 +1,53 @@
+name: Code Analysis
+
+on:
+ pull_request: null
+ push:
+ branches:
+ - main
+
+jobs:
+ code_analysis:
+ strategy:
+ fail-fast: false
+ matrix:
+ actions:
+ -
+ name: 'PHPStan'
+ run: composer phpstan
+
+ -
+ name: 'Check Active Classes'
+ run: vendor/bin/class-leak check bin src tests --ansi --skip-path=Fixture --skip-path=Source
+
+ -
+ name: 'Unit tests'
+ run: vendor/bin/phpunit
+
+ -
+ name: "Finalize classes"
+ run: vendor/bin/swiss-knife finalize-classes bin src tests --dry-run --ansi
+
+ -
+ name: 'Composer dependency Analyser'
+ run: vendor/bin/composer-dependency-analyser
+
+ -
+ name: 'Validate Composer'
+ run: composer validate
+
+ name: ${{ matrix.actions.name }}
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ # see https://github.com/shivammathur/setup-php
+ - uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.2
+ coverage: none
+
+ - uses: "ramsey/composer-install@v2"
+
+ - run: ${{ matrix.actions.run }}
diff --git a/bin/handyman.php b/bin/handyman.php
index 04d7bc2..0d9d5cd 100644
--- a/bin/handyman.php
+++ b/bin/handyman.php
@@ -1,7 +1,6 @@
ignoreErrorsOnPackage('nikic/php-parser', [ErrorType::DEV_DEPENDENCY_IN_PROD]);
diff --git a/composer.json b/composer.json
index 41dac56..4fb9980 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,7 @@
{
"name": "tomasvotruba/handyman",
"type": "phpstan-extension",
+ "license": "MIT",
"description": "Automate repeated steps when coming to a PHP project or create new package",
"require": {
"php": "^8.2",
@@ -9,7 +10,8 @@
"symfony/process": "^7.1",
"symfony/finder": "^7.1",
"nette/utils": "^4.0",
- "phpstan/phpstan": "^1.12"
+ "phpstan/phpstan": "^1.12",
+ "webmozart/assert": "^1.11"
},
"require-dev": {
"rector/rector": "^1.2",
@@ -20,7 +22,7 @@
"symplify/easy-coding-standard": "^12.3",
"shipmonk/composer-dependency-analyser": "^1.7",
"tomasvotruba/type-coverage": "^1.0",
- "tomasvotruba/class-leak": "^1.0",
+ "tomasvotruba/class-leak": "^1.1",
"tomasvotruba/unused-public": "^1.0",
"tracy/tracy": "^2.10",
"nikic/php-parser": "^4.19"
diff --git a/phpunit.xml b/phpunit.xml
index 548a391..2e3d6c4 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -9,6 +9,7 @@
tests
+ tests/PHPStan/Rule/PublicStaticDataProviderRule/Fixture
diff --git a/src/Command/GithubCommand.php b/src/Command/GithubCommand.php
index 96b89b5..6797afd 100644
--- a/src/Command/GithubCommand.php
+++ b/src/Command/GithubCommand.php
@@ -4,12 +4,12 @@
namespace TomasVotruba\Handyman\Command;
-use Nette\Utils\FileSystem;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TomasVotruba\Handyman\FileSystem\TemplateFileSystem;
+use TomasVotruba\Handyman\ValueObject\ComposerJson;
final class GithubCommand extends Command
{
@@ -27,17 +27,22 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
- $codeAnalysisFilePath = getcwd() . '/.github/workflows/code-analysis.yaml';
- if (! file_exists($codeAnalysisFilePath)) {
- $fileContents = TemplateFileSystem::renderFilePathWithVariables(
- __DIR__ . '/../../templates/github-workflows/code-analysis.yaml',
- []
+ $projectFilePath = getcwd() . '/.github/workflows/code-analysis.yaml';
+
+ if (! file_exists($projectFilePath)) {
+ $projectComposerJson = new ComposerJson(getcwd() . '/composer.json');
+
+ TemplateFileSystem::renderFilePathWithVariables(
+ __DIR__ . '/../../templates/.github/workflows/code_analysis.yaml',
+ [
+ '__PHP_VERSION__' => $projectComposerJson->getPhpVersionString(),
+ ],
+ $projectFilePath
);
- FileSystem::write($codeAnalysisFilePath, $fileContents);
- $this->symfonyStyle->success('Created .github/workflows/code-analysis.yaml');
+ $this->symfonyStyle->success('Created .github/workflows/code_analysis.yaml');
} else {
- $this->symfonyStyle->success('Config .github/workflows/code-analysis.yaml already exists');
+ $this->symfonyStyle->success('Config .github/workflows/code_analysis.yaml already exists');
}
return self::SUCCESS;
diff --git a/src/FileSystem/TemplateFileSystem.php b/src/FileSystem/TemplateFileSystem.php
index 708124e..b79328d 100644
--- a/src/FileSystem/TemplateFileSystem.php
+++ b/src/FileSystem/TemplateFileSystem.php
@@ -5,15 +5,28 @@
namespace TomasVotruba\Handyman\FileSystem;
use Nette\Utils\FileSystem;
+use Webmozart\Assert\Assert;
final class TemplateFileSystem
{
/**
* @param array $variables
*/
- public static function renderFilePathWithVariables(string $sourceFilePath, array $variables): string
- {
- $fileContents = FileSystem::read($sourceFilePath);
- return str_replace(array_keys($variables), array_values($variables), $fileContents);
+ public static function renderFilePathWithVariables(
+ string $sourceFilePath,
+ array $variables,
+ ?string $targetFilePath = null
+ ): string {
+ Assert::fileExists($sourceFilePath);
+
+ $templateContents = FileSystem::read($sourceFilePath);
+ $fileContents = str_replace(array_keys($variables), array_values($variables), $templateContents);
+
+ // save file contents directly
+ if (is_string($targetFilePath)) {
+ FileSystem::write($targetFilePath, $fileContents);
+ }
+
+ return $fileContents;
}
}
diff --git a/src/ValueObject/ComposerJson.php b/src/ValueObject/ComposerJson.php
new file mode 100644
index 0000000..7ee7b12
--- /dev/null
+++ b/src/ValueObject/ComposerJson.php
@@ -0,0 +1,40 @@
+
+ */
+ private array $json = [];
+
+ public function __construct(string $composerJsonFilePath)
+ {
+ Assert::fileExists($composerJsonFilePath);
+ $this->composerJsonFilePath = $composerJsonFilePath;
+
+ $this->json = Json::decode(FileSystem::read($this->composerJsonFilePath), true);
+ }
+
+ public function getPhpVersionString(): string
+ {
+ $requirePhp = $this->json['require']['php'] ?? null;
+ Assert::string($requirePhp);
+
+ $match = Strings::match($requirePhp, '#(?\d\.\d)#');
+ Assert::isArray($match);
+ Assert::keyExists($match, 'version');
+
+ return $match['version'];
+ }
+}
diff --git a/stubs/Doctrine/ORM/EntityManager.php b/stubs/Doctrine/ORM/EntityManager.php
new file mode 100644
index 0000000..5c6b827
--- /dev/null
+++ b/stubs/Doctrine/ORM/EntityManager.php
@@ -0,0 +1,11 @@
+