commit a4f4e1990c6dcf1d32e1e897a761b1cb35acc65a Author: pcm-libraries <> Date: Wed Aug 7 15:04:23 2024 +0000 Initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c9dc060 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[Makefile] +indent_style = tab diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a9040a --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.vscode +/vendor +composer.lock +.phpunit.result.cache +/var +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..bb2d4ed --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,32 @@ +setRules([ + '@Symfony' => true, + + 'binary_operator_spaces' => [ + 'operators' => [ + '=' => 'align_single_space', + '=>' => 'align_single_space', + ], + ], + + 'single_blank_line_at_eof' => true, + 'phpdoc_align' => false, + 'phpdoc_to_comment' => false, + 'strict_comparison' => true, + 'declare_strict_types' => true, + 'single_trait_insert_per_statement' => false, + 'nullable_type_declaration_for_default_null_value' => true, + 'increment_style' => [ + 'style' => 'post', + ], + ]) + ->setFinder( + (new PhpCsFixer\Finder()) + ->in(__DIR__) + ->exclude('var') + ) +; diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..1105963 --- /dev/null +++ b/Containerfile @@ -0,0 +1,6 @@ +FROM php:8.3-alpine + +WORKDIR /code +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer +COPY ./ /code + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2831d9e --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +License diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e8eec65 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +PHP = docker compose run php + +.PHONY: composer_install composer_update static_analysis tests + +composer_install: + @$(PHP) composer install + +composer_update: + @$(PHP) composer update + +static_analysis: + @$(PHP) vendor/bin/psalm + +tests: + @$(PHP) rm -rf var/cache + @$(PHP) vendor/bin/phpunit diff --git a/README.md b/README.md new file mode 100644 index 0000000..28ab80d --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ +# Symfony Bundle Skeleton + +A **WORK IN PROGRESS** skeleton for creating Symfony Bundles. + +This skeleton is a very basic bundle with comments explaining what various bits are doing. + +The bundle is called `PcmExampleBundle` and contains a `Greeting` class with a `greet(): string` method. + +The `greet()` method returns a string welcoming someone who's name you can specify in the bundle configuration file. + + +# Installing dependencies + +You need to run `docker compose run php` before any composer commands. EG: +```sh +docker compose run php composer require symfony/twig-bundle +``` +The Makefile has some common shorthands as usual. + + +# Modifying this bundle + +To change this bundle from `pcm/example-bundle` to something new there are few files you need to change. + +1. **Bundle PHP file and namespace** + + The file at `src/PcmExampleBundle.php` should have it's class name and filename changed. + + If you are creating a bundle called `pcm/epic-login-bundle` the namespace should be `Pcm\EpicLogin` + while the class name should be `PcmEpicLoginBundle`. + + Subsequently, all namespaces should be changed to start with `pcm\epiclogin`. + +2. **composer metadata** + + Update the `name` and `description` fields of the `composer.json` file with appropriate names. + The name should + + You will also need to update the PSR autoload classes with your bundle's class name. + + Optionally edit the authors if required. + +3. **Config files** + + - Chamge 'bundles.php` to use your new bundle class + - Modify `services.yaml` when required + - Update `definition.yaml` to specify your config structure (or remove if no config is required) + +4. **Test files** + + The `TestKernel` needs to return an array containing your bundle class. + + Again, namespaces need changing to whatever is appropriate. + +# PHPUnit testing + +The bundle and it's configuration can be tested with PHPUnit. + +This was a worthwhile section to add. + + +# Installing a development version of the bundle + +If you need to install the bundle to test stuff (EG to see how certain Twig templates look, etc) you can do so +by using a development version of the bundle. + +### Preparing the composer.json file + +First, make sure your Symfony project has the following in it's `composer.json` file: +```json +{ + "minimum-stability": "dev", + "prefer-stable": true, +} +``` + +Next, you need to add the repository to the `composer.json` file, just as you would any other PCM bundle: +```json +{ + "repositories": [ + { + "type": "vcs", + "url": "ssh://example/bundle.git" + }, + ] +} +``` + +### Installing the development bundle + +You can now install the bundle with composer. Because the bundle does not yet have a tagged version we +have to specify that it's a dev bundle alongside a branch to use. For example: +```sh +composer require pcm/example-bundle:dev-develop +``` + +The `dev-develop` part is specifying both that it's a **dev** package and that we want to use the **develop** branch. If you wanted to use the `master` branch you would specify as so: `dev-master`. + +If a flex recipe is present it will prompt you to install it. + +**NOTE** that the "symfony.lock" file will generate an incorrect version number "develop.9999999". This causes issues when uninstalling, so manually change this value to be `dev-develop` or whichever version you installed. + +### Updating the development bundle + +You can make changes to the bundle whilst it's installed. Once you've pushed your changes with git you can run a composer update to retrieve the most recent changes: +```sh +composer update pcm/example-bundle +``` + +### Uninstalling your development bundle + +Make sure that the bundle version is correct in the `symfony.lock` file (see above) before running the usual uninstall command: +```sh +composer remove pcm/example-bundle +``` + +# Creating a flex recipe + +See the flex recipe repo for info on how to do this. diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..a8b7778 --- /dev/null +++ b/compose.yml @@ -0,0 +1,7 @@ +services: + php: + build: + context: . + dockerfile: Containerfile + volumes: + - ./:/code diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..c694ad6 --- /dev/null +++ b/composer.json @@ -0,0 +1,40 @@ +{ + "name": "pcm/example-bundle", + "description": "PCM Example Bundle", + "type": "symfony-bundle", + "license": "MIT", + "version": "dev-develop", + "authors": [ + { + "name": "Bradley Goode", + "email": "bg@pcmsystems.co.uk" + }, + { + "name": "Matt Feeney", + "email": "mf@pcmsystems.co.uk" + } + ], + + "autoload": { + "psr-4": { + "Pcm\\ExampleBundle\\": "src/" + } + }, + + "autoload-dev": { + "psr-4": { + "Pcm\\ExampleBundle\\Tests\\": "tests/" + } + }, + + "require": { + "symfony/dependency-injection": "^7.1", + "symfony/framework-bundle": "^7.1", + "symfony/yaml": "^7.1" + }, + + "require-dev": { + "symfony/test-pack": "^1.1", + "friendsofphp/php-cs-fixer": "^3.61" + } +} diff --git a/config/bundles.php b/config/bundles.php new file mode 100644 index 0000000..ba8705c --- /dev/null +++ b/config/bundles.php @@ -0,0 +1,12 @@ + ['all' => true], +]; + diff --git a/config/definition.php b/config/definition.php new file mode 100644 index 0000000..1304c55 --- /dev/null +++ b/config/definition.php @@ -0,0 +1,16 @@ +rootNode() + ->children() + ->scalarNode('name')->defaultValue('Mr. NoName')->cannotBeEmpty()->end() + ->end() + ; +}; + diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..382ef0b --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,28 @@ +services: + _defaults: + autowire: true + autoconfigure: true + + # Hide the fully qualified Greeting class name from public view + # but give the class an alias. This alias will be made public instead. + # + # Read the documentation to see why we do this: + # https://symfony.com/doc/current/service_container/autowiring.html#service-autowiring-alias + # + Pcm\ExampleBundle\Greeting: + public: false + alias: pcm_example.greeting + + + # Mark the alias we created as public. + pcm_example.greeting: + public: true + class: Pcm\ExampleBundle\Greeting + + + # If we were defining a twig extension, we'd want to add the twig.runtime tag + # so it loads correctly. + # + # Pcm\ExampleBundle\SomeTwigRuntime + # tags: + # - { name: twig.runtime } diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..60cb564 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + + ./src + + + + + + + + + + + ./tests + + + diff --git a/src/Greeting.php b/src/Greeting.php new file mode 100644 index 0000000..7aa7f91 --- /dev/null +++ b/src/Greeting.php @@ -0,0 +1,18 @@ +name); + } +} + diff --git a/src/PcmExampleBundle.php b/src/PcmExampleBundle.php new file mode 100644 index 0000000..fbfdbc3 --- /dev/null +++ b/src/PcmExampleBundle.php @@ -0,0 +1,44 @@ +import('../config/services.yaml'); + + /** + * The "$config" variable contains an array representing the + * configuration and it's values. + * + * We can use it to configure the service container, for example + * by passing in arguments to any services we have defined. + * + * (see services.yaml) + */ + $container->services() + ->get('pcm_example.greeting') + ->arg('$name', $config['name']) + ; + } + + public function configure(DefinitionConfigurator $definition): void + { + /** + * Import the config definition (see definition.php) + */ + $definition->import('../config/definition.php'); + } +} + diff --git a/tests/Config/ConfigurationTest.php b/tests/Config/ConfigurationTest.php new file mode 100644 index 0000000..c180930 --- /dev/null +++ b/tests/Config/ConfigurationTest.php @@ -0,0 +1,45 @@ +configuration = new Configuration(true); + $this->processor = new Processor(); + } + + public function testThrowsIfNameIsEmpty() + { + $config = $this->getValidConfig(); + $config['name'] = ''; + $this->expectException(\Exception::class); + $this->validateConfig($config); + } + + private function validateConfig(array $config): array + { + return $this->processor->processConfiguration($this->configuration, [$config]); + } + + private function getValidConfig(): array + { + return [ + 'name' => 'Boris', + ]; + } +} + diff --git a/tests/TestKernel.php b/tests/TestKernel.php new file mode 100644 index 0000000..11728ac --- /dev/null +++ b/tests/TestKernel.php @@ -0,0 +1,26 @@ +load(__DIR__.'/../config/packages/pcm_example.yaml'); + } +} +