├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── autowire-array-parameter_code_analysis.yml │ ├── bare_run.yaml │ ├── code_analysis.yaml │ ├── easy-testing_code_analysis.yml │ ├── package-builder_code_analysis.yml │ ├── smart-file-system_code_analysis.yml │ └── symplify-kernel_code_analysis.yml ├── LICENSE ├── bin ├── monorepo-builder └── monorepo-builder.php ├── build ├── rector-downgrade-php-72.php └── target-repository │ ├── .github │ ├── FUNDING.yml │ └── workflows │ │ ├── auto_closer.yaml │ │ └── bare_run.yaml │ ├── bootstrap.php │ └── composer.json ├── composer.json ├── config └── config.php ├── ecs.php ├── full-tool-build.sh ├── packages ├── ComposerJsonManipulator │ ├── ComposerJsonFactory.php │ ├── FileSystem │ │ └── JsonFileManager.php │ ├── Json │ │ ├── JsonCleaner.php │ │ └── JsonInliner.php │ ├── Printer │ │ └── ComposerJsonPrinter.php │ ├── Sorter │ │ └── ComposerPackageSorter.php │ └── ValueObject │ │ ├── ComposerJson.php │ │ ├── ComposerJsonSection.php │ │ └── Option.php ├── Init │ └── Command │ │ └── InitCommand.php ├── Merge │ ├── Application │ │ └── MergedAndDecoratedComposerJsonFactory.php │ ├── Arrays │ │ ├── ArraySorter.php │ │ └── SortedParameterMerger.php │ ├── Cleaner │ │ └── RequireRequireDevDuplicateCleaner.php │ ├── Command │ │ └── MergeCommand.php │ ├── ComposerJsonDecorator │ │ ├── AppenderComposerJsonDecorator.php │ │ ├── FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php │ │ ├── RemoverComposerJsonDecorator.php │ │ ├── ReplaceSectionJsonDecorator.php │ │ ├── RepositoryPathComposerJsonDecorator.php │ │ ├── RootRemoveComposerJsonDecorator.php │ │ └── SortComposerJsonDecorator.php │ ├── ComposerJsonMerger.php │ ├── ComposerKeyMerger │ │ ├── AuthorComposerKeyMerger.php │ │ ├── AutoloadComposerKeyMerger.php │ │ ├── AutoloadDevComposerKeyMerger.php │ │ ├── ExtraComposerKeyMerger.php │ │ ├── MinimalStabilityKeyMerger.php │ │ ├── PreferStableKeyMerger.php │ │ ├── ProvideComposerKeyMerger.php │ │ ├── ReplaceComposerKeyMerger.php │ │ ├── RepositoriesComposerKeyMerger.php │ │ ├── RequireComposerKeyMerger.php │ │ └── RequireDevComposerKeyMerger.php │ ├── Configuration │ │ ├── MergedPackagesCollector.php │ │ └── ModifyingComposerJsonProvider.php │ ├── Contract │ │ ├── ComposerJsonDecoratorInterface.php │ │ ├── ComposerKeyMergerInterface.php │ │ └── ComposerPathNormalizerInterface.php │ ├── Guard │ │ └── ConflictingVersionsGuard.php │ ├── JsonSchema.php │ └── PathResolver │ │ ├── AutoloadPathNormalizer.php │ │ └── ComposerPatchesPathNormalizer.php ├── Propagate │ ├── Command │ │ └── PropagateCommand.php │ └── VersionPropagator.php ├── Release │ ├── Command │ │ └── ReleaseCommand.php │ ├── Configuration │ │ ├── StageResolver.php │ │ └── VersionResolver.php │ ├── Contract │ │ └── ReleaseWorker │ │ │ ├── ReleaseWorkerInterface.php │ │ │ └── StageAwareInterface.php │ ├── Exception │ │ ├── ConfigurationException.php │ │ └── MissingComposerJsonException.php │ ├── Guard │ │ └── ReleaseGuard.php │ ├── Output │ │ └── ReleaseWorkerReporter.php │ ├── Process │ │ └── ProcessRunner.php │ ├── ReleaseWorker │ │ ├── AddTagToChangelogReleaseWorker.php │ │ ├── PushNextDevReleaseWorker.php │ │ ├── PushTagReleaseWorker.php │ │ ├── SetCurrentMutualDependenciesReleaseWorker.php │ │ ├── SetNextMutualDependenciesReleaseWorker.php │ │ ├── TagVersionReleaseWorker.php │ │ ├── UpdateBranchAliasReleaseWorker.php │ │ └── UpdateReplaceReleaseWorker.php │ ├── ReleaseWorkerProvider.php │ ├── ValueObject │ │ ├── SemVersion.php │ │ └── Stage.php │ └── Version │ │ └── VersionFactory.php ├── Resources │ └── schema.json └── Testing │ ├── Command │ └── LocalizeComposerPathsCommand.php │ ├── ComposerJson │ ├── ComposerJsonSymlinker.php │ └── ComposerVersionManipulator.php │ ├── ComposerJsonRepositoriesUpdater.php │ ├── ComposerJsonRequireUpdater.php │ ├── PackageDependency │ └── UsedPackagesResolver.php │ ├── PathResolver │ └── PackagePathResolver.php │ └── ValueObject │ └── Option.php ├── phpstan.neon ├── prefix-code.sh ├── rector.php ├── scoper.php ├── src-deps ├── autowire-array-parameter │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── code_analysis.yaml │ ├── LICENSE │ ├── composer.json │ ├── easy-ci.php │ ├── phpstan.neon │ └── src │ │ ├── DependencyInjection │ │ ├── CompilerPass │ │ │ └── AutowireArrayParameterCompilerPass.php │ │ └── DefinitionFinder.php │ │ ├── DocBlock │ │ └── ParamTypeDocBlockResolver.php │ │ ├── Exception │ │ └── DependencyInjection │ │ │ └── DefinitionForTypeNotFoundException.php │ │ ├── Skipper │ │ └── ParameterSkipper.php │ │ └── TypeResolver │ │ └── ParameterTypeResolver.php ├── composer-json-manipulator │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── auto_closer.yaml │ ├── LICENSE │ ├── composer.json │ ├── config │ │ └── config.php │ └── src │ │ ├── ComposerJsonFactory.php │ │ ├── FileSystem │ │ └── JsonFileManager.php │ │ ├── Json │ │ ├── JsonCleaner.php │ │ └── JsonInliner.php │ │ ├── Printer │ │ └── ComposerJsonPrinter.php │ │ ├── Sorter │ │ └── ComposerPackageSorter.php │ │ └── ValueObject │ │ ├── ComposerJson.php │ │ ├── ComposerJsonManipulatorConfig.php │ │ ├── ComposerJsonSection.php │ │ └── Option.php ├── easy-testing │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── code_analysis.yaml │ ├── LICENSE │ ├── bin │ │ ├── easy-testing │ │ └── easy-testing.php │ ├── composer.json │ ├── config │ │ └── config.php │ └── src │ │ ├── Command │ │ └── ValidateFixtureSkipNamingCommand.php │ │ ├── DataProvider │ │ ├── StaticFixtureFinder.php │ │ └── StaticFixtureUpdater.php │ │ ├── Finder │ │ └── FixtureFinder.php │ │ ├── FixtureSplitter │ │ └── TrioFixtureSplitter.php │ │ ├── Kernel │ │ └── EasyTestingKernel.php │ │ ├── MissplacedSkipPrefixResolver.php │ │ ├── PHPUnit │ │ ├── Behavior │ │ │ └── DirectoryAssertableTrait.php │ │ └── StaticPHPUnitEnvironment.php │ │ ├── StaticFixtureSplitter.php │ │ └── ValueObject │ │ ├── EasyTestingConfig.php │ │ ├── ExpectedAndOutputFileInfoPair.php │ │ ├── FixtureSplit │ │ └── TrioContent.php │ │ ├── IncorrectAndMissingSkips.php │ │ ├── InputAndExpected.php │ │ ├── InputFileInfoAndExpected.php │ │ ├── InputFileInfoAndExpectedFileInfo.php │ │ ├── Option.php │ │ ├── Prefix.php │ │ └── SplitLine.php ├── package-builder │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── code_analysis.yaml │ ├── composer.json │ ├── config │ │ └── config.php │ ├── phpstan-baseline.neon │ └── src │ │ ├── Composer │ │ └── VendorDirProvider.php │ │ ├── Console │ │ ├── Command │ │ │ └── AbstractSymplifyCommand.php │ │ ├── Formatter │ │ │ └── ColorConsoleDiffFormatter.php │ │ ├── Input │ │ │ └── StaticInputDetector.php │ │ ├── Output │ │ │ └── ConsoleDiffer.php │ │ └── Style │ │ │ └── SymfonyStyleFactory.php │ │ ├── DependencyInjection │ │ ├── CompilerPass │ │ │ └── AutowireInterfacesCompilerPass.php │ │ └── FileLoader │ │ │ └── ParameterMergingPhpFileLoader.php │ │ ├── Diff │ │ ├── DifferFactory.php │ │ └── Output │ │ │ └── CompleteUnifiedDiffOutputBuilderFactory.php │ │ ├── Exception │ │ ├── HttpKernel │ │ │ └── MissingInterfaceException.php │ │ ├── InvalidPrivatePropertyTypeException.php │ │ ├── MissingPrivatePropertyException.php │ │ └── MissingServiceException.php │ │ ├── Parameter │ │ └── ParameterProvider.php │ │ ├── Php │ │ └── TypeChecker.php │ │ ├── Reflection │ │ ├── ClassLikeExistenceChecker.php │ │ ├── PrivatesAccessor.php │ │ └── PrivatesCaller.php │ │ ├── Strings │ │ ├── StringFormatConverter.php │ │ └── StringFormatConverter.phpqIy1Ap │ │ ├── Testing │ │ └── AbstractKernelTestCase.php │ │ ├── ValueObject │ │ ├── ConsoleColorDiffConfig.php │ │ ├── MethodName.php │ │ └── Option.php │ │ └── Yaml │ │ └── ParametersMerger.php ├── smart-file-system │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── code_analysis.yaml │ ├── LICENSE │ ├── composer.json │ └── src │ │ ├── Exception │ │ ├── DirectoryNotFoundException.php │ │ └── FileNotFoundException.php │ │ ├── FileSystemFilter.php │ │ ├── FileSystemGuard.php │ │ ├── Finder │ │ ├── FinderSanitizer.php │ │ └── SmartFinder.php │ │ ├── Json │ │ └── JsonFileSystem.php │ │ ├── Normalizer │ │ └── PathNormalizer.php │ │ ├── SmartFileInfo.php │ │ └── SmartFileSystem.php └── symplify-kernel │ ├── .github │ ├── FUNDING.yaml │ └── workflows │ │ └── code_analysis.yaml │ ├── LICENSE │ ├── composer.json │ ├── config │ └── common-config.php │ ├── easy-ci.php │ ├── phpstan.neon │ └── src │ ├── Config │ └── Loader │ │ └── ParameterMergingLoaderFactory.php │ ├── ContainerBuilderFactory.php │ ├── Contract │ ├── Config │ │ └── LoaderFactoryInterface.php │ └── LightKernelInterface.php │ ├── DependencyInjection │ └── LoadExtensionConfigsCompilerPass.php │ ├── Exception │ ├── BootException.php │ └── ShouldNotHappenException.php │ ├── HttpKernel │ └── AbstractSymplifyKernel.php │ └── ValueObject │ ├── KernelBootAndApplicationRun.php │ └── SymplifyKernelConfig.php ├── src ├── Command │ ├── BumpInterdependencyCommand.php │ ├── PackageAliasCommand.php │ └── ValidateCommand.php ├── Config │ └── MBConfig.php ├── Console │ └── MonorepoBuilderApplication.php ├── Contract │ └── Git │ │ └── TagResolverInterface.php ├── DependencyUpdater.php ├── DevMasterAliasUpdater.php ├── Exception │ ├── ConfigurationException.php │ ├── Git │ │ └── InvalidGitVersionException.php │ ├── MissingComposerJsonException.php │ └── Validator │ │ └── InvalidComposerJsonSetupException.php ├── FileSystem │ └── ComposerJsonProvider.php ├── Finder │ └── PackageComposerFinder.php ├── Git │ ├── ExpectedAliasResolver.php │ └── MostRecentTagResolver.php ├── Kernel │ └── MonorepoBuilderKernel.php ├── Package │ └── PackageNamesProvider.php ├── Utils │ ├── RelativeFilePathHelper.php │ └── VersionUtils.php ├── Validator │ ├── ConflictingPackageVersionsReporter.php │ └── SourcesPresenceValidator.php ├── ValueObject │ ├── File.php │ └── Option.php └── VersionValidator.php └── templates └── monorepo ├── composer.json ├── monorepo-builder.php └── packages ├── first-package ├── composer.json └── src │ └── FirstClass.php └── second-package ├── composer.json └── src └── SecondClass.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | indent_style = space 9 | indent_size = 4 10 | 11 | [*.{yml,yaml}] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | github: tomasvotruba 3 | custom: https://www.paypal.me/rectorphp 4 | -------------------------------------------------------------------------------- /.github/workflows/autowire-array-parameter_code_analysis.yml: -------------------------------------------------------------------------------- 1 | name: autowire-array-parameter Code Analysis 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | code_analysis: 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | actions: 12 | - 13 | name: 'PHPStan' 14 | run: cd src-deps/autowire-array-parameter && composer phpstan --ansi 15 | 16 | - 17 | name: 'Composer Validate' 18 | run: cd src-deps/autowire-array-parameter && composer validate --ansi 19 | 20 | - 21 | name: 'Tests' 22 | run: cd src-deps/autowire-array-parameter && vendor/bin/phpunit 23 | 24 | - 25 | name: 'PHP Linter' 26 | run: cd src-deps/autowire-array-parameter && vendor/bin/parallel-lint src tests 27 | 28 | - 29 | name: 'Check Commented Code' 30 | run: cd src-deps/autowire-array-parameter && vendor/bin/easy-ci check-commented-code src tests --ansi 31 | 32 | - 33 | name: 'Check Active Classes' 34 | run: > 35 | cd src-deps/autowire-array-parameter 36 | && vendor/bin/class-leak check src --skip-type="Symplify\\AutowireArrayParameter\\DependencyInjection\\CompilerPass\\AutowireArrayParameterCompilerPass" 37 | 38 | name: ${{ matrix.actions.name }} 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v3 43 | # see https://github.com/shivammathur/setup-php 44 | - uses: shivammathur/setup-php@v2 45 | with: 46 | php-version: 8.2 47 | coverage: none 48 | 49 | # composer install cache - https://github.com/ramsey/composer-install 50 | - uses: "ramsey/composer-install@v2" 51 | with: 52 | working-directory: "src-deps/autowire-array-parameter" 53 | 54 | - run: ${{ matrix.actions.run }} 55 | -------------------------------------------------------------------------------- /.github/workflows/bare_run.yaml: -------------------------------------------------------------------------------- 1 | name: Bare Run on various PHP versions 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | bare_run: 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | php_version: ['7.2', '7.3', '7.4', '8.0'] 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - 21 | id: check_tag 22 | run: | 23 | MESSAGE=$(git tag -l --format='%(contents)' $(git describe --tags $(git rev-list --tags --max-count=1))) 24 | if echo $MESSAGE | grep -q "PHP 7.2 downgraded"; then 25 | echo "NEEDED_DOWNGRADE=1" >> $GITHUB_ENV 26 | else 27 | echo "NEEDED_DOWNGRADE=0" >> $GITHUB_ENV 28 | fi 29 | 30 | - 31 | name: Setup PHP And Run Monorepo 32 | if: env.NEEDED_DOWNGRADE == '1' 33 | uses: shivammathur/setup-php@v2 34 | with: 35 | php-version: ${{ matrix.php_version }} 36 | coverage: none 37 | - 38 | if: env.NEEDED_DOWNGRADE == '1' 39 | run: php bin/monorepo-builder list --ansi -------------------------------------------------------------------------------- /.github/workflows/easy-testing_code_analysis.yml: -------------------------------------------------------------------------------- 1 | name: easy-testing Code Analysis 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | code_analysis: 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | actions: 12 | - 13 | name: 'PHPStan' 14 | run: cd src-deps/easy-testing && composer phpstan --ansi 15 | 16 | - 17 | name: 'Composer Validate' 18 | run: cd src-deps/easy-testing && composer validate --ansi 19 | 20 | - 21 | name: 'Tests' 22 | run: cd src-deps/easy-testing && vendor/bin/phpunit 23 | 24 | - 25 | name: 'PHP Linter' 26 | run: cd src-deps/easy-testing && vendor/bin/parallel-lint src tests 27 | 28 | - 29 | name: 'Check Commented Code' 30 | run: cd src-deps/easy-testing && vendor/bin/easy-ci check-commented-code src tests --ansi 31 | 32 | - 33 | name: 'Check Active Classes' 34 | run: > 35 | cd src-deps/easy-testing 36 | && vendor/bin/class-leak check src 37 | --skip-type="Symplify\\AutowireArrayParameter\\DependencyInjection\\CompilerPass\\AutowireArrayParameterCompilerPass" 38 | --skip-type="Symplify\\EasyTesting\\Kernel\\EasyTestingKernel" 39 | 40 | name: ${{ matrix.actions.name }} 41 | runs-on: ubuntu-latest 42 | 43 | steps: 44 | - uses: actions/checkout@v3 45 | # see https://github.com/shivammathur/setup-php 46 | - uses: shivammathur/setup-php@v2 47 | with: 48 | php-version: 8.2 49 | coverage: none 50 | 51 | # composer install cache - https://github.com/ramsey/composer-install 52 | - uses: "ramsey/composer-install@v2" 53 | with: 54 | working-directory: "src-deps/easy-testing" 55 | 56 | - run: ${{ matrix.actions.run }} 57 | -------------------------------------------------------------------------------- /.github/workflows/package-builder_code_analysis.yml: -------------------------------------------------------------------------------- 1 | name: package-builder Code Analysis 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | code_analysis: 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | actions: 12 | - 13 | name: 'PHPStan' 14 | run: cd src-deps/package-builder && composer phpstan --ansi 15 | 16 | - 17 | name: 'Composer Validate' 18 | run: cd src-deps/package-builder && composer validate --ansi 19 | 20 | - 21 | name: 'Tests' 22 | run: cd src-deps/package-builder && vendor/bin/phpunit 23 | 24 | - 25 | name: 'PHP Linter' 26 | run: cd src-deps/package-builder && vendor/bin/parallel-lint src tests 27 | 28 | - 29 | name: 'Check Commented Code' 30 | run: cd src-deps/package-builder && vendor/bin/easy-ci check-commented-code src tests --ansi 31 | 32 | - 33 | name: 'Check Active Classes' 34 | run: > 35 | cd src-deps/package-builder 36 | && vendor/bin/class-leak check src 37 | --skip-type="Symplify\\PackageBuilder\\DependencyInjection\\CompilerPass\\AutowireInterfacesCompilerPass" 38 | --skip-type="Symplify\\PackageBuilder\\Diff\\DifferFactory" 39 | 40 | name: ${{ matrix.actions.name }} 41 | runs-on: ubuntu-latest 42 | 43 | steps: 44 | - uses: actions/checkout@v3 45 | # see https://github.com/shivammathur/setup-php 46 | - uses: shivammathur/setup-php@v2 47 | with: 48 | php-version: 8.2 49 | coverage: none 50 | 51 | # composer install cache - https://github.com/ramsey/composer-install 52 | - uses: "ramsey/composer-install@v2" 53 | with: 54 | working-directory: "src-deps/package-builder" 55 | 56 | - run: ${{ matrix.actions.run }} 57 | -------------------------------------------------------------------------------- /.github/workflows/smart-file-system_code_analysis.yml: -------------------------------------------------------------------------------- 1 | name: smart-file-system Code Analysis 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | code_analysis: 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | actions: 12 | - 13 | name: 'PHPStan' 14 | run: cd src-deps/smart-file-system && composer phpstan --ansi 15 | 16 | - 17 | name: 'Composer Validate' 18 | run: cd src-deps/smart-file-system && composer validate --ansi 19 | 20 | - 21 | name: 'Tests' 22 | run: cd src-deps/smart-file-system && vendor/bin/phpunit 23 | 24 | - 25 | name: 'PHP Linter' 26 | run: cd src-deps/smart-file-system && vendor/bin/parallel-lint src tests 27 | 28 | - 29 | name: 'Check Commented Code' 30 | run: cd src-deps/smart-file-system && vendor/bin/easy-ci check-commented-code src tests --ansi 31 | 32 | - 33 | name: 'Check Active Classes' 34 | run: > 35 | cd src-deps/smart-file-system 36 | && vendor/bin/class-leak check src --skip-type="Symplify\\PackageBuilder\\DependencyInjection\\CompilerPass\\AutowireInterfacesCompilerPass" 37 | 38 | name: ${{ matrix.actions.name }} 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v3 43 | # see https://github.com/shivammathur/setup-php 44 | - uses: shivammathur/setup-php@v2 45 | with: 46 | php-version: 8.2 47 | coverage: none 48 | 49 | # composer install cache - https://github.com/ramsey/composer-install 50 | - uses: "ramsey/composer-install@v2" 51 | with: 52 | working-directory: "src-deps/smart-file-system" 53 | 54 | - run: ${{ matrix.actions.run }} 55 | -------------------------------------------------------------------------------- /.github/workflows/symplify-kernel_code_analysis.yml: -------------------------------------------------------------------------------- 1 | name: symplify-kernel Code Analysis 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | code_analysis: 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | actions: 12 | - 13 | name: 'PHPStan' 14 | run: cd src-deps/symplify-kernel && composer phpstan --ansi 15 | 16 | - 17 | name: 'Composer Validate' 18 | run: cd src-deps/symplify-kernel && composer validate --ansi 19 | 20 | - 21 | name: 'Tests' 22 | run: cd src-deps/symplify-kernel && vendor/bin/phpunit 23 | 24 | - 25 | name: 'PHP Linter' 26 | run: cd src-deps/symplify-kernel && vendor/bin/parallel-lint src tests 27 | 28 | - 29 | name: 'Check Commented Code' 30 | run: cd src-deps/symplify-kernel && vendor/bin/easy-ci check-commented-code src tests --ansi 31 | 32 | - 33 | name: 'Check Active Classes' 34 | run: cd src-deps/symplify-kernel && vendor/bin/class-leak check src 35 | 36 | name: ${{ matrix.actions.name }} 37 | runs-on: ubuntu-latest 38 | 39 | steps: 40 | - uses: actions/checkout@v3 41 | # see https://github.com/shivammathur/setup-php 42 | - uses: shivammathur/setup-php@v2 43 | with: 44 | php-version: 8.2 45 | coverage: none 46 | 47 | # composer install cache - https://github.com/ramsey/composer-install 48 | - uses: "ramsey/composer-install@v2" 49 | with: 50 | working-directory: "src-deps/symplify-kernel" 51 | 52 | - run: ${{ matrix.actions.run }} 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | --------------- 3 | 4 | Copyright (c) 2016 Tomas Votruba (https://tomasvotruba.com) 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /bin/monorepo-builder: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 47 | 48 | 49 | 50 | function resolveConfigFile(ArgvInput $argvInput): ?string 51 | { 52 | if ($argvInput->hasParameterOption(['-c', '--config'])) { 53 | $configOption = $argvInput->getParameterOption(['-c', '--config']); 54 | if (is_string($configOption) && file_exists($configOption)) { 55 | return realpath($configOption); 56 | } 57 | } 58 | 59 | $defaultConfigFilePath = getcwd() . '/' . File::CONFIG; 60 | if (file_exists($defaultConfigFilePath)) { 61 | return $defaultConfigFilePath; 62 | } 63 | 64 | return null; 65 | } 66 | -------------------------------------------------------------------------------- /build/rector-downgrade-php-72.php: -------------------------------------------------------------------------------- 1 | parallel(240, 8, 1); 10 | 11 | $rectorConfig->sets([DowngradeLevelSetList::DOWN_TO_PHP_72]); 12 | 13 | $rectorConfig->skip([ 14 | '*/Tests/*', 15 | '*/tests/*', 16 | __DIR__ . '/../../tests', 17 | # missing "optional" dependency and never used here 18 | '*/symfony/framework-bundle/KernelBrowser.php', 19 | '*/symfony/http-kernel/HttpKernelBrowser.php', 20 | ]); 21 | }; -------------------------------------------------------------------------------- /build/target-repository/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | github: tomasvotruba 3 | custom: https://www.paypal.me/rectorphp 4 | -------------------------------------------------------------------------------- /build/target-repository/.github/workflows/auto_closer.yaml: -------------------------------------------------------------------------------- 1 | name: Auto Closer PR 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | 7 | jobs: 8 | run: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: superbrothers/close-pull-request@v3 12 | with: 13 | # Optional. Post a issue comment just before closing a pull request. 14 | comment: | 15 | Hi, thank you for your contribution. 16 | 17 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository. 18 | 19 | We'd like to kindly ask you to move the contribution there - https://github.com/symplify/symplify. 20 | 21 | We'll check it, review it and give you feed back right way. 22 | 23 | Thank you. 24 | -------------------------------------------------------------------------------- /build/target-repository/.github/workflows/bare_run.yaml: -------------------------------------------------------------------------------- 1 | name: Bare Run 2 | 3 | on: [pull_request, push] 4 | 5 | jobs: 6 | bare_run: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | php_version: ['7.2', '7.3', '7.4', '8.0'] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - 18 | uses: shivammathur/setup-php@v2 19 | with: 20 | php-version: ${{ matrix.php_version }} 21 | coverage: none 22 | 23 | - run: php bin/monorepo-builder list --ansi 24 | -------------------------------------------------------------------------------- /build/target-repository/bootstrap.php: -------------------------------------------------------------------------------- 1 | loadClass($class); 24 | } 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /build/target-repository/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symplify/monorepo-builder", 3 | "description": "Prefixed version of Not only Composer tools to build a Monorepo.", 4 | "license": "MIT", 5 | "require": { 6 | "php": ">=7.2" 7 | }, 8 | "bin": [ 9 | "bin/monorepo-builder" 10 | ], 11 | "extra": { 12 | "branch-alias": { 13 | "dev-main": "10.3-dev" 14 | } 15 | }, 16 | "autoload": { 17 | "files": [ 18 | "bootstrap.php" 19 | ] 20 | }, 21 | "config": { 22 | "allow-plugins": { 23 | "cweagans/composer-patches": true, 24 | "phpstan/extension-installer": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ecs.php: -------------------------------------------------------------------------------- 1 | paths([ 10 | __DIR__ . '/ecs.php', 11 | __DIR__ . '/rector.php', 12 | __DIR__ . '/config', 13 | __DIR__ . '/src', 14 | __DIR__ . '/tests', 15 | __DIR__ . '/src-deps', 16 | ]); 17 | 18 | $ecsConfig->sets([ 19 | SetList::COMMON, 20 | SetList::PSR_12, 21 | ]); 22 | }; 23 | -------------------------------------------------------------------------------- /full-tool-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # add patches 4 | composer install --ansi 5 | 6 | # but skip dev dependencies 7 | composer update --no-dev --ansi 8 | 9 | # remove tests and useless files, to make downgraded, scoped and deployed codebase as small as possible 10 | rm -rf tests 11 | 12 | # downgrade with rector 13 | mkdir rector-local 14 | composer require rector/rector ^0.17 --working-dir rector-local 15 | rector-local/vendor/bin/rector process bin src packages vendor --config build/rector-downgrade-php-72.php --ansi 16 | 17 | # prefix 18 | sh prefix-code.sh 19 | -------------------------------------------------------------------------------- /packages/ComposerJsonManipulator/Json/JsonCleaner.php: -------------------------------------------------------------------------------- 1 | $data 11 | * @return array 12 | */ 13 | public function removeEmptyKeysFromJsonArray(array $data): array 14 | { 15 | foreach ($data as $key => $value) { 16 | if (! is_array($value)) { 17 | continue; 18 | } 19 | 20 | if ($value === []) { 21 | unset($data[$key]); 22 | } else { 23 | $data[$key] = $this->removeEmptyKeysFromJsonArray($value); 24 | } 25 | } 26 | 27 | return $data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/ComposerJsonManipulator/Json/JsonInliner.php: -------------------------------------------------------------------------------- 1 | parameterProvider->hasParameter(Option::INLINE_SECTIONS)) { 27 | return $jsonContent; 28 | } 29 | 30 | $inlineSections = $this->parameterProvider->provideArrayParameter(Option::INLINE_SECTIONS); 31 | 32 | foreach ($inlineSections as $inlineSection) { 33 | $pattern = '#("' . preg_quote((string) $inlineSection, '#') . '": )\[(.*?)\](,)#ms'; 34 | 35 | $jsonContent = Strings::replace($jsonContent, $pattern, static function (array $match): string { 36 | $inlined = Strings::replace($match[2], self::SPACE_REGEX, ' '); 37 | $inlined = trim($inlined); 38 | $inlined = '[' . $inlined . ']'; 39 | return $match[1] . $inlined . $match[3]; 40 | }); 41 | } 42 | 43 | return $jsonContent; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php: -------------------------------------------------------------------------------- 1 | jsonFileManager->encodeJsonToFileContent($composerJson->getJsonArray()); 24 | } 25 | 26 | public function print(ComposerJson $composerJson, string | SmartFileInfo $targetFile): void 27 | { 28 | if (is_string($targetFile)) { 29 | $this->jsonFileManager->printComposerJsonToFilePath($composerJson, $targetFile); 30 | return; 31 | } 32 | 33 | $this->jsonFileManager->printJsonToFileInfo($composerJson->getJsonArray(), $targetFile); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/ComposerJsonManipulator/ValueObject/Option.php: -------------------------------------------------------------------------------- 1 | setName('init'); 22 | $this->setDescription('Creates empty monorepo directory and composer.json structure.'); 23 | $this->addArgument(self::OUTPUT, InputArgument::OPTIONAL, 'Directory to generate monorepo into.', getcwd()); 24 | } 25 | 26 | protected function execute(InputInterface $input, OutputInterface $output): int 27 | { 28 | /** @var string $output */ 29 | $output = $input->getArgument(self::OUTPUT); 30 | 31 | $this->smartFileSystem->mirror(__DIR__ . '/../../../templates/monorepo', $output); 32 | 33 | $this->symfonyStyle->success('Congrats! Your first monorepo is here.'); 34 | $message = sprintf( 35 | 'Try the next step - merge "composer.json" files from packages to the root one:%s "vendor/bin/monorepo-builder merge"', 36 | PHP_EOL 37 | ); 38 | $this->symfonyStyle->note($message); 39 | 40 | return self::SUCCESS; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php: -------------------------------------------------------------------------------- 1 | mergePackageFileInfosAndDecorate($mainComposerJson,$packageFileInfos); 31 | 32 | $this->composerJsonMerger->mergeJsonToRoot($mainComposerJson, $mergedAndDecoratedComposerJson); 33 | } 34 | 35 | /** 36 | * @param SmartFileInfo[] $packageFileInfos 37 | */ 38 | private function mergePackageFileInfosAndDecorate(ComposerJson $mainComposerJson,array $packageFileInfos): ComposerJson 39 | { 40 | $mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($mainComposerJson,$packageFileInfos); 41 | foreach ($this->composerJsonDecorators as $composerJsonDecorator) { 42 | $composerJsonDecorator->decorate($mergedComposerJson); 43 | } 44 | 45 | return $mergedComposerJson; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/Merge/Arrays/ArraySorter.php: -------------------------------------------------------------------------------- 1 | isSequential($array)) { 22 | sort($array); 23 | } else { 24 | ksort($array); 25 | } 26 | 27 | foreach ($array as $key => $value) { 28 | if (is_array($value)) { 29 | $array[$key] = $this->recursiveSort($value); 30 | } 31 | } 32 | 33 | return $array; 34 | } 35 | 36 | /** 37 | * @param mixed[] $orderedProperty 38 | * @param mixed[] $array 39 | * @return mixed[] 40 | */ 41 | public function recursiveSortBySchema(array $orderedProperty,array $array): array 42 | { 43 | 44 | if ($array === []) { 45 | return $array; 46 | } 47 | 48 | if ($this->isSequential($array)) { 49 | sort($array); 50 | } else { 51 | uksort($array,static function (string $key1, string $key2) use ($orderedProperty) : int { 52 | if (!in_array($key1,$orderedProperty,true)){ 53 | return PHP_INT_MAX; 54 | } 55 | 56 | return array_search($key1,$orderedProperty,true) <=> array_search($key2,$orderedProperty,true); 57 | }); 58 | } 59 | 60 | foreach ($array as $key => $value) { 61 | if (is_array($value)) { 62 | $array[$key] = $this->recursiveSort($value); 63 | } 64 | } 65 | 66 | return $array; 67 | } 68 | 69 | /** 70 | * @param mixed[] $array 71 | */ 72 | private function isSequential(array $array): bool 73 | { 74 | $zeroToItemCount = range(0, count($array) - 1); 75 | return array_keys($array) === $zeroToItemCount; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/Merge/Arrays/SortedParameterMerger.php: -------------------------------------------------------------------------------- 1 | parametersMerger->mergeWithCombine($firstArray, $secondArray); 26 | return $this->recursiveSortBySchema($composerPropertyName,$mergedArray); 27 | } 28 | 29 | /** 30 | * @param mixed[] $mergedArray 31 | * @return mixed[] 32 | */ 33 | private function recursiveSortBySchema(string $composerPropertyName,array $mergedArray): array 34 | { 35 | $propertyDefinitions = JsonSchema::getPropertyDefinitions($composerPropertyName); 36 | 37 | if ($propertyDefinitions === []){ 38 | return $this->arraySorter->recursiveSort($mergedArray); 39 | } 40 | 41 | return $this->arraySorter->recursiveSortBySchema($propertyDefinitions,$mergedArray); 42 | } 43 | 44 | /** 45 | * @param mixed[] $firstArray 46 | * @param mixed[] $secondArray 47 | * @return mixed[] 48 | */ 49 | public function mergeAndSort(string $composerPropertyName, array $firstArray, array $secondArray): array 50 | { 51 | $mergedArray = $this->parametersMerger->merge($firstArray, $secondArray); 52 | 53 | return $this->recursiveSortBySchema($composerPropertyName,$mergedArray); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php: -------------------------------------------------------------------------------- 1 | $requireDev 13 | * @return array 14 | */ 15 | public function unsetPackageFromRequire(ComposerJson $mainComposerJson, array $requireDev): array 16 | { 17 | // give require priority 18 | $requirePackageNames = $mainComposerJson->getRequirePackageNames(); 19 | foreach ($requirePackageNames as $requirePackageName) { 20 | if (! isset($requireDev[$requirePackageName])) { 21 | continue; 22 | } 23 | 24 | unset($requireDev[$requirePackageName]); 25 | } 26 | 27 | return $requireDev; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php: -------------------------------------------------------------------------------- 1 | modifyingComposerJsonProvider->getAppendingComposerJson(); 23 | if (! $appendingComposerJson instanceof ComposerJson) { 24 | return; 25 | } 26 | 27 | $this->composerJsonMerger->mergeJsonToRoot($composerJson, $appendingComposerJson); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php: -------------------------------------------------------------------------------- 1 | getRequire() === []) { 15 | return; 16 | } 17 | 18 | if ($composerJson->getRequireDev() === []) { 19 | return; 20 | } 21 | 22 | $duplicatedPackages = $composerJson->getDuplicatedRequirePackages(); 23 | 24 | $currentRequireDev = $composerJson->getRequireDev(); 25 | $packages = array_keys($currentRequireDev); 26 | 27 | foreach ($packages as $package) { 28 | if (in_array($package, $duplicatedPackages, true)) { 29 | unset($currentRequireDev[$package]); 30 | } 31 | } 32 | 33 | $composerJson->setRequireDev($currentRequireDev); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php: -------------------------------------------------------------------------------- 1 | mergedPackagesCollector->getPackages(); 21 | 22 | foreach ($mergedPackages as $mergedPackage) { 23 | // prevent value override 24 | if ($composerJson->isReplacePackageSet($mergedPackage)) { 25 | continue; 26 | } 27 | 28 | $composerJson->setReplacePackage($mergedPackage, 'self.version'); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php: -------------------------------------------------------------------------------- 1 | processReplaceRepositoriesRelativePath($composerJson); 20 | $this->processRemoveDuplicates($composerJson); 21 | } 22 | 23 | private function processReplaceRepositoriesRelativePath(ComposerJson $composerJson): void 24 | { 25 | $repositories = $composerJson->getRepositories(); 26 | 27 | foreach ($repositories as $index => $repository) { 28 | if (($repository['type'] ?? '') !== 'path') { 29 | continue; 30 | } 31 | 32 | $repositories[$index]['url'] = str_replace(self::UP_DIRECTORY, '', (string) $repository['url']); 33 | } 34 | 35 | $composerJson->setRepositories($repositories); 36 | } 37 | 38 | private function processRemoveDuplicates(ComposerJson $composerJson): void 39 | { 40 | $repositories = $composerJson->getRepositories(); 41 | $paths = []; 42 | 43 | foreach ($repositories as $index => $repository) { 44 | if (($repository['type'] ?? '') !== 'path') { 45 | continue; 46 | } 47 | 48 | if (in_array((string) $repository['url'], $paths, true)) { 49 | unset($repositories[$index]); 50 | } 51 | 52 | $paths[] = $repository['url']; 53 | } 54 | 55 | $composerJson->setRepositories($repositories); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php: -------------------------------------------------------------------------------- 1 | filterOutMergedPackages($composerJson->getRequire()); 25 | $composerJson->setRequire($require); 26 | 27 | $requireDev = $this->filterOutMergedPackages($composerJson->getRequireDev()); 28 | $composerJson->setRequireDev($requireDev); 29 | } 30 | 31 | /** 32 | * @param mixed[] $require 33 | * @return mixed[] 34 | */ 35 | private function filterOutMergedPackages(array $require): array 36 | { 37 | $packageNames = array_keys($require); 38 | foreach ($packageNames as $packageName) { 39 | if (! in_array($packageName, $this->mergedPackagesCollector->getPackages(), true)) { 40 | continue; 41 | } 42 | 43 | unset($require[$packageName]); 44 | } 45 | 46 | return $require; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php: -------------------------------------------------------------------------------- 1 | sectionOrder = $parameterProvider->provideArrayParameter(Option::SECTION_ORDER); 25 | } 26 | 27 | public function decorate(ComposerJson $composerJson): void 28 | { 29 | $orderedKeys = $composerJson->getJsonKeys(); 30 | 31 | usort( 32 | $orderedKeys, 33 | fn (string $key1, string $key2): int => $this->findKeyPosition($key1) <=> $this->findKeyPosition($key2) 34 | ); 35 | 36 | $composerJson->setOrderedKeys($orderedKeys); 37 | } 38 | 39 | private function findKeyPosition(string $key): int | string | bool 40 | { 41 | return array_search($key, $this->sectionOrder, true); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getAuthors() === []) { 15 | return; 16 | } 17 | 18 | $mainAuthors = array_column($mainComposerJson->getAuthors(), null, 'name'); 19 | $newAuthors = array_column($newComposerJson->getAuthors(), null, 'name'); 20 | 21 | $authors = array_merge($mainAuthors, $newAuthors); 22 | $authors = array_values($authors); 23 | 24 | $mainComposerJson->setAuthors($authors); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getAutoload() === []) { 22 | return; 23 | } 24 | 25 | $autoload = $this->sortedParameterMerger->mergeAndSort(ComposerJsonSection::AUTOLOAD, 26 | $mainComposerJson->getAutoload(), 27 | $newComposerJson->getAutoload() 28 | ); 29 | $mainComposerJson->setAutoload($autoload); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getAutoloadDev() === []) { 22 | return; 23 | } 24 | 25 | $autoloadDev = $this->sortedParameterMerger->mergeRecursiveAndSort(ComposerJsonSection::AUTOLOAD_DEV, 26 | $mainComposerJson->getAutoloadDev(), 27 | $newComposerJson->getAutoloadDev() 28 | ); 29 | 30 | $mainComposerJson->setAutoloadDev($autoloadDev); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getExtra() === []) { 27 | return; 28 | } 29 | 30 | // clean content not desired to merge 31 | $newComposerJsonExtra = $newComposerJson->getExtra(); 32 | // part of the plugin only 33 | if (isset($newComposerJsonExtra[self::PHPSTAN]['includes'])) { 34 | unset($newComposerJsonExtra[self::PHPSTAN]['includes']); 35 | 36 | if ($newComposerJsonExtra[self::PHPSTAN] === []) { 37 | unset($newComposerJsonExtra[self::PHPSTAN]); 38 | } 39 | } 40 | 41 | $extra = $this->sortedParameterMerger->mergeRecursiveAndSort(ComposerJsonSection::EXTRA,$mainComposerJson->getExtra(), $newComposerJsonExtra); 42 | 43 | // do not merge extra alias as only for local packages 44 | if (isset($extra['branch-alias'])) { 45 | unset($extra['branch-alias']); 46 | } 47 | 48 | if (! is_array($extra)) { 49 | return; 50 | } 51 | 52 | $mainComposerJson->setExtra($extra); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php: -------------------------------------------------------------------------------- 1 | getMinimumStability()); 21 | } catch (InvalidPreReleaseSuffixException) { 22 | return; 23 | } 24 | 25 | try { 26 | $mainStability = new PreReleaseSuffix((string) $mainComposerJson->getMinimumStability()); 27 | } catch (InvalidPreReleaseSuffixException) { 28 | $mainStability = null; 29 | } 30 | 31 | if (! $mainStability instanceof PreReleaseSuffix || $mainStability->isGreaterThan($newStability)) { 32 | $mainComposerJson->setMinimumStability($newStability->asString()); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php: -------------------------------------------------------------------------------- 1 | getPreferStable() === null) { 15 | return; 16 | } 17 | 18 | $mainComposerJson->setPreferStable($newComposerJson->getPreferStable()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getReplace() === []) { 15 | return; 16 | } 17 | 18 | $replace = array_merge($newComposerJson->getReplace(), $mainComposerJson->getReplace()); 19 | $mainComposerJson->setReplace($replace); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getRepositories() === []) { 22 | return; 23 | } 24 | 25 | $repositories = $this->sortedParameterMerger->mergeRecursiveAndSort(ComposerJsonSection::REPOSITORIES, 26 | $mainComposerJson->getRepositories(), 27 | $newComposerJson->getRepositories() 28 | ); 29 | 30 | // uniquate special cases, ref https://github.com/symplify/symplify/issues/1197 31 | $repositories = array_unique($repositories, SORT_REGULAR); 32 | // remove keys 33 | $repositories = array_values($repositories); 34 | 35 | $mainComposerJson->setRepositories($repositories); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getRequire() === []) { 24 | return; 25 | } 26 | 27 | $require = $this->sortedParameterMerger->mergeAndSort(ComposerJsonSection::REQUIRE, 28 | $newComposerJson->getRequire(), 29 | $mainComposerJson->getRequire() 30 | ); 31 | 32 | $mainComposerJson->setRequire($require); 33 | 34 | $requireDev = $this->requireRequireDevDuplicateCleaner->unsetPackageFromRequire( 35 | $mainComposerJson, 36 | $mainComposerJson->getRequireDev() 37 | ); 38 | $mainComposerJson->setRequireDev($requireDev); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php: -------------------------------------------------------------------------------- 1 | getRequireDev() === []) { 24 | return; 25 | } 26 | 27 | $requireDev = $this->sortedParameterMerger->mergeAndSort(ComposerJsonSection::REQUIRE_DEV, 28 | $newComposerJson->getRequireDev(), 29 | $mainComposerJson->getRequireDev() 30 | ); 31 | 32 | $requireDev = $this->requireRequireDevDuplicateCleaner->unsetPackageFromRequire($mainComposerJson, $requireDev); 33 | 34 | $mainComposerJson->setRequireDev($requireDev); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/Merge/Configuration/MergedPackagesCollector.php: -------------------------------------------------------------------------------- 1 | packages[] = $package; 17 | } 18 | 19 | /** 20 | * @return string[] 21 | */ 22 | public function getPackages(): array 23 | { 24 | $this->packages = array_unique($this->packages); 25 | 26 | sort($this->packages); 27 | 28 | return $this->packages; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/Merge/Configuration/ModifyingComposerJsonProvider.php: -------------------------------------------------------------------------------- 1 | parameterProvider->provideArrayParameter(Option::DATA_TO_REMOVE); 23 | if ($dataToRemove === []) { 24 | return null; 25 | } 26 | 27 | return $this->composerJsonFactory->createFromArray($dataToRemove); 28 | } 29 | 30 | public function getAppendingComposerJson(): ?ComposerJson 31 | { 32 | $dataToAppend = $this->parameterProvider->provideArrayParameter(Option::DATA_TO_APPEND); 33 | if ($dataToAppend === []) { 34 | return null; 35 | } 36 | 37 | return $this->composerJsonFactory->createFromArray($dataToAppend); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/Merge/Contract/ComposerJsonDecoratorInterface.php: -------------------------------------------------------------------------------- 1 | versionValidator->findConflictingPackageVersionsInFileInfos( 24 | $this->composerJsonProvider->getPackagesComposerFileInfos() 25 | ); 26 | 27 | if ($conflictingPackageVersions === []) { 28 | return; 29 | } 30 | 31 | $this->conflictingPackageVersionsReporter->report($conflictingPackageVersions); 32 | 33 | throw new ShouldNotHappenException('Fix conflicting package version first'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/Merge/JsonSchema.php: -------------------------------------------------------------------------------- 1 | composerSchema = json_decode($json_schema,true, 512, JSON_THROW_ON_ERROR); 21 | } 22 | 23 | public static function getPropertyDefinitions(string $propertyName): array 24 | { 25 | return array_keys((new self())->composerSchema['definitions'][$propertyName]['properties'] ?? []); 26 | } 27 | 28 | public static function getProperties(): array 29 | { 30 | return array_keys((new self())->composerSchema['properties'] ?? []); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /packages/Propagate/VersionPropagator.php: -------------------------------------------------------------------------------- 1 | getRequire(), $mainComposerJson->getRequireDev()); 14 | 15 | foreach ($packagesToVersions as $packageName => $packageVersion) { 16 | if (! $otherComposerJson->hasPackage($packageName)) { 17 | continue; 18 | } 19 | 20 | $otherComposerJson->changePackageVersion($packageName, $packageVersion); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/Release/Configuration/StageResolver.php: -------------------------------------------------------------------------------- 1 | getOption(Option::STAGE); 22 | 23 | // empty 24 | if ($stage === Stage::MAIN) { 25 | $this->releaseGuard->guardRequiredStageOnEmptyStage(); 26 | } else { 27 | $this->releaseGuard->guardStage($stage); 28 | } 29 | 30 | return $stage; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/Release/Configuration/VersionResolver.php: -------------------------------------------------------------------------------- 1 | getArgument(Option::VERSION); 23 | return $this->versionFactory->createValidVersion($versionArgument, $stage); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php: -------------------------------------------------------------------------------- 1 | " 12 | */ 13 | public function getStage(): string; 14 | } 15 | -------------------------------------------------------------------------------- /packages/Release/Exception/ConfigurationException.php: -------------------------------------------------------------------------------- 1 | symfonyStyle->isVerbose()) { 21 | return; 22 | } 23 | 24 | // show debug data on -v/--verbose/--debug 25 | $this->symfonyStyle->writeln('class: ' . $releaseWorker::class); 26 | if ($releaseWorker instanceof StageAwareInterface) { 27 | $this->symfonyStyle->writeln('stage: ' . $releaseWorker->getStage()); 28 | } 29 | 30 | $this->symfonyStyle->newLine(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/Release/Process/ProcessRunner.php: -------------------------------------------------------------------------------- 1 | symfonyStyle->isVerbose()) { 31 | $this->symfonyStyle->note('Running process: ' . $this->normalizeToString($commandLine)); 32 | } 33 | 34 | $process = $this->createProcess($commandLine, $cwd); 35 | $process->run(); 36 | 37 | $this->reportResult($process); 38 | 39 | return $process->getOutput(); 40 | } 41 | 42 | /** 43 | * @param string|string[] $content 44 | */ 45 | private function normalizeToString(string | array $content): string 46 | { 47 | if (is_array($content)) { 48 | return implode(' ', $content); 49 | } 50 | 51 | return $content; 52 | } 53 | 54 | /** 55 | * @param string|string[] $commandLine 56 | */ 57 | private function createProcess(string | array $commandLine, ?string $cwd): Process 58 | { 59 | // @since Symfony 4.2: https://github.com/symfony/symfony/pull/27821 60 | if (is_string($commandLine) && method_exists(Process::class, 'fromShellCommandline')) { 61 | return Process::fromShellCommandline($commandLine, $cwd, null, null, self::TIMEOUT); 62 | } 63 | 64 | return new Process($commandLine, $cwd, null, null, self::TIMEOUT); 65 | } 66 | 67 | private function reportResult(Process $process): void 68 | { 69 | if ($process->isSuccessful()) { 70 | return; 71 | } 72 | 73 | throw new ProcessFailedException($process); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php: -------------------------------------------------------------------------------- 1 | createNewHeadline($version); 34 | 35 | $changelogFileContent = $this->smartFileSystem->readFile($changelogFilePath); 36 | $changelogFileContent = Strings::replace( 37 | $changelogFileContent, 38 | self::UNRELEASED_HEADLINE_REGEX, 39 | '## ' . $newHeadline 40 | ); 41 | 42 | $this->smartFileSystem->dumpFile($changelogFilePath, $changelogFileContent); 43 | } 44 | 45 | public function getDescription(Version $version): string 46 | { 47 | $newHeadline = $this->createNewHeadline($version); 48 | 49 | return sprintf('Change "Unreleased" in `CHANGELOG.md` to "%s"', $newHeadline); 50 | } 51 | 52 | private function createNewHeadline(Version $version): string 53 | { 54 | $dateTime = new DateTime(); 55 | return $version->getVersionString() . ' - ' . $dateTime->format('Y-m-d'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php: -------------------------------------------------------------------------------- 1 | branchName = $parameterProvider->provideStringParameter(Option::DEFAULT_BRANCH_NAME); 24 | } 25 | 26 | public function work(Version $version): void 27 | { 28 | $versionInString = $this->getVersionDev($version); 29 | 30 | $gitAddCommitCommand = sprintf( 31 | 'git add . && git commit --allow-empty -m "open %s" && git push origin "%s"', 32 | $versionInString, 33 | $this->branchName 34 | ); 35 | 36 | $this->processRunner->run($gitAddCommitCommand); 37 | } 38 | 39 | public function getDescription(Version $version): string 40 | { 41 | $versionInString = $this->getVersionDev($version); 42 | 43 | return sprintf('Push "%s" open to remote repository', $versionInString); 44 | } 45 | 46 | private function getVersionDev(Version $version): string 47 | { 48 | return $this->versionUtils->getNextAliasFormat($version); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/PushTagReleaseWorker.php: -------------------------------------------------------------------------------- 1 | processRunner->run('git push --tags'); 21 | } 22 | 23 | public function getDescription(Version $version): string 24 | { 25 | return sprintf('Push "%s" tag to remote repository', $version->getVersionString()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php: -------------------------------------------------------------------------------- 1 | versionUtils->getRequiredFormat($version); 27 | 28 | $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( 29 | $this->composerJsonProvider->getPackagesComposerFileInfos(), 30 | $this->packageNamesProvider->provide(), 31 | $versionInString 32 | ); 33 | 34 | // give time to propagate values before commit 35 | sleep(1); 36 | } 37 | 38 | public function getDescription(Version $version): string 39 | { 40 | $versionInString = $this->versionUtils->getRequiredFormat($version); 41 | 42 | return sprintf('Set packages mutual dependencies to "%s" version', $versionInString); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php: -------------------------------------------------------------------------------- 1 | versionUtils->getRequiredNextFormat($version); 27 | 28 | $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( 29 | $this->composerJsonProvider->getPackagesComposerFileInfos(), 30 | $this->packageNamesProvider->provide(), 31 | $versionInString 32 | ); 33 | } 34 | 35 | public function getDescription(Version $version): string 36 | { 37 | $versionInString = $this->versionUtils->getRequiredNextFormat($version); 38 | 39 | return sprintf('Set packages mutual dependencies to "%s" (alias of dev version)', $versionInString); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php: -------------------------------------------------------------------------------- 1 | versionUtils->getNextAliasFormat($version); 25 | 26 | $this->devMasterAliasUpdater->updateFileInfosWithAlias( 27 | $this->composerJsonProvider->getPackagesComposerFileInfos(), 28 | $nextAlias 29 | ); 30 | } 31 | 32 | public function getDescription(Version $version): string 33 | { 34 | $nextAlias = $this->versionUtils->getNextAliasFormat($version); 35 | 36 | return sprintf('Set branch alias "%s" to all packages', $nextAlias); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php: -------------------------------------------------------------------------------- 1 | composerJsonProvider->getRootComposerJson(); 25 | 26 | $replace = $rootComposerJson->getReplace(); 27 | 28 | $packageNames = $this->composerJsonProvider->getPackageNames(); 29 | 30 | $newReplace = []; 31 | foreach (array_keys($replace) as $package) { 32 | if (! in_array($package, $packageNames, true)) { 33 | continue; 34 | } 35 | 36 | $newReplace[$package] = $version->getVersionString(); 37 | } 38 | 39 | if ($replace === $newReplace) { 40 | return; 41 | } 42 | 43 | $rootComposerJson->setReplace($newReplace); 44 | 45 | $rootFileInfo = $rootComposerJson->getFileInfo(); 46 | if (! $rootFileInfo instanceof SmartFileInfo) { 47 | throw new MissingComposerJsonException(); 48 | } 49 | 50 | $this->jsonFileManager->printJsonToFileInfo($rootComposerJson->getJsonArray(), $rootFileInfo); 51 | } 52 | 53 | public function getDescription(Version $version): string 54 | { 55 | return 'Update "replace" version in "composer.json" to new tag to avoid circular dependencies conflicts'; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/Release/ReleaseWorkerProvider.php: -------------------------------------------------------------------------------- 1 | releaseWorkers; 32 | } 33 | 34 | $activeReleaseWorkers = []; 35 | foreach ($this->releaseWorkers as $releaseWorker) { 36 | if (! $releaseWorker instanceof StageAwareInterface) { 37 | continue; 38 | } 39 | 40 | if ($stage !== $releaseWorker->getStage()) { 41 | continue; 42 | } 43 | 44 | $activeReleaseWorkers[] = $releaseWorker; 45 | } 46 | 47 | return $activeReleaseWorkers; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/Release/ValueObject/SemVersion.php: -------------------------------------------------------------------------------- 1 | branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter( 23 | Option::DEFAULT_BRANCH_NAME 24 | ); 25 | } 26 | 27 | /** 28 | * @param mixed[] $packageComposerJson 29 | * @param string[] $usedPackageNames 30 | * @return mixed[] 31 | */ 32 | public function decorateAsteriskVersionForUsedPackages(array $packageComposerJson, array $usedPackageNames): array 33 | { 34 | foreach ([ComposerJsonSection::REQUIRE, ComposerJsonSection::REQUIRE_DEV] as $section) { 35 | foreach ($usedPackageNames as $usedPackageName) { 36 | if (! isset($packageComposerJson[$section][$usedPackageName])) { 37 | continue; 38 | } 39 | 40 | $packageComposerJson[$section][$usedPackageName] = $this->branchAliasTarget; 41 | } 42 | } 43 | 44 | return $packageComposerJson; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/Testing/ComposerJsonRequireUpdater.php: -------------------------------------------------------------------------------- 1 | jsonFileManager->loadFromFileInfo($packageFileInfo); 28 | 29 | $usedPackageNames = $this->usedPackagesResolver->resolveForPackage($packageComposerJson); 30 | if ($usedPackageNames === []) { 31 | $message = sprintf( 32 | 'Package "%s" does not use any mutual dependencies, so we skip it', 33 | $packageFileInfo->getRelativeFilePathFromCwd() 34 | ); 35 | $this->symfonyStyle->note($message); 36 | return; 37 | } 38 | 39 | $packageComposerJson = $this->composerVersionManipulator->decorateAsteriskVersionForUsedPackages( 40 | $packageComposerJson, 41 | $usedPackageNames 42 | ); 43 | 44 | $oldComposerJsonContents = $packageFileInfo->getContents(); 45 | 46 | $newComposerJsonContents = $this->jsonFileManager->printJsonToFileInfoAndReturn( 47 | $packageComposerJson, 48 | $packageFileInfo 49 | ); 50 | 51 | $message = sprintf('File "%s" was updated', $packageFileInfo->getRelativeFilePathFromCwd()); 52 | $this->symfonyStyle->title($message); 53 | 54 | $diff = $this->consoleDiffer->diff($oldComposerJsonContents, $newComposerJsonContents); 55 | $this->symfonyStyle->writeln($diff); 56 | 57 | $this->symfonyStyle->newLine(2); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/Testing/PackageDependency/UsedPackagesResolver.php: -------------------------------------------------------------------------------- 1 | packageNamesProvider->provide(), true)) { 33 | continue; 34 | } 35 | 36 | $usedPackageNames[] = $packageName; 37 | } 38 | } 39 | 40 | return $usedPackageNames; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/Testing/PathResolver/PackagePathResolver.php: -------------------------------------------------------------------------------- 1 | getRealPath()); 22 | $nestingLevel = 0; 23 | 24 | while ($currentDirectory . '/composer.json' !== $rootComposerFileInfo->getRealPath()) { 25 | ++$nestingLevel; 26 | $currentDirectory = dirname($currentDirectory); 27 | } 28 | 29 | return str_repeat('../', $nestingLevel); 30 | } 31 | 32 | public function resolveRelativeDirectoryToRoot( 33 | SmartFileInfo $rootComposerFileInfo, 34 | SmartFileInfo $packageComposerFileInfo 35 | ): string { 36 | $rootDirectory = dirname($rootComposerFileInfo->getRealPath()); 37 | 38 | return dirname($packageComposerFileInfo->getRelativeFilePathFromDirectory($rootDirectory)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/Testing/ValueObject/Option.php: -------------------------------------------------------------------------------- 1 | sets([ 13 | SetList::CODE_QUALITY, 14 | SetList::DEAD_CODE, 15 | LevelSetList::UP_TO_PHP_82, 16 | SetList::CODING_STYLE, 17 | SetList::TYPE_DECLARATION, 18 | SetList::NAMING, 19 | SetList::PRIVATIZATION, 20 | SetList::EARLY_RETURN, 21 | PHPUnitSetList::PHPUNIT_CODE_QUALITY, 22 | ]); 23 | 24 | $rectorConfig->rules([ 25 | ExplicitNullableParamTypeRector::class, 26 | Rector\PHPUnit\PHPUnit70\Rector\Class_\RemoveDataProviderTestPrefixRector::class, 27 | Rector\PHPUnit\PHPUnit100\Rector\Class_\StaticDataProviderClassMethodRector::class, 28 | Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DataProviderAnnotationToAttributeRector::class, 29 | 30 | ]); 31 | 32 | $rectorConfig->paths([ 33 | __DIR__ . '/config', 34 | __DIR__ . '/src', 35 | __DIR__ . '/tests', 36 | __DIR__ . '/src-deps', 37 | __DIR__ . '/packages', 38 | __DIR__ . '/packages-tests', 39 | ]); 40 | 41 | $rectorConfig->importNames(); 42 | 43 | $rectorConfig->skip([ 44 | '*/scoper.php', 45 | '*/Source/*', 46 | '*/Fixture/*', 47 | '*/vendor/*', 48 | ]); 49 | }; 50 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | github: tomasvotruba 3 | custom: https://www.paypal.me/rectorphp 4 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/.github/workflows/code_analysis.yaml: -------------------------------------------------------------------------------- 1 | name: Code Analysis 2 | 3 | on: 4 | pull_request: null 5 | push: 6 | branches: 7 | - main 8 | 9 | env: 10 | # see https://github.com/composer/composer/issues/9368#issuecomment-718112361 11 | COMPOSER_ROOT_VERSION: "dev-main" 12 | 13 | jobs: 14 | code_analysis: 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | actions: 19 | - 20 | name: 'PHPStan' 21 | run: composer phpstan --ansi 22 | 23 | - 24 | name: 'Composer Validate' 25 | run: composer validate --ansi 26 | 27 | - 28 | name: 'Rector' 29 | run: composer rector --ansi 30 | 31 | - 32 | name: 'Coding Standard' 33 | run: composer fix-cs --ansi 34 | 35 | - 36 | name: 'Tests' 37 | run: vendor/bin/phpunit 38 | 39 | - 40 | name: 'PHP Linter' 41 | run: vendor/bin/parallel-lint src tests 42 | 43 | - 44 | name: 'Check Commented Code' 45 | run: vendor/bin/easy-ci check-commented-code src tests --ansi 46 | 47 | - 48 | name: 'Check Active Classes' 49 | run: vendor/bin/easy-ci check-active-class src --ansi 50 | 51 | name: ${{ matrix.actions.name }} 52 | runs-on: ubuntu-latest 53 | 54 | steps: 55 | - uses: actions/checkout@v3 56 | # see https://github.com/shivammathur/setup-php 57 | - uses: shivammathur/setup-php@v2 58 | with: 59 | php-version: 8.1 60 | coverage: none 61 | 62 | # composer install cache - https://github.com/ramsey/composer-install 63 | - uses: "ramsey/composer-install@v2" 64 | 65 | - run: ${{ matrix.actions.run }} 66 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | --------------- 3 | 4 | Copyright (c) 2018 Tomas Votruba (https://tomasvotruba.com) 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symplify/autowire-array-parameter", 3 | "description": "Autowire array parameters for your Symfony applications", 4 | "license": "MIT", 5 | "require": { 6 | "php": ">=8.2", 7 | "nette/utils": "^4.0.5", 8 | "symfony/dependency-injection": "^7.0" 9 | }, 10 | "require-dev": { 11 | "php-parallel-lint/php-parallel-lint": "^1.3", 12 | "phpstan/extension-installer": "^1.2", 13 | "phpunit/phpunit": "^11.0", 14 | "symplify/easy-ci": "^11.1", 15 | "symplify/package-builder": "*", 16 | "symplify/phpstan-extensions": "^11.1", 17 | "symplify/symplify-kernel": "*", 18 | "tomasvotruba/class-leak": "^2.0.5", 19 | "tomasvotruba/unused-public": "^0.3.0" 20 | }, 21 | "repositories": [ 22 | { 23 | "type": "path", 24 | "url": "../composer-json-manipulator" 25 | }, 26 | { 27 | "type": "path", 28 | "url": "../easy-testing" 29 | }, 30 | { 31 | "type": "path", 32 | "url": "../package-builder" 33 | }, 34 | { 35 | "type": "path", 36 | "url": "../smart-file-system" 37 | }, 38 | { 39 | "type": "path", 40 | "url": "../symplify-kernel" 41 | } 42 | ], 43 | "autoload": { 44 | "psr-4": { 45 | "Symplify\\AutowireArrayParameter\\": "src" 46 | } 47 | }, 48 | "autoload-dev": { 49 | "psr-4": { 50 | "Symplify\\AutowireArrayParameter\\Tests\\": "tests" 51 | } 52 | }, 53 | "extra": { 54 | "branch-alias": { 55 | "dev-main": "11.2-dev" 56 | } 57 | }, 58 | "scripts": { 59 | "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify", 60 | "release": "vendor/bin/monorepo-builder release patch --ansi" 61 | }, 62 | "minimum-stability": "dev", 63 | "prefer-stable": true, 64 | "config": { 65 | "sort-packages": true, 66 | "platform-check": false, 67 | "allow-plugins": { 68 | "cweagans/composer-patches": true, 69 | "phpstan/extension-installer": true 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/easy-ci.php: -------------------------------------------------------------------------------- 1 | [\w\\\\]+)\[\]\s+\$' . self::NAME_PLACEHOLDER . '#'; 27 | 28 | /** 29 | * @var string 30 | * @see https://regex101.com/r/FZ50hn/2 31 | */ 32 | private const SHAPE_REGEX = '#@param\s+(array|iterable)\<(?<' . self::TYPE_PART . '>[\w\\\\]+)\>\s+\$' . self::NAME_PLACEHOLDER . '#'; 33 | 34 | /** 35 | * @var string 36 | */ 37 | private const NAME_PLACEHOLDER = '__NAME__'; 38 | 39 | /** 40 | * @var string[] 41 | */ 42 | private const ARRAY_REGEXES = [self::NORMAL_REGEX, self::SHAPE_REGEX]; 43 | 44 | public function resolve(string $docBlock, string $parameterName): ?string 45 | { 46 | foreach (self::ARRAY_REGEXES as $arrayRegexWithPlaceholder) { 47 | $arrayRegex = str_replace(self::NAME_PLACEHOLDER, $parameterName, $arrayRegexWithPlaceholder); 48 | 49 | $result = Strings::match($docBlock, $arrayRegex); 50 | if (isset($result[self::TYPE_PART])) { 51 | return $result[self::TYPE_PART]; 52 | } 53 | } 54 | 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src-deps/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | private array $resolvedParameterTypesCached = []; 17 | 18 | public function __construct( 19 | private readonly ParamTypeDocBlockResolver $paramTypeDocBlockResolver 20 | ) { 21 | } 22 | 23 | public function resolveParameterType(string $parameterName, ReflectionMethod $reflectionMethod): ?string 24 | { 25 | $docComment = $reflectionMethod->getDocComment(); 26 | if ($docComment === false) { 27 | return null; 28 | } 29 | 30 | $declaringReflectionClass = $reflectionMethod->getDeclaringClass(); 31 | $uniqueKey = $parameterName . $declaringReflectionClass->getName() . $reflectionMethod->getName(); 32 | if (isset($this->resolvedParameterTypesCached[$uniqueKey])) { 33 | return $this->resolvedParameterTypesCached[$uniqueKey]; 34 | } 35 | 36 | $resolvedType = $this->paramTypeDocBlockResolver->resolve($docComment, $parameterName); 37 | if ($resolvedType === null) { 38 | return null; 39 | } 40 | 41 | // not a class|interface type 42 | if (ctype_lower($resolvedType[0])) { 43 | return null; 44 | } 45 | 46 | $resolvedClass = Reflection::expandClassName($resolvedType, $declaringReflectionClass); 47 | $this->resolvedParameterTypesCached[$uniqueKey] = $resolvedClass; 48 | 49 | return $resolvedClass; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | github: tomasvotruba 3 | custom: https://www.paypal.me/rectorphp 4 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/.github/workflows/auto_closer.yaml: -------------------------------------------------------------------------------- 1 | name: Auto Closer PR 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | 7 | jobs: 8 | run: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: superbrothers/close-pull-request@v3 12 | with: 13 | # Optional. Post a issue comment just before closing a pull request. 14 | comment: | 15 | Hi, thank you for your contribution. 16 | 17 | Unfortunately, this repository is read-only. It's a split from our main monorepo repository. 18 | 19 | We'd like to kindly ask you to move the contribution there - https://github.com/symplify/symplify. 20 | 21 | We'll check it, review it and give you feed back right way. 22 | 23 | Thank you. 24 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | --------------- 3 | 4 | Copyright (c) 2020 Tomas Votruba (https://tomasvotruba.com) 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/config/config.php: -------------------------------------------------------------------------------- 1 | parameters(); 16 | 17 | $parameters->set(Option::INLINE_SECTIONS, ['keywords']); 18 | 19 | $services = $containerConfigurator->services(); 20 | 21 | $services->defaults() 22 | ->public() 23 | ->autowire(); 24 | 25 | $services->load('Symplify\ComposerJsonManipulator\\', __DIR__ . '/../src'); 26 | 27 | $services->set(SmartFileSystem::class); 28 | $services->set(PrivatesCaller::class); 29 | 30 | $services->set(ParameterProvider::class) 31 | ->args([service('service_container')]); 32 | 33 | $services->set(SymfonyStyleFactory::class); 34 | $services->set(SymfonyStyle::class) 35 | ->factory([service(SymfonyStyleFactory::class), 'create']); 36 | }; 37 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/src/Json/JsonCleaner.php: -------------------------------------------------------------------------------- 1 | $data 11 | * @return array 12 | */ 13 | public function removeEmptyKeysFromJsonArray(array $data): array 14 | { 15 | foreach ($data as $key => $value) { 16 | if (! is_array($value)) { 17 | continue; 18 | } 19 | 20 | if ($value === []) { 21 | unset($data[$key]); 22 | } else { 23 | $data[$key] = $this->removeEmptyKeysFromJsonArray($value); 24 | } 25 | } 26 | 27 | return $data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/src/Json/JsonInliner.php: -------------------------------------------------------------------------------- 1 | parameterProvider->hasParameter(Option::INLINE_SECTIONS)) { 27 | return $jsonContent; 28 | } 29 | 30 | $inlineSections = $this->parameterProvider->provideArrayParameter(Option::INLINE_SECTIONS); 31 | 32 | foreach ($inlineSections as $inlineSection) { 33 | $pattern = '#("' . preg_quote((string) $inlineSection, '#') . '": )\[(.*?)\](,)#ms'; 34 | 35 | $jsonContent = Strings::replace($jsonContent, $pattern, static function (array $match): string { 36 | $inlined = Strings::replace($match[2], self::SPACE_REGEX, ' '); 37 | $inlined = trim($inlined); 38 | $inlined = '[' . $inlined . ']'; 39 | return $match[1] . $inlined . $match[3]; 40 | }); 41 | } 42 | 43 | return $jsonContent; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/src/Printer/ComposerJsonPrinter.php: -------------------------------------------------------------------------------- 1 | jsonFileManager->encodeJsonToFileContent($composerJson->getJsonArray()); 24 | } 25 | 26 | public function print(ComposerJson $composerJson, string | SmartFileInfo $targetFile): void 27 | { 28 | if (is_string($targetFile)) { 29 | $this->jsonFileManager->printComposerJsonToFilePath($composerJson, $targetFile); 30 | return; 31 | } 32 | 33 | $this->jsonFileManager->printJsonToFileInfo($composerJson->getJsonArray(), $targetFile); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src-deps/composer-json-manipulator/src/ValueObject/ComposerJsonManipulatorConfig.php: -------------------------------------------------------------------------------- 1 | run(); 26 | -------------------------------------------------------------------------------- /src-deps/easy-testing/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symplify/easy-testing", 3 | "description": "Testing made easy", 4 | "license": "MIT", 5 | "type": "symfony-bundle", 6 | "bin": [ 7 | "bin/easy-testing" 8 | ], 9 | "require": { 10 | "php": ">=8.2", 11 | "nette/utils": "^4.0.5", 12 | "symfony/finder": "^7.0", 13 | "symfony/console": "^7.0", 14 | "symfony/dependency-injection": "^7.0", 15 | "symplify/package-builder": "*", 16 | "symplify/symplify-kernel": "*", 17 | "symplify/smart-file-system": "*" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "^11.0", 21 | "php-parallel-lint/php-parallel-lint": "^1.3", 22 | "phpstan/extension-installer": "^1.2", 23 | "symplify/easy-ci": "^11.1", 24 | "symplify/phpstan-extensions": "^11.1", 25 | "tomasvotruba/class-leak": "^2.0.5", 26 | "tomasvotruba/unused-public": "^0.3.0" 27 | }, 28 | "repositories": [ 29 | { 30 | "type": "path", 31 | "url": "../autowire-array-parameter" 32 | }, 33 | { 34 | "type": "path", 35 | "url": "../composer-json-manipulator" 36 | }, 37 | { 38 | "type": "path", 39 | "url": "../package-builder" 40 | }, 41 | { 42 | "type": "path", 43 | "url": "../smart-file-system" 44 | }, 45 | { 46 | "type": "path", 47 | "url": "../symplify-kernel" 48 | } 49 | ], 50 | "autoload": { 51 | "psr-4": { 52 | "Symplify\\EasyTesting\\": "src" 53 | } 54 | }, 55 | "autoload-dev": { 56 | "psr-4": { 57 | "Symplify\\EasyTesting\\Tests\\": "tests" 58 | } 59 | }, 60 | "extra": { 61 | "branch-alias": { 62 | "dev-main": "11.2-dev" 63 | } 64 | }, 65 | "scripts": { 66 | "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify" 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true, 70 | "config": { 71 | "sort-packages": true, 72 | "platform-check": false, 73 | "allow-plugins": { 74 | "cweagans/composer-patches": true, 75 | "phpstan/extension-installer": true 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src-deps/easy-testing/config/config.php: -------------------------------------------------------------------------------- 1 | services(); 12 | 13 | $services->defaults() 14 | ->public() 15 | ->autowire(); 16 | 17 | $services->load('Symplify\EasyTesting\\', __DIR__ . '/../src') 18 | ->exclude([__DIR__ . '/../src/DataProvider', __DIR__ . '/../src/Kernel', __DIR__ . '/../src/ValueObject']); 19 | 20 | // console 21 | $services->set(Application::class) 22 | ->call('add', [service(ValidateFixtureSkipNamingCommand::class)]); 23 | }; 24 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/DataProvider/StaticFixtureUpdater.php: -------------------------------------------------------------------------------- 1 | dumpFile($fixtureFileInfo->getRealPath(), $newOriginalContent); 28 | } 29 | 30 | public static function updateExpectedFixtureContent( 31 | string $newOriginalContent, 32 | SmartFileInfo $expectedFixtureFileInfo 33 | ): void { 34 | if (! getenv('UPDATE_TESTS') && ! getenv('UT')) { 35 | return; 36 | } 37 | 38 | self::getSmartFileSystem() 39 | ->dumpFile($expectedFixtureFileInfo->getRealPath(), $newOriginalContent); 40 | } 41 | 42 | private static function getSmartFileSystem(): SmartFileSystem 43 | { 44 | return new SmartFileSystem(); 45 | } 46 | 47 | private static function resolveNewFixtureContent( 48 | SmartFileInfo|string $originalFileInfo, 49 | string $changedContent 50 | ): string { 51 | if ($originalFileInfo instanceof SmartFileInfo) { 52 | $originalContent = $originalFileInfo->getContents(); 53 | } else { 54 | $originalContent = $originalFileInfo; 55 | } 56 | 57 | if ($originalContent === $changedContent) { 58 | return $originalContent; 59 | } 60 | 61 | return $originalContent . '-----' . PHP_EOL . $changedContent; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/Finder/FixtureFinder.php: -------------------------------------------------------------------------------- 1 | files() 26 | ->in($sources) 27 | ->name('*.php.inc') 28 | ->path('Fixture') 29 | ->sortByName(); 30 | 31 | return $this->finderSanitizer->sanitize($finder); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php: -------------------------------------------------------------------------------- 1 | getContents(), SplitLine::SPLIT_LINE_REGEX); 21 | $this->ensureHasThreeParts($parts, $smartFileInfo); 22 | 23 | return new TrioContent($parts[0], $parts[1], $parts[2]); 24 | } 25 | 26 | /** 27 | * @param mixed[] $parts 28 | */ 29 | private function ensureHasThreeParts(array $parts, SmartFileInfo $smartFileInfo): void 30 | { 31 | if (count($parts) === 3) { 32 | return; 33 | } 34 | 35 | $message = sprintf( 36 | 'The fixture "%s" should have 3 parts. %d found', 37 | $smartFileInfo->getRelativeFilePathFromCwd(), 38 | count($parts) 39 | ); 40 | throw new ShouldNotHappenException($message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/Kernel/EasyTestingKernel.php: -------------------------------------------------------------------------------- 1 | create($configFiles); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/MissplacedSkipPrefixResolver.php: -------------------------------------------------------------------------------- 1 | hasNameSkipStart($fixtureFileInfo); 28 | $fileContents = $fixtureFileInfo->getContents(); 29 | $hasSplitLine = (bool) Strings::match($fileContents, SplitLine::SPLIT_LINE_REGEX); 30 | 31 | if ($hasNameSkipStart && $hasSplitLine) { 32 | $incorrectSkips[] = $fixtureFileInfo; 33 | continue; 34 | } 35 | 36 | if (! $hasNameSkipStart && ! $hasSplitLine) { 37 | $missingSkips[] = $fixtureFileInfo; 38 | } 39 | } 40 | 41 | return new IncorrectAndMissingSkips($incorrectSkips, $missingSkips); 42 | } 43 | 44 | private function hasNameSkipStart(SmartFileInfo $fixtureFileInfo): bool 45 | { 46 | return (bool) Strings::match($fixtureFileInfo->getBasenameWithoutSuffix(), Prefix::SKIP_PREFIX_REGEX); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php: -------------------------------------------------------------------------------- 1 | expectedFileInfo->getContents(); 24 | } 25 | 26 | public function getOutputFileContent(): string 27 | { 28 | if (! $this->outputFileInfo instanceof SmartFileInfo) { 29 | throw new ShouldNotHappenException(); 30 | } 31 | 32 | return $this->outputFileInfo->getContents(); 33 | } 34 | 35 | public function doesOutputFileExist(): bool 36 | { 37 | return $this->outputFileInfo instanceof SmartFileInfo; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php: -------------------------------------------------------------------------------- 1 | firstValue; 22 | } 23 | 24 | public function getSecondValue(): string 25 | { 26 | return $this->secondValue; 27 | } 28 | 29 | public function getExpectedResult(): string 30 | { 31 | return $this->expectedResult; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php: -------------------------------------------------------------------------------- 1 | incorrectSkipFileInfos; 27 | } 28 | 29 | /** 30 | * @return SmartFileInfo[] 31 | */ 32 | public function getMissingSkipFileInfos(): array 33 | { 34 | return $this->missingSkipFileInfos; 35 | } 36 | 37 | public function getFileCount(): int 38 | { 39 | return count($this->missingSkipFileInfos) + count($this->incorrectSkipFileInfos); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/InputAndExpected.php: -------------------------------------------------------------------------------- 1 | input; 18 | } 19 | 20 | public function getExpected(): mixed 21 | { 22 | return $this->expected; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/InputFileInfoAndExpected.php: -------------------------------------------------------------------------------- 1 | inputFileInfo->getContents(); 23 | } 24 | 25 | public function getInputFileInfo(): SmartFileInfo 26 | { 27 | return $this->inputFileInfo; 28 | } 29 | 30 | public function getInputFileRealPath(): string 31 | { 32 | return $this->inputFileInfo->getRealPath(); 33 | } 34 | 35 | public function getExpected(): mixed 36 | { 37 | return $this->expected; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php: -------------------------------------------------------------------------------- 1 | inputFileInfo; 23 | } 24 | 25 | public function getExpectedFileInfo(): SmartFileInfo 26 | { 27 | return $this->expectedFileInfo; 28 | } 29 | 30 | public function getExpectedFileContent(): string 31 | { 32 | return $this->expectedFileInfo->getContents(); 33 | } 34 | 35 | public function getExpectedFileInfoRealPath(): string 36 | { 37 | return $this->expectedFileInfo->getRealPath(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src-deps/easy-testing/src/ValueObject/Option.php: -------------------------------------------------------------------------------- 1 | =8.2", 7 | "nette/utils": "^4.0.5", 8 | "sebastian/diff": "^6.0", 9 | "symfony/config": "^7.0", 10 | "symfony/console": "^7.0", 11 | "symfony/dependency-injection": "^7.0", 12 | "symfony/http-kernel": "^7.0", 13 | "symfony/finder": "^7.0" 14 | }, 15 | "require-dev": { 16 | "php-parallel-lint/php-parallel-lint": "^1.3", 17 | "phpstan/extension-installer": "^1.2", 18 | "phpunit/phpunit": "^11.0", 19 | "symplify/easy-ci": "^11.2.0", 20 | "symplify/phpstan-extensions": "^11.1", 21 | "symplify/phpstan-rules": "^12.4.9", 22 | "symplify/symplify-kernel": "*", 23 | "tomasvotruba/class-leak": "^2.0.5", 24 | "tomasvotruba/unused-public": "^0.3.0" 25 | }, 26 | "repositories": [ 27 | { 28 | "type": "path", 29 | "url": "../autowire-array-parameter" 30 | }, 31 | { 32 | "type": "path", 33 | "url": "../easy-testing" 34 | }, 35 | { 36 | "type": "path", 37 | "url": "../smart-file-system" 38 | }, 39 | { 40 | "type": "path", 41 | "url": "../symplify-kernel" 42 | } 43 | ], 44 | "autoload": { 45 | "psr-4": { 46 | "Symplify\\PackageBuilder\\": "src" 47 | } 48 | }, 49 | "autoload-dev": { 50 | "psr-4": { 51 | "Symplify\\PackageBuilder\\Tests\\": "tests" 52 | } 53 | }, 54 | "extra": { 55 | "branch-alias": { 56 | "dev-main": "11.2-dev" 57 | } 58 | }, 59 | "scripts": { 60 | "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify" 61 | }, 62 | "minimum-stability": "dev", 63 | "prefer-stable": true, 64 | "config": { 65 | "sort-packages": true, 66 | "platform-check": false, 67 | "allow-plugins": { 68 | "cweagans/composer-patches": true, 69 | "phpstan/extension-installer": true 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src-deps/package-builder/config/config.php: -------------------------------------------------------------------------------- 1 | services(); 15 | 16 | $services->defaults() 17 | ->public() 18 | ->autowire(); 19 | 20 | $services->set(ColorConsoleDiffFormatter::class); 21 | 22 | $services->set(ConsoleDiffer::class); 23 | 24 | $services->set(DifferFactory::class); 25 | $services->set(Differ::class) 26 | ->factory([service(DifferFactory::class), 'create']); 27 | 28 | $services->set(PrivatesAccessor::class); 29 | }; 30 | -------------------------------------------------------------------------------- /src-deps/package-builder/phpstan-baseline.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | ignoreErrors: 3 | - 4 | message: "#^Parameter \\#1 \\$path of function dirname expects string, string\\|false given\\.$#" 5 | count: 1 6 | path: src/Composer/VendorDirProvider.php 7 | 8 | - 9 | message: "#^Call to an undefined method Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\:\\:getParameterBag\\(\\)\\.$#" 10 | count: 1 11 | path: src/Parameter/ParameterProvider.php 12 | 13 | - 14 | message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" 15 | count: 1 16 | path: src/Reflection/ClassLikeExistenceChecker.php 17 | 18 | - 19 | message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" 20 | count: 2 21 | path: src/Reflection/PrivatesCaller.php 22 | 23 | - 24 | message: "#^Call to method setConfigs\\(\\) on an unknown class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface\\.$#" 25 | count: 1 26 | path: src/Testing/AbstractKernelTestCase.php 27 | 28 | - 29 | message: "#^Class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface not found\\.$#" 30 | count: 2 31 | path: src/Testing/AbstractKernelTestCase.php 32 | 33 | - 34 | message: "#^PHPDoc tag @var for variable \\$kernel contains unknown class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface\\.$#" 35 | count: 1 36 | path: src/Testing/AbstractKernelTestCase.php 37 | 38 | - 39 | message: "#^Parameter \\#1 \\$kernel of method Symplify\\\\PackageBuilder\\\\Testing\\\\AbstractKernelTestCase\\:\\:bootAndReturnKernel\\(\\) expects Symfony\\\\Component\\\\HttpKernel\\\\KernelInterface, Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface given\\.$#" 40 | count: 1 41 | path: src/Testing/AbstractKernelTestCase.php 42 | 43 | - 44 | message: "#^Static property Symplify\\\\PackageBuilder\\\\Testing\\\\AbstractKernelTestCase\\:\\:\\$container \\(Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\) does not accept Psr\\\\Container\\\\ContainerInterface\\.$#" 45 | count: 2 46 | path: src/Testing/AbstractKernelTestCase.php 47 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Composer/VendorDirProvider.php: -------------------------------------------------------------------------------- 1 | reflectionFallback(); 30 | } 31 | 32 | private function reflectionFallback(): string 33 | { 34 | $reflectionClass = new ReflectionClass(ClassLoader::class); 35 | return dirname($reflectionClass->getFileName(), 2); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Console/Command/AbstractSymplifyCommand.php: -------------------------------------------------------------------------------- 1 | addOption(Option::CONFIG, 'c', InputOption::VALUE_REQUIRED, 'Path to config file'); 31 | } 32 | 33 | #[Required] 34 | public function autowire( 35 | SymfonyStyle $symfonyStyle, 36 | SmartFileSystem $smartFileSystem, 37 | SmartFinder $smartFinder, 38 | FileSystemGuard $fileSystemGuard 39 | ): void { 40 | $this->symfonyStyle = $symfonyStyle; 41 | $this->smartFileSystem = $smartFileSystem; 42 | $this->smartFinder = $smartFinder; 43 | $this->fileSystemGuard = $fileSystemGuard; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Console/Input/StaticInputDetector.php: -------------------------------------------------------------------------------- 1 | hasParameterOption(['--debug', '-v', '-vv', '-vvv']); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Console/Output/ConsoleDiffer.php: -------------------------------------------------------------------------------- 1 | differ->diff($old, $new); 24 | return $this->colorConsoleDiffFormatter->format($diff); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Console/Style/SymfonyStyleFactory.php: -------------------------------------------------------------------------------- 1 | privatesCaller = new PrivatesCaller(); 24 | } 25 | 26 | public function create(): SymfonyStyle 27 | { 28 | // to prevent missing argv indexes 29 | if (! isset($_SERVER['argv'])) { 30 | $_SERVER['argv'] = []; 31 | } 32 | 33 | $argvInput = new ArgvInput(); 34 | $consoleOutput = new ConsoleOutput(); 35 | 36 | // to configure all -v, -vv, -vvv options without memory-lock to Application run() arguments 37 | $this->privatesCaller->callPrivateMethod(new Application(), 'configureIO', [$argvInput, $consoleOutput]); 38 | 39 | // --debug is called 40 | if ($argvInput->hasParameterOption('--debug')) { 41 | $consoleOutput->setVerbosity(OutputInterface::VERBOSITY_DEBUG); 42 | } 43 | 44 | // disable output for tests 45 | if ($this->isPHPUnitRun()) { 46 | $consoleOutput->setVerbosity(OutputInterface::VERBOSITY_QUIET); 47 | } 48 | 49 | return new SymfonyStyle($argvInput, $consoleOutput); 50 | } 51 | 52 | /** 53 | * Never ever used static methods if not neccesary, this is just handy for tests + src to prevent duplication. 54 | */ 55 | private function isPHPUnitRun(): bool 56 | { 57 | return defined('PHPUNIT_COMPOSER_INSTALL') || defined('__PHPUNIT_PHAR__'); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php: -------------------------------------------------------------------------------- 1 | getDefinitions(); 23 | 24 | foreach ($definitions as $definition) { 25 | foreach ($this->typesToAutowire as $typeToAutowire) { 26 | if (! is_a((string) $definition->getClass(), $typeToAutowire, true)) { 27 | continue; 28 | } 29 | 30 | $definition->setAutowired(true); 31 | continue 2; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Diff/DifferFactory.php: -------------------------------------------------------------------------------- 1 | create(); 23 | 24 | return new Differ($unifiedDiffOutputBuilder); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php: -------------------------------------------------------------------------------- 1 | privatesAccessor->setPrivateProperty($unifiedDiffOutputBuilder, 'contextLines', 10000); 28 | return $unifiedDiffOutputBuilder; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php: -------------------------------------------------------------------------------- 1 | $types 14 | */ 15 | public function isInstanceOf(object | string $object, array $types): bool 16 | { 17 | foreach ($types as $type) { 18 | if (is_a($object, $type, true)) { 19 | return true; 20 | } 21 | } 22 | 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Reflection/ClassLikeExistenceChecker.php: -------------------------------------------------------------------------------- 1 | doesClassLikeExist($classLikeName)) { 43 | return false; 44 | } 45 | 46 | // already known values 47 | if (in_array($classLikeName, $this->sensitiveExistingClasses, true)) { 48 | return true; 49 | } 50 | 51 | if (in_array($classLikeName, $this->sensitiveNonExistingClasses, true)) { 52 | return false; 53 | } 54 | 55 | $reflectionClass = new ReflectionClass($classLikeName); 56 | if ($classLikeName !== $reflectionClass->getName()) { 57 | $this->sensitiveNonExistingClasses[] = $classLikeName; 58 | return false; 59 | } 60 | 61 | $this->sensitiveExistingClasses[] = $classLikeName; 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Reflection/PrivatesCaller.php: -------------------------------------------------------------------------------- 1 | newInstanceWithoutConstructor(); 24 | } 25 | 26 | $reflectionMethod = $this->createAccessibleMethodReflection($object, $methodName); 27 | 28 | return $reflectionMethod->invokeArgs($object, $arguments); 29 | } 30 | 31 | /** 32 | * @api 33 | */ 34 | public function callPrivateMethodWithReference(object | string $object, string $methodName, mixed $argument): mixed 35 | { 36 | if (is_string($object)) { 37 | $reflectionClass = new ReflectionClass($object); 38 | $object = $reflectionClass->newInstanceWithoutConstructor(); 39 | } 40 | 41 | $reflectionMethod = $this->createAccessibleMethodReflection($object, $methodName); 42 | $reflectionMethod->invokeArgs($object, [&$argument]); 43 | 44 | return $argument; 45 | } 46 | 47 | private function createAccessibleMethodReflection(object $object, string $methodName): ReflectionMethod 48 | { 49 | return new ReflectionMethod($object::class, $methodName); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Strings/StringFormatConverter.php: -------------------------------------------------------------------------------- 1 | camelCaseToGlue($input, '_'); 33 | } 34 | 35 | public function camelCaseToDashed(string $input): string 36 | { 37 | return $this->camelCaseToGlue($input, '-'); 38 | } 39 | 40 | /** 41 | * @param array $items 42 | * @return array 43 | */ 44 | public function camelCaseToUnderscoreInArrayKeys(array $items): array 45 | { 46 | foreach ($items as $key => $value) { 47 | if (! is_string($key)) { 48 | continue; 49 | } 50 | 51 | $newKey = $this->camelCaseToUnderscore($key); 52 | if ($key === $newKey) { 53 | continue; 54 | } 55 | 56 | $items[$newKey] = $value; 57 | unset($items[$key]); 58 | } 59 | 60 | return $items; 61 | } 62 | 63 | private function camelCaseToGlue(string $input, string $glue): string 64 | { 65 | $matches = Strings::matchAll($input, self::BIG_LETTER_REGEX); 66 | 67 | $parts = []; 68 | foreach ($matches as $match) { 69 | $parts[] = $match[0] === strtoupper((string) $match[0]) ? strtolower($match[0]) : lcfirst( 70 | (string) $match[0] 71 | ); 72 | } 73 | 74 | return implode($glue, $parts); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src-deps/package-builder/src/Strings/StringFormatConverter.phpqIy1Ap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symplify/monorepo-builder/9f2d303b8b8273b201bea3489e5108b8183aa388/src-deps/package-builder/src/Strings/StringFormatConverter.phpqIy1Ap -------------------------------------------------------------------------------- /src-deps/package-builder/src/ValueObject/ConsoleColorDiffConfig.php: -------------------------------------------------------------------------------- 1 | =8.2", 7 | "nette/utils": "^4.0.5", 8 | "symfony/filesystem": "^7.0", 9 | "symfony/finder": "^7.0", 10 | "symplify/easy-testing": "*" 11 | }, 12 | "require-dev": { 13 | "phpunit/phpunit": "^11.0", 14 | "php-parallel-lint/php-parallel-lint": "^1.3", 15 | "phpstan/extension-installer": "^1.2", 16 | "symplify/easy-ci": "^11.1", 17 | "symplify/phpstan-extensions": "^11.1", 18 | "symplify/phpstan-rules": "^12.4.9", 19 | "symplify/symplify-kernel": "*", 20 | "tomasvotruba/class-leak": "^2.0.5", 21 | "tomasvotruba/unused-public": "^0.3.0" 22 | }, 23 | "repositories": [ 24 | { 25 | "type": "path", 26 | "url": "../autowire-array-parameter" 27 | }, 28 | { 29 | "type": "path", 30 | "url": "../easy-testing" 31 | }, 32 | { 33 | "type": "path", 34 | "url": "../package-builder" 35 | }, 36 | { 37 | "type": "path", 38 | "url": "../symplify-kernel" 39 | } 40 | ], 41 | "autoload": { 42 | "psr-4": { 43 | "Symplify\\SmartFileSystem\\": "src" 44 | } 45 | }, 46 | "autoload-dev": { 47 | "psr-4": { 48 | "Symplify\\SmartFileSystem\\Tests\\": "tests" 49 | } 50 | }, 51 | "extra": { 52 | "branch-alias": { 53 | "dev-main": "11.2-dev" 54 | } 55 | }, 56 | "scripts": { 57 | "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify" 58 | }, 59 | "minimum-stability": "dev", 60 | "prefer-stable": true, 61 | "config": { 62 | "sort-packages": true, 63 | "platform-check": false, 64 | "allow-plugins": { 65 | "cweagans/composer-patches": true, 66 | "phpstan/extension-installer": true 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src-deps/smart-file-system/src/Exception/DirectoryNotFoundException.php: -------------------------------------------------------------------------------- 1 | ! is_file($path)); 19 | 20 | return array_values($directories); 21 | } 22 | 23 | /** 24 | * @param string[] $filesAndDirectories 25 | * @return string[] 26 | */ 27 | public function filterFiles(array $filesAndDirectories): array 28 | { 29 | $files = array_filter($filesAndDirectories, static fn (string $path): bool => is_file($path)); 30 | 31 | return array_values($files); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src-deps/smart-file-system/src/FileSystemGuard.php: -------------------------------------------------------------------------------- 1 | isFileInfoValid($fileInfo)) { 21 | continue; 22 | } 23 | 24 | /** @var string $realPath */ 25 | $realPath = $fileInfo->getRealPath(); 26 | 27 | $smartFileInfos[] = new SmartFileInfo($realPath); 28 | } 29 | 30 | return $smartFileInfos; 31 | } 32 | 33 | private function isFileInfoValid(SplFileInfo $fileInfo): bool 34 | { 35 | return (bool) $fileInfo->getRealPath(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src-deps/smart-file-system/src/Finder/SmartFinder.php: -------------------------------------------------------------------------------- 1 | fileSystemFilter->filterDirectories($directoriesOrFiles); 30 | 31 | $fileInfos = []; 32 | 33 | if ($directories !== []) { 34 | $finder = new Finder(); 35 | $finder->name('*') 36 | ->in($directories) 37 | ->path($path) 38 | ->files() 39 | ->sortByName(); 40 | 41 | $fileInfos = $this->finderSanitizer->sanitize($finder); 42 | } 43 | 44 | return $fileInfos; 45 | } 46 | 47 | /** 48 | * @param string[] $directoriesOrFiles 49 | * @param string[] $excludedDirectories 50 | * @return SmartFileInfo[] 51 | */ 52 | public function find(array $directoriesOrFiles, string $name, array $excludedDirectories = []): array 53 | { 54 | $directories = $this->fileSystemFilter->filterDirectories($directoriesOrFiles); 55 | 56 | $fileInfos = []; 57 | 58 | if ($directories !== []) { 59 | $finder = new Finder(); 60 | $finder->name($name) 61 | ->in($directories) 62 | ->files() 63 | ->sortByName(); 64 | 65 | if ($excludedDirectories !== []) { 66 | $finder->exclude($excludedDirectories); 67 | } 68 | 69 | $fileInfos = $this->finderSanitizer->sanitize($finder); 70 | } 71 | 72 | $files = $this->fileSystemFilter->filterFiles($directoriesOrFiles); 73 | foreach ($files as $file) { 74 | $fileInfos[] = new SmartFileInfo($file); 75 | } 76 | 77 | return $fileInfos; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src-deps/smart-file-system/src/Json/JsonFileSystem.php: -------------------------------------------------------------------------------- 1 | fileSystemGuard->ensureFileExists($filePath, __METHOD__); 30 | 31 | $fileContent = $this->smartFileSystem->readFile($filePath); 32 | return Json::decode($fileContent, Json::FORCE_ARRAY); 33 | } 34 | 35 | /** 36 | * @param array $jsonArray 37 | */ 38 | public function writeJsonToFilePath(array $jsonArray, string $filePath): void 39 | { 40 | $jsonContent = Json::encode($jsonArray, Json::PRETTY) . PHP_EOL; 41 | $this->smartFileSystem->dumpFile($filePath, $jsonContent); 42 | } 43 | 44 | /** 45 | * @param array $newJsonArray 46 | */ 47 | public function mergeArrayToJsonFile(string $filePath, array $newJsonArray): void 48 | { 49 | $jsonArray = $this->loadFilePathToJson($filePath); 50 | 51 | $newComposerJsonArray = Arrays::mergeTree($jsonArray, $newJsonArray); 52 | 53 | $this->writeJsonToFilePath($newComposerJsonArray, $filePath); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src-deps/smart-file-system/src/SmartFileSystem.php: -------------------------------------------------------------------------------- 1 | getLastError()); 27 | throw new IOException($message, 0, null, $fileName); 28 | } 29 | 30 | return $source; 31 | } 32 | 33 | /** 34 | * Converts given HTML code to plain text 35 | * 36 | * @source https://github.com/nette/utils/blob/e7bd59f1dd860d25dbbb1ac720dddd0fa1388f4c/src/Utils/Html.php#L325-L331 37 | */ 38 | private function htmlToText(string $html): string 39 | { 40 | $content = strip_tags($html); 41 | return html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8'); 42 | } 43 | 44 | /** 45 | * Returns the last PHP error as plain string. 46 | * 47 | * @source https://github.com/nette/utils/blob/ab8eea12b8aacc7ea5bdafa49b711c2988447994/src/Utils/Helpers.php#L31-L40 48 | */ 49 | private function getLastError(): string 50 | { 51 | $message = error_get_last()['message'] ?? ''; 52 | $htmlMessage = ini_get('html_errors') ? $this->htmlToText($message) : $message; 53 | 54 | return Strings::replace($htmlMessage, self::BEFORE_COLLON_REGEX, ''); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/.github/FUNDING.yaml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | github: tomasvotruba 3 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/.github/workflows/code_analysis.yaml: -------------------------------------------------------------------------------- 1 | name: Code Analysis 2 | 3 | on: 4 | pull_request: null 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | code_analysis: 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | actions: 15 | - 16 | name: 'PHPStan' 17 | run: composer phpstan --ansi 18 | 19 | - 20 | name: 'Composer Validate' 21 | run: composer validate --ansi 22 | 23 | - 24 | name: 'Rector' 25 | run: composer rector --ansi 26 | 27 | - 28 | name: 'Coding Standard' 29 | run: composer fix-cs --ansi 30 | 31 | - 32 | name: 'Tests' 33 | run: vendor/bin/phpunit 34 | 35 | - 36 | name: 'PHP Linter' 37 | run: vendor/bin/parallel-lint src tests 38 | 39 | - 40 | name: 'Check Commented Code' 41 | run: vendor/bin/easy-ci check-commented-code src tests --ansi 42 | 43 | - 44 | name: 'Check Active Classes' 45 | run: vendor/bin/easy-ci check-active-class src --ansi 46 | 47 | name: ${{ matrix.actions.name }} 48 | runs-on: ubuntu-latest 49 | 50 | steps: 51 | - uses: actions/checkout@v3 52 | # see https://github.com/shivammathur/setup-php 53 | - uses: shivammathur/setup-php@v2 54 | with: 55 | php-version: 8.1 56 | coverage: none 57 | 58 | # composer install cache - https://github.com/ramsey/composer-install 59 | - uses: "ramsey/composer-install@v2" 60 | 61 | - run: ${{ matrix.actions.run }} 62 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | --------------- 3 | 4 | Copyright (c) 2017 Tomas Votruba (https://tomasvotruba.com) 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symplify/symplify-kernel", 3 | "description": "Internal Kernel for Symplify packages", 4 | "license": "MIT", 5 | "require": { 6 | "php": ">=8.2", 7 | "symfony/console": "^7.0", 8 | "symfony/dependency-injection": "^7.0", 9 | "symfony/http-kernel": "^7.0", 10 | "symplify/autowire-array-parameter": "*", 11 | "symplify/package-builder": "*", 12 | "symplify/smart-file-system": "*", 13 | "webmozart/assert": "^1.11" 14 | }, 15 | "require-dev": { 16 | "phpunit/phpunit": "^11.0", 17 | "php-parallel-lint/php-parallel-lint": "^1.3", 18 | "phpstan/extension-installer": "^1.2", 19 | "symplify/easy-ci": "^11.1", 20 | "symplify/phpstan-extensions": "^11.1", 21 | "tomasvotruba/class-leak": "^2.0.5", 22 | "tomasvotruba/unused-public": "^0.3.0" 23 | }, 24 | "repositories": [ 25 | { 26 | "type": "path", 27 | "url": "../autowire-array-parameter" 28 | }, 29 | { 30 | "type": "path", 31 | "url": "../easy-testing" 32 | }, 33 | { 34 | "type": "path", 35 | "url": "../package-builder" 36 | }, 37 | { 38 | "type": "path", 39 | "url": "../smart-file-system" 40 | } 41 | ], 42 | "autoload": { 43 | "psr-4": { 44 | "Symplify\\SymplifyKernel\\": "src" 45 | } 46 | }, 47 | "autoload-dev": { 48 | "psr-4": { 49 | "Symplify\\SymplifyKernel\\Tests\\": "tests" 50 | } 51 | }, 52 | "extra": { 53 | "branch-alias": { 54 | "dev-main": "11.2-dev" 55 | } 56 | }, 57 | "minimum-stability": "dev", 58 | "prefer-stable": true, 59 | "scripts": { 60 | "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify" 61 | }, 62 | "config": { 63 | "sort-packages": true, 64 | "platform-check": false, 65 | "allow-plugins": { 66 | "cweagans/composer-patches": true, 67 | "phpstan/extension-installer": true 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/config/common-config.php: -------------------------------------------------------------------------------- 1 | services(); 19 | 20 | $services->defaults() 21 | ->public() 22 | ->autowire(); 23 | 24 | // symfony style 25 | $services->set(SymfonyStyleFactory::class); 26 | $services->set(SymfonyStyle::class) 27 | ->factory([service(SymfonyStyleFactory::class), 'create']); 28 | 29 | // filesystem 30 | $services->set(FinderSanitizer::class); 31 | $services->set(SmartFileSystem::class); 32 | $services->set(SmartFinder::class); 33 | $services->set(FileSystemGuard::class); 34 | $services->set(FileSystemFilter::class); 35 | 36 | $services->set(ParameterProvider::class) 37 | ->args([service('service_container')]); 38 | 39 | $services->set(PrivatesAccessor::class); 40 | }; 41 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/easy-ci.php: -------------------------------------------------------------------------------- 1 | getExtensions()); 19 | 20 | foreach ($extensionNames as $extensionName) { 21 | $containerBuilder->loadFromExtension($extensionName, []); 22 | } 23 | 24 | parent::process($containerBuilder); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/src/Exception/BootException.php: -------------------------------------------------------------------------------- 1 | create($configFiles, $compilerPasses, $extensions); 39 | $containerBuilder->compile(); 40 | 41 | $this->container = $containerBuilder; 42 | 43 | return $containerBuilder; 44 | } 45 | 46 | public function getContainer(): ContainerInterface 47 | { 48 | if (! $this->container instanceof Container) { 49 | throw new ShouldNotHappenException(); 50 | } 51 | 52 | return $this->container; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src-deps/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php: -------------------------------------------------------------------------------- 1 | setName('bump-interdependency'); 33 | $this->setDescription('Bump dependency of split packages on each other'); 34 | $this->addArgument( 35 | self::VERSION_ARGUMENT, 36 | InputArgument::REQUIRED, 37 | 'New version of inter-dependencies, e.g. "^4.4.2"' 38 | ); 39 | } 40 | 41 | protected function execute(InputInterface $input, OutputInterface $output): int 42 | { 43 | $this->sourcesPresenceValidator->validateRootComposerJsonName(); 44 | 45 | /** @var string $version */ 46 | $version = $input->getArgument(self::VERSION_ARGUMENT); 47 | 48 | $packageNames = $this->composerJsonProvider->getPackageNames(); 49 | 50 | $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( 51 | $this->composerJsonProvider->getPackagesComposerFileInfos(), 52 | $packageNames, 53 | $version 54 | ); 55 | 56 | $successMessage = sprintf('Inter-dependencies of packages were updated to "%s".', $version); 57 | $this->symfonyStyle->success($successMessage); 58 | 59 | return self::SUCCESS; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Command/PackageAliasCommand.php: -------------------------------------------------------------------------------- 1 | setName('package-alias'); 27 | $this->setDescription('Updates branch alias in "composer.json" all found packages'); 28 | } 29 | 30 | protected function execute(InputInterface $input, OutputInterface $output): int 31 | { 32 | $composerPackageFiles = $this->packageComposerFinder->getPackageComposerFiles(); 33 | if ($composerPackageFiles === []) { 34 | $this->symfonyStyle->error('No "composer.json" were found in packages.'); 35 | return self::FAILURE; 36 | } 37 | 38 | $expectedAlias = $this->expectedAliasResolver->resolve(); 39 | 40 | $this->devMasterAliasUpdater->updateFileInfosWithAlias($composerPackageFiles, $expectedAlias); 41 | 42 | $message = sprintf('Alias was updated to "%s" in all packages.', $expectedAlias); 43 | $this->symfonyStyle->success($message); 44 | 45 | return self::SUCCESS; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Command/ValidateCommand.php: -------------------------------------------------------------------------------- 1 | setName('validate'); 29 | $this->setDescription('Validates synchronized versions in "composer.json" in all found packages.'); 30 | } 31 | 32 | protected function execute(InputInterface $input, OutputInterface $output): int 33 | { 34 | $this->sourcesPresenceValidator->validatePackageComposerJsons(); 35 | 36 | $conflictingPackageVersions = $this->versionValidator->findConflictingPackageVersionsInFileInfos( 37 | $this->composerJsonProvider->getRootAndPackageFileInfos() 38 | ); 39 | 40 | if ($conflictingPackageVersions === []) { 41 | $this->symfonyStyle->success('All packages "composer.json" files use same package versions.'); 42 | 43 | return self::SUCCESS; 44 | } 45 | 46 | $this->conflictingPackageVersionsReporter->report($conflictingPackageVersions); 47 | 48 | return self::FAILURE; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Console/MonorepoBuilderApplication.php: -------------------------------------------------------------------------------- 1 | addCommands($commands); 18 | parent::__construct(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Contract/Git/TagResolverInterface.php: -------------------------------------------------------------------------------- 1 | branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter( 39 | Option::DEFAULT_BRANCH_NAME 40 | ); 41 | } 42 | 43 | /** 44 | * @param SmartFileInfo[] $fileInfos 45 | */ 46 | public function updateFileInfosWithAlias(array $fileInfos, string $alias): void 47 | { 48 | foreach ($fileInfos as $fileInfo) { 49 | $json = $this->jsonFileManager->loadFromFileInfo($fileInfo); 50 | if ($this->shouldSkip($json, $alias)) { 51 | continue; 52 | } 53 | 54 | $json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget] = $alias; 55 | 56 | $this->jsonFileManager->printJsonToFileInfo($json, $fileInfo); 57 | } 58 | } 59 | 60 | /** 61 | * @param mixed[] $json 62 | */ 63 | private function shouldSkip(array $json, string $alias): bool 64 | { 65 | // update only when already present 66 | if (! isset($json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget])) { 67 | return true; 68 | } 69 | 70 | $currentAlias = $json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget]; 71 | 72 | return $currentAlias === $alias; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Exception/ConfigurationException.php: -------------------------------------------------------------------------------- 1 | run(); 21 | 22 | $output = $process->getOutput(); 23 | 24 | return $this->versionUtils->getNextAliasFormat($output); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Git/MostRecentTagResolver.php: -------------------------------------------------------------------------------- 1 | parseTags($this->processRunner->run(self::COMMAND, $gitDirectory)); 31 | 32 | /** @var string $theMostRecentTag */ 33 | $theMostRecentTag = (string) array_pop($tagList); 34 | 35 | if ($theMostRecentTag === '') { 36 | return null; 37 | } 38 | 39 | return $theMostRecentTag; 40 | } 41 | 42 | /** 43 | * @return string[] 44 | */ 45 | private function parseTags(string $commandResult): array 46 | { 47 | $tags = trim($commandResult); 48 | 49 | // Remove all "\r" chars in case the CLI env like the Windows OS. 50 | // Otherwise (ConEmu, git bash, mingw cli, e.g.), leave as is. 51 | $normalizedTags = str_replace("\r", '', $tags); 52 | 53 | return explode("\n", $normalizedTags); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Kernel/MonorepoBuilderKernel.php: -------------------------------------------------------------------------------- 1 | create($configFiles, $compilerPasses, []); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Package/PackageNamesProvider.php: -------------------------------------------------------------------------------- 1 | names !== []) { 30 | return $this->names; 31 | } 32 | 33 | $packagesFileInfos = $this->composerJsonProvider->getPackagesComposerFileInfos(); 34 | foreach ($packagesFileInfos as $packageFileInfo) { 35 | $name = $this->extractNameFromFileInfo($packageFileInfo); 36 | if ($name !== null) { 37 | $this->names[] = $name; 38 | } 39 | } 40 | 41 | return $this->names; 42 | } 43 | 44 | private function extractNameFromFileInfo(SmartFileInfo $smartFileInfo): ?string 45 | { 46 | $json = $this->jsonFileManager->loadFromFileInfo($smartFileInfo); 47 | 48 | return $json['name'] ?? null; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Utils/RelativeFilePathHelper.php: -------------------------------------------------------------------------------- 1 | makePathRelative((string) \realpath($filePath), \getcwd()); 15 | return \rtrim($relativeFilePathFromCwd, '/'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Validator/ConflictingPackageVersionsReporter.php: -------------------------------------------------------------------------------- 1 | > $conflictingPackages 19 | */ 20 | public function report(array $conflictingPackages): void 21 | { 22 | foreach ($conflictingPackages as $packageName => $filesToVersions) { 23 | $message = sprintf('Package "%s" has incompatible version', $packageName); 24 | $this->symfonyStyle->title($message); 25 | 26 | $tableRows = $this->createTableRows($filesToVersions); 27 | $this->symfonyStyle->table(['File', 'Version'], $tableRows); 28 | } 29 | 30 | $this->symfonyStyle->error('Found conflicting package versions, fix them first.'); 31 | } 32 | 33 | /** 34 | * @param array $filesToVersions 35 | * @return array 36 | */ 37 | private function createTableRows(array $filesToVersions): array 38 | { 39 | $tableRows = []; 40 | 41 | foreach ($filesToVersions as $file => $version) { 42 | $tableRows[] = [RelativeFilePathHelper::resolveFromCwd($file), $version]; 43 | } 44 | 45 | return $tableRows; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Validator/SourcesPresenceValidator.php: -------------------------------------------------------------------------------- 1 | packageDirectories = $parameterProvider->provideArrayParameter(Option::PACKAGE_DIRECTORIES); 24 | } 25 | 26 | public function validatePackageComposerJsons(): void 27 | { 28 | $composerPackageFiles = $this->composerJsonProvider->getPackagesComposerFileInfos(); 29 | if ($composerPackageFiles !== []) { 30 | return; 31 | } 32 | 33 | throw new InvalidComposerJsonSetupException(sprintf( 34 | 'No package "composer.json" was found in package directories: "%s". Add "composer.json" or configure another directory in "parameters > package_directories"', 35 | implode('", "', $this->packageDirectories) 36 | )); 37 | } 38 | 39 | public function validateRootComposerJsonName(): void 40 | { 41 | $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); 42 | if ($rootComposerJson->getName() !== null) { 43 | return; 44 | } 45 | 46 | throw new InvalidComposerJsonSetupException('Complete "name" to your root "composer.json".'); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/ValueObject/File.php: -------------------------------------------------------------------------------- 1 | packageDirectories([__DIR__ . '/packages']); 9 | }; 10 | -------------------------------------------------------------------------------- /templates/monorepo/packages/first-package/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "your-monorepo/first-package", 3 | "require": { 4 | "php": "^7.2", 5 | "symfony/http-kernel": "^5.0" 6 | }, 7 | "autoload": { 8 | "psr-4": { 9 | "YourMonorepo\\FirstPackage\\": "src" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /templates/monorepo/packages/first-package/src/FirstClass.php: -------------------------------------------------------------------------------- 1 |