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
-[](https://travis-ci.org/drupal-composer/drupal-project)
+[](https://github.com/drupal-composer/drupal-project/actions/workflows/ci.yml)
+
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);
}
}