diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..686c443cec --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# Drupal editor configuration normalization +# @see http://editorconfig.org/ + +# 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 = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[composer.{json,lock}] +indent_size = 4 diff --git a/.env.example b/.env.example index 60581237b1..4d04ef831b 100644 --- a/.env.example +++ b/.env.example @@ -2,18 +2,18 @@ # Copy and rename this file to .env at root of this project. # -# A common use case is to supply database creds via the environment. Edit settings.php +# A common use case is to supply database credentials via the environment. Edit settings.php # like so: # # $databases['default']['default'] = [ -# 'database' => getenv('MYSQL_DATABASE'), +# 'database' => $_ENV['MYSQL_DATABASE'], # 'driver' => 'mysql', -# 'host' => getenv('MYSQL_HOSTNAME'), +# 'host' => $_ENV['MYSQL_HOSTNAME'], # 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', -# 'password' => getenv('MYSQL_PASSWORD'), -# 'port' => getenv('MYSQL_PORT'), +# 'password' => $_ENV['MYSQL_PASSWORD'], +# 'port' => $_ENV['MYSQL_PORT'], # 'prefix' => '', -# 'username' => getenv('MYSQL_USER'), +# 'username' => $_ENV['MYSQL_USER'], # ]; # # Uncomment and populate as needed. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..3cc303fda9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,122 @@ +name: CI + +on: + push: + pull_request: + types: + - opened + - synchronize + - reopened + +env: + COMPOSER_MEMORY_LIMIT: -1 + SIMPLETEST_DB: sqlite://tmp/site.sqlite + SIMPLETEST_BASE_URL: "http://127.0.0.1:8080/" + +jobs: + build: + runs-on: 'ubuntu-20.04' + strategy: + fail-fast: false + + matrix: + php-versions: ['8.1', '8.2'] + drupal-release: ['stable', 'beta', 'dev'] + composer-channel: ['stable', 'snapshot'] + # Drupal 10.x-dev tests fail on PHP 8.3. + # @see https://www.drupal.org/project/drupal/issues/3375693 + include: + - php-versions: '8.3' + drupal-release: 'stable' + composer-channel: 'stable' + - php-versions: '8.3' + drupal-release: 'stable' + composer-channel: 'snapshot' + + steps: + - name: Dump matrix context + env: + MATRIX_CONTEXT: ${{ toJSON(matrix) }} + run: echo "$MATRIX_CONTEXT" + + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: gd, pdo_sqlite + + - name: Update Composer + run: composer --verbose self-update --${{ matrix.composer-channel }} + + - name: Show Composer version + run: composer --version + + - name: Validate composer.json + run: composer --verbose validate + + - name: Install dependencies + run: composer --verbose install + + - name: Validate composer.json structure + run: composer normalize --dry-run + + - name: Require bower-asset + run: | + test ! -d web/libraries/dropzone + composer require bower-asset/dropzone + test -d web/libraries/dropzone + + # @see https://www.drupal.org/node/3176567 + - name: Install testing dependency + if: ${{ matrix.php-versions == '8.1' }} + run: composer require --dev phpspec/prophecy-phpunit:^2 + + - name: Override Drupal version to dev for testing dev releases + if: matrix.drupal-release == 'dev' || matrix.drupal-release == 'beta' + run: | + composer config minimum-stability ${{ matrix.drupal-release }} + composer config prefer-stable false + composer --verbose require --no-update drupal/core-composer-scaffold:^10@${{ matrix.drupal-release }} + composer --verbose require --no-update drupal/core-recommended:^10@${{ matrix.drupal-release }} + composer --verbose require --no-update --dev drupal/core-dev:^10@${{ matrix.drupal-release }} + composer --verbose update + + - name: Install site + run: ./vendor/bin/drush site-install --verbose --yes --db-url=sqlite://tmp/site.sqlite + + - name: Show site information + run: ./vendor/bin/drush status + + - name: Start server + run: | + ./vendor/bin/drush runserver "$SIMPLETEST_BASE_URL" & + until curl -s "$SIMPLETEST_BASE_URL"; do true; done > /dev/null + + - name: Run a single unit test to verify the testing setup + run: ./vendor/bin/phpunit -c ./web/core ./web/core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php + + # Using outdated Composer version to test the Composer version constraint. + test-composer: + runs-on: ubuntu-latest + + steps: + + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: gd, pdo_sqlite + tools: composer:v2.2 + + - name: Show Composer version + run: composer --version + + - name: Install dependencies + # This command should fail because of the Composer version constraint. + run: composer --verbose install && exit 1 || exit 0 diff --git a/.gitignore b/.gitignore index 50d278d8f4..4669354007 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ -# Ignore directories generated by Composer +# To ignore OS temporary files use global .gitignore +# https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer + +# Ignore directories generated by Composer. /drush/contrib/ /vendor/ /web/core/ @@ -7,18 +10,22 @@ /web/profiles/contrib/ /web/libraries/ -# Ignore sensitive information +# Ignore sensitive information. /web/sites/*/settings.php -/web/sites/*/settings.local.php -# Ignore Drupal's file directory +# Ignore Drupal's file directory. /web/sites/*/files/ # Ignore SimpleTest multi-site environment. /web/sites/simpletest -# Ignore files generated by PhpStorm -/.idea/ - -# Ignore .env files as they are personal +# Ignore .env files as they could contain sensitive information. /.env + +# Manage .gitattributes with Drupal scaffold for cross-platform compatibility. +# Remove the line below and commit the file for more granular control. +/.gitattributes + +# Manage all .gitignore files with Drupal scaffold. +# Remove the line below and commit the files for more granular control. +**/.gitignore diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ac51e49242..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: php -dist: trusty -sudo: false - -php: - - 7.0 - - 7.1 - - 7.2 - - 7.3 - -env: - global: - - SIMPLETEST_DB=sqlite://tmp/site.sqlite - - SIMPLETEST_BASE_URL="http://127.0.0.1:8080/" - matrix: - - RELEASE=stable COMPOSER_CHANNEL=stable - - RELEASE=dev COMPOSER_CHANNEL=stable - - RELEASE=stable COMPOSER_CHANNEL=snapshot - -before_install: - - echo 'sendmail_path = /bin/true' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - - phpenv config-rm xdebug.ini - - composer --verbose self-update --$COMPOSER_CHANNEL - - composer --version - -install: - - composer --verbose validate - - composer --verbose install - -script: - - if [[ $RELEASE = dev ]]; then composer --verbose remove --no-update drupal/console; fi; - - if [[ $RELEASE = dev ]]; then composer --verbose require --no-update drupal/core:8.8.x-dev; composer --verbose require --no-update --dev drupal/core-dev:8.8.x-dev; fi; - - if [[ $RELEASE = dev ]]; then composer --verbose update; fi; - - ./vendor/bin/drush site-install --verbose --yes --db-url=sqlite://tmp/site.sqlite - - ./vendor/bin/drush runserver $SIMPLETEST_BASE_URL & - - until curl -s $SIMPLETEST_BASE_URL; do true; done > /dev/null - # Run a single unit test to verfiy the testing setup. - - ./vendor/bin/phpunit -c ./web/core ./web/core/modules/system/tests/src/Unit/SystemRequirementsTest.php - - ./vendor/bin/drush - - if [[ $RELEASE = stable ]]; then ./vendor/bin/drupal; fi; diff --git a/README.md b/README.md index 2c40e4384f..2677db9623 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,159 @@ # Composer template for Drupal projects -[![Build Status](https://travis-ci.org/drupal-composer/drupal-project.svg?branch=8.x)](https://travis-ci.org/drupal-composer/drupal-project) +[![CI](https://github.com/drupal-composer/drupal-project/actions/workflows/ci.yml/badge.svg?branch=10.x)](https://github.com/drupal-composer/drupal-project/actions/workflows/ci.yml) +![LICENSE](https://img.shields.io/github/license/drupal-composer/drupal-project) This project template provides a starter kit for managing your site dependencies with [Composer](https://getcomposer.org/). -If you want to know how to use it as replacement for -[Drush Make](https://github.com/drush-ops/drush/blob/8.x/docs/make.md) visit -the [Documentation on drupal.org](https://www.drupal.org/node/2471553). +> [!IMPORTANT] +> [Drupal 11 branch](https://github.com/drupal-composer/drupal-project/tree/11.x) is available! -## Usage +## What does the template do? -First you need to [install composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx). +* Drupal will be installed in the `web` directory. +* Generated composer autoloader `vendor/autoload.php` is used instead of + `web/vendor/autoload.php` provided by Drupal core. +* Modules (packages of type `drupal-module`) will be placed in `web/modules/contrib` directory. +* Themes (packages of type `drupal-theme`) will be placed in `web/themes/contrib` directory. +* Profiles (packages of type `drupal-profile`) will be placed in `web/profiles/contrib` directory. +* Creates default writable versions of `settings.php` and `services.yml`. +* Creates `web/sites/default/files` directory. +* Drush is installed for use as `vendor/bin/drush`. +* Provides an [example](.env.example) of the `.env` file. -> Note: The instructions below refer to the [global composer installation](https://getcomposer.org/doc/00-intro.md#globally). +## Installing + +> [!NOTE] +> The instructions below refer to the [global Composer installation](https://getcomposer.org/doc/00-intro.md#globally). You might need to replace `composer` with `php composer.phar` (or similar) for your setup. -After that you can create the project: +Create your project: +```bash +composer create-project drupal-composer/drupal-project:10.x-dev some-dir --no-interaction ``` -composer create-project drupal-composer/drupal-project:8.x-dev some-dir --no-interaction + +The `composer create-project` command passes ownership of all files to the +project that is created. You should create a new Git repository, and commit +all files not excluded by the `.gitignore` file. + +## Usage + +### Adding new dependencies + +Use `composer require` to include and download dependencies for your project. + +```bash +cd some-dir +composer require drupal/devel ``` -With `composer require ...` you can download new dependencies to your -installation. +By default, this project is set to install only stable releases of dependencies, +as specified by `"minimum-stability": "stable"` in `composer.json`. If you need +to use non-stable releases (e.g., `alpha`, `beta`, `RC`), you can modify the +version constraint to allow for such versions. For instance, to require a beta +version of a module: +```bash +composer require drupal/devel:1.0.0-beta1 ``` -cd some-dir -composer require drupal/devel:~1.0 + +Alternatively, you can globally adjust the stability settings by modifying +`composer.json` to include the desired stability level and explicitly allow it: + +```json +{ + "minimum-stability": "beta", + "prefer-stable": true +} ``` -The `composer create-project` command passes ownership of all files to the -project that is created. You should create a new git repository, and commit -all files not excluded by the .gitignore file. +This configuration ensures that stable releases are preferred, but allows the +installation of non-stable packages when necessary. -## What does the template do? +### Adding libraries -When installing the given `composer.json` some tasks are taken care of: +You can manage front-end asset libraries with Composer thanks to the +[asset-packagist repository](https://asset-packagist.org/). Composer will detect +and install new versions of a library that meet the stated constraints. -* Drupal will be installed in the `web`-directory. -* Autoloader is implemented to use the generated composer autoloader in `vendor/autoload.php`, - instead of the one provided by Drupal (`web/vendor/autoload.php`). -* Modules (packages of type `drupal-module`) will be placed in `web/modules/contrib/` -* Theme (packages of type `drupal-theme`) will be placed in `web/themes/contrib/` -* Profiles (packages of type `drupal-profile`) will be placed in `web/profiles/contrib/` -* Creates default writable versions of `settings.php` and `services.yml`. -* Creates `web/sites/default/files`-directory. -* Latest version of drush is installed locally for use at `vendor/bin/drush`. -* Latest version of DrupalConsole is installed locally for use at `vendor/bin/drupal`. -* Creates environment variables based on your .env file. See [.env.example](.env.example). +```bash +composer require bower-asset/dropzone +``` + +### Custom installation paths for libraries + +The installation path of a specific library can be controlled by adding it to +the `extra.installer-paths` configuration preceding `web/libraries/{$name}`. +For example, the `chosen` Drupal module expects the `chosen` library to be +located on `web/libraries/chosen`, but `composer require npm-asset/chosen-js` +installs the library into `web/libraries/chosen-js`. The following configuration +overrides installation it into the expected directory: + +```json +{ + "extra": { + "installer-paths": { + "web/libraries/chosen": [ + "npm-asset/chosen-js" + ], + "web/libraries/{$name}": [ + "type:drupal-library", + "type:npm-asset", + "type:bower-asset" + ] + } + } +} +``` + +For more details, see https://asset-packagist.org/site/about -## Updating Drupal Core +### Updating Drupal Core This project will attempt to keep all of your Drupal Core files up-to-date; the project [drupal/core-composer-scaffold](https://github.com/drupal/core-composer-scaffold) -is used to ensure that your scaffold files are updated every time drupal/core is -updated. If you customize any of the "scaffolding" files (commonly .htaccess), +is used to ensure that your scaffold files are updated every time `drupal/core` +is updated. + +If you customize any of the "scaffolding" files (commonly `.htaccess`), you may need to merge conflicts if any of your modified files are updated in a new release of Drupal core. -Follow the steps below to update your core files. +Follow the steps below to update your Drupal core files. -1. Run `composer update drupal/core drupal/core-dev --with-dependencies` to update Drupal Core and its dependencies. +1. Run `composer update "drupal/core-*" --with-dependencies` to update Drupal Core and its dependencies. 2. Run `git diff` to determine if any of the scaffolding files have changed. Review the files for any changes and restore any customizations to `.htaccess` or `robots.txt`. -1. Commit everything all together in a single commit, so `web` will remain in +3. Commit everything all together in a single commit, so `web` will remain in sync with the `core` when checking out branches or running `git bisect`. -1. In the event that there are non-trivial conflicts in step 2, you may wish +4. In the event that there are non-trivial conflicts in step 2, you may wish to perform these steps on a branch, and use `git merge` to combine the updated core files with your customized files. This facilitates the use of a [three-way merge tool such as kdiff3](http://www.gitshah.com/2010/12/how-to-setup-kdiff-as-diff-tool-for-git.html). This setup is not necessary if your changes are simple; keeping all of your modifications at the beginning or end of the file is a good strategy to keep merges easy. -## Generate composer.json from existing project - -With using [the "Composer Generate" drush extension](https://www.drupal.org/project/composer_generate) -you can now generate a basic `composer.json` file from an existing project. Note -that the generated `composer.json` might differ from this project's file. - - -## FAQ +## FAQs ### Should I commit the contrib modules I download? Composer recommends **no**. They provide [argumentation against but also -workrounds if a project decides to do it anyway](https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md). +workarounds if a project decides to do it anyway](https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md). ### Should I commit the scaffolding files? -The [Drupal Composer Scaffold](https://github.com/drupal/core-composer-scaffold) plugin can download the scaffold files (like -index.php, update.php, …) to the web/ directory of your project. If you have not customized those files you could choose -to not check them into your version control system (e.g. git). If that is the case for your project it might be -convenient to automatically run the drupal-scaffold plugin after every install or update of your project. You can -achieve that by registering `@composer drupal:scaffold` as post-install and post-update command in your composer.json: +The [Drupal Composer Scaffold](https://github.com/drupal/core-composer-scaffold) +plugin can download the scaffold files (like `index.php`, `update.php` etc.) to +the `web` directory of your project. If you have not customized those files you +could choose to not check them into your version control system (e.g. git). +If that is the case for your project, it might be convenient to automatically +run the drupal-scaffold plugin after every install or update of your project. +You can achieve that by registering `@composer drupal:scaffold` as `post-install` +and `post-update` command in your `composer.json`: ```json "scripts": { @@ -109,14 +167,16 @@ achieve that by registering `@composer drupal:scaffold` as post-install and post ] }, ``` -### How can I apply patches to downloaded modules? -If you need to apply patches (depending on the project being modified, a pull -request is often a better solution), you can do so with the -[composer-patches](https://github.com/cweagans/composer-patches) plugin. +### How can I apply patches to included dependencies? + +If you need to apply patches, you can do so with the +[composer-patches](https://github.com/cweagans/composer-patches) plugin included +in this project. + +To add a patch to Drupal module `foobar`, insert the `patches` section in the +`extra` section of `composer.json`: -To add a patch to drupal module foobar insert the patches section in the extra -section of composer.json: ```json "extra": { "patches": { @@ -126,20 +186,39 @@ section of composer.json: } } ``` -### How do I switch from packagist.drupal-composer.org to packages.drupal.org? -Follow the instructions in the [documentation on drupal.org](https://www.drupal.org/docs/develop/using-composer/using-packagesdrupalorg). +### How do I specify a PHP version? + +There are 2 places where Composer will be looking for PHP version requirements +when resolving dependencies: +1. The `require.php` version value in `composer.json`. +2. The `config.platform` version value in `composer.json`. + +The purpose of `require.php` is to set the minimum PHP language requirements +for a package. For example, the minimum version required for Drupal 10.0 is +`8.0.2` or above, which can be specified as `>=8`. + +The purpose of `config.platform` is to set the PHP language requirements for the +specific instance of the package running in the current environment. For +example, while the minimum version required for Drupal 10 is `8.0.2` or above, +the actual PHP version on the hosting provider could be `8.1.0`. The value of +this field should provide your exact version of PHP with all 3 parts of the +version. + +#### Which versions to specify in my Drupal site? -### How do I specify a PHP version ? +This project includes `drupal/core` which already has `require.php` added. Your +would inherit that constraint. There is no need to add `require.php` to your +`composer.json`. -This project supports PHP 7.0 as minimum version (see [Drupal 8 PHP requirements](https://www.drupal.org/docs/8/system-requirements/drupal-8-php-requirements)), however it's possible that a `composer update` will upgrade some package that will then require PHP 7+. +`config.platform` is a platform-specific. It is recommended to specify +`config.platform` as a _specific version_ (e.g.`8.1.19`) constraint to ensure +that only the package versions supported by your current environment are used. -To prevent this you can add this code to specify the PHP version you want to use in the `config` section of `composer.json`: ```json "config": { - "sort-packages": true, "platform": { - "php": "7.0.33" + "php": "8.1.19" } }, ``` diff --git a/composer.json b/composer.json index b29500cc0c..6867818862 100644 --- a/composer.json +++ b/composer.json @@ -1,80 +1,130 @@ { "name": "drupal-composer/drupal-project", - "description": "Project template for Drupal 8 projects with composer", - "type": "project", + "description": "Project template for Drupal 10 projects with Composer", "license": "GPL-2.0-or-later", + "type": "project", "authors": [ { "name": "", "role": "" } ], - "repositories": [ - { - "type": "composer", - "url": "https://packages.drupal.org/8" - } - ], "require": { - "php": ">=7.0.8", - "composer/installers": "^1.2", - "cweagans/composer-patches": "^1.6.5", - "drupal/console": "^1.0.2", - "drupal/core": "^8.8.0", - "drupal/core-composer-scaffold": "^8.8.0", - "drush/drush": "^9.7.1 | ^10.0.0", - "vlucas/phpdotenv": "^4.0", - "webflo/drupal-finder": "^1.0.0", - "zaporylie/composer-drupal-optimizations": "^1.0" + "composer/installers": "^2.1", + "cweagans/composer-patches": "^1.7", + "drupal/core-composer-scaffold": "^10.2.0", + "drupal/core-recommended": "^10.2.0", + "drush/drush": "^12.4.3", + "oomphinc/composer-installers-extender": "^2.0", + "vlucas/phpdotenv": "^5.1", + "webflo/drupal-finder": "^1.3" }, "require-dev": { - "drupal/core-dev": "^8.8.0" + "drupal/core-dev": "^10.2.0", + "ergebnis/composer-normalize": "^2.42" }, "conflict": { "drupal/drupal": "*" }, - "minimum-stability": "dev", + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + }, + { + "type": "composer", + "url": "https://asset-packagist.org/" + } + ], + "minimum-stability": "stable", "prefer-stable": true, - "config": { - "sort-packages": true - }, "autoload": { "classmap": [ "scripts/composer/ScriptHandler.php" ], - "files": ["load.environment.php"] + "files": [ + "load.environment.php" + ] + }, + "config": { + "allow-plugins": { + "composer/installers": true, + "cweagans/composer-patches": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "drupal/core-composer-scaffold": true, + "ergebnis/composer-normalize": true, + "oomphinc/composer-installers-extender": true, + "php-http/discovery": true, + "phpstan/extension-installer": true, + "tbachert/spi": true + }, + "discard-changes": true, + "sort-packages": true + }, + "extra": { + "composer-exit-on-patch-failure": true, + "drupal-scaffold": { + "file-mapping": { + "[project-root]/.gitignore": false, + "[web-root]/INSTALL.txt": false, + "[web-root]/README.txt": false + }, + "locations": { + "web-root": "web/" + } + }, + "installer-paths": { + "web/core": [ + "type:drupal-core" + ], + "web/libraries/{$name}": [ + "type:drupal-library", + "type:bower-asset", + "type:npm-asset" + ], + "web/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "web/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "web/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "drush/Commands/contrib/{$name}": [ + "type:drupal-drush" + ], + "web/modules/custom/{$name}": [ + "type:drupal-custom-module" + ], + "web/profiles/custom/{$name}": [ + "type:drupal-custom-profile" + ], + "web/themes/custom/{$name}": [ + "type:drupal-custom-theme" + ] + }, + "installer-types": [ + "bower-asset", + "npm-asset" + ], + "patchLevel": { + "drupal/core": "-p2" + }, + "patches": {} }, "scripts": { "pre-install-cmd": [ "DrupalProject\\composer\\ScriptHandler::checkComposerVersion" ], - "pre-update-cmd": [ - "DrupalProject\\composer\\ScriptHandler::checkComposerVersion" - ], "post-install-cmd": [ "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" ], + "pre-update-cmd": [ + "DrupalProject\\composer\\ScriptHandler::checkComposerVersion" + ], "post-update-cmd": [ "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" ] - }, - "extra": { - "composer-exit-on-patch-failure": true, - "patchLevel": { - "drupal/core": "-p2" - }, - "drupal-scaffold": { - "locations": { - "web-root": "web/" - } - }, - "installer-paths": { - "web/core": ["type:drupal-core"], - "web/libraries/{$name}": ["type:drupal-library"], - "web/modules/contrib/{$name}": ["type:drupal-module"], - "web/profiles/contrib/{$name}": ["type:drupal-profile"], - "web/themes/contrib/{$name}": ["type:drupal-theme"], - "drush/Commands/contrib/{$name}": ["type:drupal-drush"] - } } } diff --git a/drush/Commands/PolicyCommands.php b/drush/Commands/PolicyCommands.php index 290b4e0331..790bbeb210 100644 --- a/drush/Commands/PolicyCommands.php +++ b/drush/Commands/PolicyCommands.php @@ -3,6 +3,10 @@ namespace Drush\Commands; use Consolidation\AnnotatedCommand\CommandData; +use Consolidation\AnnotatedCommand\Hooks\HookManager; +use Drush\Attributes\Hook; +use Drush\Commands\core\RsyncCommands; +use Drush\Commands\sql\SqlSyncCommands; /** * Edit this file to reflect your organization's needs. @@ -13,10 +17,9 @@ class PolicyCommands extends DrushCommands { * Prevent catastrophic braino. Note that this file has to be local to the * machine that initiates the sql:sync command. * - * @hook validate sql:sync - * * @throws \Exception */ + #[Hook(type: HookManager::ARGUMENT_VALIDATOR, target: SqlSyncCommands::SYNC)] public function sqlSyncValidate(CommandData $commandData) { if ($commandData->input()->getArgument('target') == '@prod') { throw new \Exception(dt('Per !file, you may never overwrite the production database.', ['!file' => __FILE__])); @@ -26,10 +29,9 @@ public function sqlSyncValidate(CommandData $commandData) { /** * Limit rsync operations to production site. * - * @hook validate core:rsync - * * @throws \Exception */ + #[Hook(type: HookManager::ARGUMENT_VALIDATOR, target: RsyncCommands::RSYNC)] public function rsyncValidate(CommandData $commandData) { if (preg_match("/^@prod/", $commandData->input()->getArgument('target'))) { throw new \Exception(dt('Per !file, you may never rsync to the production site.', ['!file' => __FILE__])); diff --git a/load.environment.php b/load.environment.php index eef1d28d07..eb5e3a0f8f 100644 --- a/load.environment.php +++ b/load.environment.php @@ -6,10 +6,12 @@ */ use Dotenv\Dotenv; -use Dotenv\Exception\InvalidPathException; /** * Load any .env file. See /.env.example. + * + * Drupal has no official method for loading environment variables and uses + * getenv() in some places. */ -$dotenv = Dotenv::createImmutable(__DIR__); +$dotenv = Dotenv::createUnsafeImmutable(__DIR__); $dotenv->safeLoad(); diff --git a/scripts/composer/ScriptHandler.php b/scripts/composer/ScriptHandler.php index 51026d38a1..0ccdb85642 100644 --- a/scripts/composer/ScriptHandler.php +++ b/scripts/composer/ScriptHandler.php @@ -10,18 +10,23 @@ use Composer\Script\Event; use Composer\Semver\Comparator; use Drupal\Core\Site\Settings; -use DrupalFinder\DrupalFinder; +use Drupal\Core\Site\SettingsEditor; +use DrupalFinder\DrupalFinderComposerRuntime; use Symfony\Component\Filesystem\Filesystem; -use Webmozart\PathUtil\Path; +use Symfony\Component\Filesystem\Path; class ScriptHandler { public static function createRequiredFiles(Event $event) { $fs = new Filesystem(); - $drupalFinder = new DrupalFinder(); - $drupalFinder->locateRoot(getcwd()); + $drupalFinder = new DrupalFinderComposerRuntime(); $drupalRoot = $drupalFinder->getDrupalRoot(); + if (is_null($drupalRoot)) { + $event->getIO()->writeError('Drupal root could not be detected.'); + exit(1); + } + $dirs = [ 'modules', 'profiles', @@ -46,13 +51,13 @@ public static function createRequiredFiles(Event $event) { 'value' => Path::makeRelative($drupalFinder->getComposerRoot() . '/config/sync', $drupalRoot), 'required' => TRUE, ]; - drupal_rewrite_settings($settings, $drupalRoot . '/sites/default/settings.php'); + SettingsEditor::rewrite($drupalRoot . '/sites/default/settings.php', $settings); $fs->chmod($drupalRoot . '/sites/default/settings.php', 0666); $event->getIO()->write("Created a sites/default/settings.php file with chmod 0666"); } // Create the files directory with chmod 0777 - if (!$fs->exists($drupalRoot . '/sites/default/files')) { + if (!$fs->exists($drupalRoot . '/sites/default/files') && !is_link($drupalRoot . '/sites/default/files')) { $oldmask = umask(0); $fs->mkdir($drupalRoot . '/sites/default/files', 0777); umask($oldmask); @@ -91,8 +96,8 @@ public static function checkComposerVersion(Event $event) { if ($version === '@package_version@' || $version === '@package_branch_alias_version@') { $io->writeError('You are running a development version of Composer. If you experience problems, please update Composer to the latest stable version.'); } - elseif (Comparator::lessThan($version, '1.0.0')) { - $io->writeError('Drupal-project requires Composer version 1.0.0 or higher. Please update your Composer before continuing.'); + elseif (Comparator::lessThan($version, '2.3.6')) { + $io->writeError('Drupal-project requires Composer version 2.3.6 or higher. Please update your Composer before continuing.'); exit(1); } }