diff --git a/.circleci/config.yml b/.circleci/config.yml index e40092ecd..96631c0c9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,7 +39,7 @@ aliases: #;< SCAFFOLD_DEV - &renovatebot_git_author 'Renovate Self Hosted ' #;> SCAFFOLD_DEV - ##### - &renovatebot_git_author 'RenovateBot Self Hosted ' + ##### - &renovatebot_git_author 'RenovateBot Self Hosted ' # The schedule to run RenovateBot on. Defaults to running twice a day. - &renovatebot_schedule "5 11,23 * * *" #;> RENOVATEBOT diff --git a/.env b/.env index df0538b61..9cacbb462 100644 --- a/.env +++ b/.env @@ -27,7 +27,7 @@ # the project directory and can be overridden with $COMPOSE_PROJECT_NAME. VORTEX_PROJECT=your_site -# Name of the webroot directory with Drupal codebase. +# Name of the web root directory containing a Drupal codebase. VORTEX_WEBROOT=web # The timezone for the containers. @@ -43,11 +43,13 @@ DRUPAL_PROFILE=standard # Drupal theme name. DRUPAL_THEME=your_site_theme -# Stage file proxy origin. Note that HTTP Auth provided by Shield will be -# automatically added to the origin URL. -DRUPAL_STAGE_FILE_PROXY_ORIGIN=https://www.your-site-url.example/ +# Stage file proxy origin. +# +# If using Shield, the HTTP authentication credentials will be automatically +# added to the origin URL. +DRUPAL_STAGE_FILE_PROXY_ORIGIN=https://www.your-site-domain.example/ -# Shield print message. +# Shield message. DRUPAL_SHIELD_PRINT="Restricted access." #;< REDIS @@ -71,13 +73,16 @@ DRUPAL_CLAMAV_MODE=daemon # PROVISION # ################################################################################ -# Variables in this section control how the site is provisioned. +# By "provision", we mean the process of initialising the database (from dump +# or fresh install from profile), running updates, appying configuration +# changes, clearing caches and performing other tasks that prepare the site for +# use. # @see https://vortex.drevops.com/workflows/provision # Set to 1 to install a site from profile instead of the database file dump. VORTEX_PROVISION_USE_PROFILE=0 -# Overwrite existing database if it exists. +# Overwrite a database if it exists. # # Usually set to 0 in deployed environments and can be temporary set to 1 for # a specific deployment. @@ -90,23 +95,42 @@ VORTEX_PROVISION_OVERRIDE_DB=0 # environments and is always skipped in the production environment. VORTEX_PROVISION_SANITIZE_DB_SKIP=0 -# Sanitization email pattern. Sanitization is enabled by default in all -# non-production environments. +# Sanitization email pattern. +# +# Applied if database sanitization is enabled. # @see https://vortex.drevops.com/workflows/build#sanitization -VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@your-site-url.example" +VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@your-site-domain.example" # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 +################################################################################ +# HOSTING # +################################################################################ + +#;< LAGOON +# Lagoon project name. May be different from $VORTEX_PROJECT. +LAGOON_PROJECT=your_site + +# Dedicated branch to identify the production environment. +VORTEX_LAGOON_PRODUCTION_BRANCH=main +#;> LAGOON + +#;< ACQUIA +# Acquia application name. +VORTEX_ACQUIA_APP_NAME= +#;> ACQUIA + ################################################################################ # DATABASE # ################################################################################ # Database service runs a single database within a container. -# See settings.php for database credentials defaults. +# See settings.php for database credentials defaults or run +# `ahoy drush sql:connect`. -# Database can be imported from a file dump into an empty database started from -# the database default image or can exist in a pre-built container image. +# Database can be imported from a *file dump* into an empty database started +# from the database default image or can *exist* in a pre-built container image. # Defaults to importing from a file. # @see https://vortex.drevops.com/workflows/database @@ -124,26 +148,28 @@ VORTEX_DB_FILE=db.sql #;< !PROVISION_USE_PROFILE # Database can be sourced from one of the following locations: # -# - `curl` - directly from URL as a file using CURL. -# - `ftp` - directly from FTP as a file using CURL. +# - `curl` - directly from a URL as a file using CURL. +# - `ftp` - directly from an FTP as a file using CURL. # - `acquia` - from the latest Acquia backup via Cloud API as a file. # - `lagoon` - from Lagoon main environment as a file. # - `container_registry` - from the container registry as a container image. # - `none` - not downloaded, site is freshly installed for every build. - +# # Note that "container_registry" works only for database-in-image # database storage (when $VORTEX_DB_IMAGE variable has a value). VORTEX_DB_DOWNLOAD_SOURCE=curl #;< VORTEX_DB_DOWNLOAD_SOURCE_CURL -# Database dump file sourced from CURL, with optional HTTP Basic Authentication -# credentials embedded into the value. +# Database dump file sourced from CURL. +# +# HTTP Basic Authentication credentials should be embedded into the value. VORTEX_DB_DOWNLOAD_CURL_URL= #;> VORTEX_DB_DOWNLOAD_SOURCE_CURL # Environment to download the database from. +# +# Applies to Acquia and Lagoon environments. VORTEX_DB_DOWNLOAD_ENVIRONMENT=prod -#;> !PROVISION_USE_PROFILE #;< FTP # Database dump file sourced from FTP. @@ -159,17 +185,11 @@ VORTEX_DB_DOWNLOAD_FTP_FILE=db.sql #;> FTP #;< ACQUIA -# Acquia application name to download the database from. -VORTEX_ACQUIA_APP_NAME= - # Acquia database name to download the database from. VORTEX_DB_DOWNLOAD_ACQUIA_DB_NAME=your_site #;> ACQUIA -#;< LAGOON -# Lagoon project name. May be different from $VORTEX_PROJECT. -LAGOON_PROJECT=your_site -#;> LAGOON +#;> !PROVISION_USE_PROFILE #;< DEPLOYMENT ################################################################################ @@ -186,12 +206,6 @@ LAGOON_PROJECT=your_site # # See https://vortex.drevops.com/workflows/deploy VORTEX_DEPLOY_TYPES=artifact - -#;< LAGOON -# Dedicated branch to identify the production environment. -VORTEX_LAGOON_PRODUCTION_BRANCH=main -#;> LAGOON - #;> DEPLOYMENT #;< NOTIFICATIONS @@ -208,30 +222,26 @@ VORTEX_LAGOON_PRODUCTION_BRANCH=main VORTEX_NOTIFY_CHANNELS=email # Email to send notifications from. -VORTEX_NOTIFY_EMAIL_FROM="webmaster@your-site-url.example" +VORTEX_NOTIFY_EMAIL_FROM="webmaster@your-site-domain.example" # Email address(es) to send notifications to. # # Multiple names can be specified as a comma-separated list of email addresses # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" -VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@your-site-url.example" +VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@your-site-domain.example" #;> NOTIFICATIONS #;< DEMO ################################################################################ # DEMO # ################################################################################ - -#------------------------------------------------------------------------------- -# Variables used to override project-specific values for demonstration purposes. -# -# This is to allow to demonstrate how Vortex works without asking users -# to perform any additional steps when trying out Vortex for the first time. -# -# Remove this section from your project when database download integration setup -# is finished. -#------------------------------------------------------------------------------- +# # +# Override project-specific values for demonstration purposes. # +# Used to showcase Vortex without asking users to perform additional steps. # +# Remove this section after completing database download integration. # +# # +################################################################################ #;< VORTEX_DB_DOWNLOAD_SOURCE_CURL # URL of the demo database used for demonstration with CURL database @@ -240,7 +250,7 @@ VORTEX_DB_DOWNLOAD_CURL_URL=https://github.com/drevops/vortex/releases/download/ #;> VORTEX_DB_DOWNLOAD_SOURCE_CURL #;< VORTEX_DB_IMAGE -# The name of the demo database image used for demonstration only for +# The name of the demo database image used for demonstration for # database-in-image data storage. #; The line below will be automatically uncommented for database-in-image #; storage. It is commented out to allow running non-database-in-image diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml index 43376e915..8d326bd11 100644 --- a/.github/workflows/renovate.yml +++ b/.github/workflows/renovate.yml @@ -25,4 +25,4 @@ jobs: RENOVATE_DEPENDENCY_DASHBOARD_TITLE: 'Renovate Dependency Dashboard (self-hosted) by GitHub Actions' RENOVATE_DEPENDENCY_DASHBOARD: ${{ vars.RENOVATE_DEPENDENCY_DASHBOARD || 'false' }} RENOVATE_DRY_RUN: ${{ vars.RENOVATE_DRY_RUN || 'false' }} - RENOVATE_GIT_AUTHOR: ${{ vars.RENOVATE_GIT_AUTHOR || 'Renovate Self Hosted ' }} + RENOVATE_GIT_AUTHOR: ${{ vars.RENOVATE_GIT_AUTHOR || 'Renovate Self Hosted ' }} diff --git a/.lagoon.yml b/.lagoon.yml index 2302c9af9..cd5de244e 100644 --- a/.lagoon.yml +++ b/.lagoon.yml @@ -109,10 +109,10 @@ environments: # By default, Lagoon installs Let's Encrypt certificates for all environments. # routes: # - nginx-php: - # - www.your-site-url.example: + # - www.your-site-domain.example: # tls-acme: 'false' monitoring_urls: - - www.your-site-url.example + - www.your-site-domain.example # Branch name that represents development environment. develop: cronjobs: @@ -124,10 +124,10 @@ environments: # By default, Lagoon installs Let's Encrypt certificates for all environments. # routes: # - nginx-php: - # - dev.your-site-url.example: + # - dev.your-site-domain.example: # tls-acme: 'false' monitoring_urls: - - dev.your-site-url.example + - dev.your-site-domain.example routes: insecure: Redirect diff --git a/.vortex/.ahoy.yml b/.vortex/.ahoy.yml index 255255b0d..55e1af10e 100644 --- a/.vortex/.ahoy.yml +++ b/.vortex/.ahoy.yml @@ -8,7 +8,7 @@ commands: cmd: | [ ! -d ./tests/node_modules ] && npm --prefix tests ci [ ! -d ./docs/node_modules ] && npm --prefix docs ci - [ ! -d ./installer/node_modules ] && composer --working-dir installer install + [ ! -d ./installer/vendor ] && composer --working-dir installer install docs: name: Start documentation server. @@ -28,6 +28,12 @@ commands: [ ! -d ./docs/node_modules ] && npm --prefix docs ci npm --prefix docs run build + build-installer: + name: Build documentation. + cmd: | + [ ! -d ./installer/vendor ] && composer --working-dir installer install + composer --working-dir installer build + lint: name: Lint Vortex project. cmd: | diff --git a/.vortex/docs/.utils/variables/extra/.env.variables.sh b/.vortex/docs/.utils/variables/extra/.env.variables.sh index d291ca9ea..982c12512 100755 --- a/.vortex/docs/.utils/variables/extra/.env.variables.sh +++ b/.vortex/docs/.utils/variables/extra/.env.variables.sh @@ -16,7 +16,7 @@ VORTEX_DB_IMAGE= VORTEX_DB_IMAGE_BASE= # Drupal admin email. May need to be reset if database was sanitized. -DRUPAL_ADMIN_EMAIL="webmaster@your-site-url.example" +DRUPAL_ADMIN_EMAIL="webmaster@your-site-domain.example" # Password replacement used for sanitised database. VORTEX_PROVISION_SANITIZE_DB_PASSWORD="" @@ -42,7 +42,7 @@ DRUPAL_SITE_NAME="${VORTEX_PROJECT}" # Drupal site email. # Used only when installing from profile. -DRUPAL_SITE_EMAIL="webmaster@your-site-url.example" +DRUPAL_SITE_EMAIL="webmaster@your-site-domain.example" # Print output from Composer install. VORTEX_COMPOSER_VERBOSE=1 diff --git a/.vortex/docs/.utils/variables/extra/ci.variables.sh b/.vortex/docs/.utils/variables/extra/ci.variables.sh index 1edce6099..bdd5336e1 100755 --- a/.vortex/docs/.utils/variables/extra/ci.variables.sh +++ b/.vortex/docs/.utils/variables/extra/ci.variables.sh @@ -65,4 +65,4 @@ RENOVATE_DEPENDENCY_DASHBOARD=false RENOVATE_DRY_RUN=false # Commit author for self-hosted Renovate bot. -RENOVATE_GIT_AUTHOR='Renovate Self Hosted ' +RENOVATE_GIT_AUTHOR='Renovate Self Hosted ' diff --git a/.vortex/docs/content/getting-started/features.mdx b/.vortex/docs/content/getting-started/features.mdx index 70c6c826b..dae410389 100644 --- a/.vortex/docs/content/getting-started/features.mdx +++ b/.vortex/docs/content/getting-started/features.mdx @@ -10,7 +10,7 @@ The following list includes āœ… completed and šŸš§ upcoming features. * šŸ’§ Drupal * āœ… Based on [drupal-composer/drupal-project](https://github.com/drupal-composer/drupal-project) - * āœ… [Drupal 10](https://www.drupal.org/project/drupal) + * āœ… [Drupal 11](https://www.drupal.org/project/drupal) * āœ… Configurable webroot * āœ… [Pre-configured settings](https://github.com/drevops/vortex/blob/develop/web/sites/default/settings.php) * āœ… [Custom module scaffold](https://github.com/drevops/vortex/blob/develop/web/modules/custom/ys_core) diff --git a/.vortex/docs/content/workflows/variables.mdx b/.vortex/docs/content/workflows/variables.mdx index dfffd05a4..e5bcf61ed 100644 --- a/.vortex/docs/content/workflows/variables.mdx +++ b/.vortex/docs/content/workflows/variables.mdx @@ -88,7 +88,7 @@ Defined in: `docker-compose.yml`, `scripts/vortex/info.sh` Drupal admin email. May need to be reset if database was sanitized. -Default value: `webmaster@your-site-url.example` +Default value: `webmaster@your-site-domain.example` Defined in: `.env` @@ -162,7 +162,7 @@ Defined in: `.env` ### `DRUPAL_SHIELD_PRINT` -Shield print message. +Shield message. Default value: `Restricted access.` @@ -172,7 +172,7 @@ Defined in: `.env` Drupal site email.
Used only when installing from profile. -Default value: `webmaster@your-site-url.example` +Default value: `webmaster@your-site-domain.example` Defined in: `.env`, `scripts/vortex/provision.sh` @@ -186,9 +186,11 @@ Defined in: `.env`, `scripts/vortex/provision.sh` ### `DRUPAL_STAGE_FILE_PROXY_ORIGIN` -Stage file proxy origin. Note that HTTP Auth provided by Shield will be
automatically added to the origin URL. +Stage file proxy origin. -Default value: `https://www.your-site-url.example/` +If using Shield, the HTTP authentication credentials will be automatically
added to the origin URL. + +Default value: `https://www.your-site-domain.example/` Defined in: `.env` @@ -272,7 +274,7 @@ Defined in: `CI config` Commit author for self-hosted Renovate bot. -Default value: `'Renovate Self Hosted '` +Default value: `'Renovate Self Hosted '` Defined in: `CI config` @@ -294,7 +296,7 @@ Defined in: `scripts/vortex/task-purge-cache-acquia.sh` ### `VORTEX_ACQUIA_APP_NAME` -Acquia application name to download the database from. +Acquia application name. Default value: `UNDEFINED` @@ -488,7 +490,9 @@ Defined in: `.env`, `scripts/vortex/download-db-acquia.sh` ### `VORTEX_DB_DOWNLOAD_CURL_URL` -Database dump file sourced from CURL, with optional HTTP Basic Authentication
credentials embedded into the value. +Database dump file sourced from CURL. + +HTTP Basic Authentication credentials should be embedded into the value. Default value: `UNDEFINED` @@ -498,6 +502,8 @@ Defined in: `.env`, `scripts/vortex/download-db-curl.sh` Environment to download the database from. +Applies to Acquia and Lagoon environments. + Default value: `prod` Defined in: `.env`, `scripts/vortex/download-db-acquia.sh`, `scripts/vortex/download-db-lagoon.sh` @@ -618,6 +624,15 @@ Defined in: `scripts/vortex/download-db-lagoon.sh` ### `VORTEX_DB_DOWNLOAD_SOURCE` +Database can be sourced from one of the following locations: + +- `curl` - directly from a URL as a file using CURL. +- `ftp` - directly from an FTP as a file using CURL. +- `acquia` - from the latest Acquia backup via Cloud API as a file. +- `lagoon` - from Lagoon main environment as a file. +- `container_registry` - from the container registry as a container image. +- `none` - not downloaded, site is freshly installed for every build. + Note that "container_registry" works only for database-in-image
database storage (when [`$VORTEX_DB_IMAGE`](#vortex_db_image) variable has a value). Default value: `curl` @@ -1227,7 +1242,7 @@ Defined in: `scripts/vortex/notify-email.sh` Email to send notifications from. -Default value: `webmaster@your-site-url.example` +Default value: `webmaster@your-site-domain.example` Defined in: `.env`, `scripts/vortex/notify-email.sh` @@ -1245,7 +1260,7 @@ Email address(es) to send notifications to. Multiple names can be specified as a comma-separated list of email addresses
with optional names in the format "email|name".
Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" -Default value: `webmaster@your-site-url.example` +Default value: `webmaster@your-site-domain.example` Defined in: `.env`, `scripts/vortex/notify-email.sh` @@ -1533,7 +1548,7 @@ Defined in: `scripts/vortex/provision.sh` ### `VORTEX_PROVISION_OVERRIDE_DB` -Overwrite existing database if it exists. +Overwrite a database if it exists. Usually set to `0` in deployed environments and can be temporary set to `1` for
a specific deployment.
Set this to `1` in .env.local to override when developing locally. @@ -1561,9 +1576,11 @@ Defined in: `scripts/vortex/provision-sanitize-db.sh` ### `VORTEX_PROVISION_SANITIZE_DB_EMAIL` -Sanitization email pattern. Sanitization is enabled by default in all
non-production environments.
@see https://vortex.drevops.com/workflows/build#sanitization +Sanitization email pattern. + +Applied if database sanitization is enabled.
@see https://vortex.drevops.com/workflows/build#sanitization -Default value: `user_%uid@your-site-url.example` +Default value: `user_%uid@your-site-domain.example` Defined in: `.env`, `scripts/vortex/provision-sanitize-db.sh` @@ -1862,7 +1879,7 @@ Defined in: `.env` ### `VORTEX_WEBROOT` -Name of the webroot directory with Drupal codebase. +Name of the web root directory containing a Drupal codebase. Default value: `web` diff --git a/.vortex/installer/composer.json b/.vortex/installer/composer.json index 472178270..e5d246416 100644 --- a/.vortex/installer/composer.json +++ b/.vortex/installer/composer.json @@ -27,7 +27,7 @@ "drupal/coder": "^8.3", "ergebnis/composer-normalize": "^2.45", "mikey179/vfsstream": "^1.6", - "opis/closure": "^3.6", + "opis/closure": "^4", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^10", "rector/rector": "^1.0.0" diff --git a/.vortex/installer/composer.lock b/.vortex/installer/composer.lock index 79fe7d405..25c0393e9 100644 --- a/.vortex/installer/composer.lock +++ b/.vortex/installer/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5a995c729a9bc0de421a808833578ca6", + "content-hash": "9b1ac86bcb8602ff6b784952c86facaf", "packages": [ { "name": "psr/container", @@ -627,12 +627,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -1896,34 +1896,33 @@ }, { "name": "opis/closure", - "version": "3.6.3", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/opis/closure.git", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" + "reference": "9b6ef5f622b4b29cf98bdc144f2a370c3a40d4df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", + "url": "https://api.github.com/repos/opis/closure/zipball/9b6ef5f622b4b29cf98bdc144f2a370c3a40d4df", + "reference": "9b6ef5f622b4b29cf98bdc144f2a370c3a40d4df", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0 || ^8.0" + "php": "^8.0" }, "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.6.x-dev" + "dev-master": "4.x-dev" } }, "autoload": { "files": [ - "functions.php" + "src/functions.php" ], "psr-4": { "Opis\\Closure\\": "src/" @@ -1943,7 +1942,7 @@ "email": "sarca_sorin@hotmail.com" } ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary data.", "homepage": "https://opis.io/closure", "keywords": [ "anonymous functions", @@ -1955,9 +1954,9 @@ ], "support": { "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.3" + "source": "https://github.com/opis/closure/tree/4.3.1" }, - "time": "2022-01-27T09:35:39+00:00" + "time": "2025-01-10T20:42:24+00:00" }, { "name": "phar-io/manifest", diff --git a/.vortex/installer/src/Command/InstallCommand.php b/.vortex/installer/src/Command/InstallCommand.php index 2c8d21f43..e2225942a 100644 --- a/.vortex/installer/src/Command/InstallCommand.php +++ b/.vortex/installer/src/Command/InstallCommand.php @@ -96,6 +96,13 @@ protected function configure(): void { protected function execute(InputInterface $input, OutputInterface $output): int { $this->output = $output; + // @see https://github.com/drevops/vortex/issues/1502 + if ($input->getOption('help') || $input->getArgument('path') == 'help') { + $output->write($this->getHelp()); + + return Command::SUCCESS; + } + try { $this->checkRequirements(); @@ -143,8 +150,8 @@ protected function resolveOptions(array $options, ?string $path): void { $this->config->set('quiet', TRUE); } - if (!empty($options['no-ansi'])) { - $this->config->set('ANSI', FALSE); + if (!is_null($options['ansi'])) { + $this->config->set('ANSI', $options['ansi']); } else { // On Windows, default to no ANSI, except in ANSICON and ConEmu. @@ -161,8 +168,17 @@ protected function resolveOptions(array $options, ?string $path): void { // Set destination directory. if (!empty($path)) { $path = $this->fsGetAbsolutePath($path); - if (!is_readable($path) || !is_dir($path)) { - throw new \RuntimeException(sprintf('Destination directory "%s" is not readable or does not exist.', $path)); + + if (file_exists($path)) { + if (is_file($path)) { + throw new \RuntimeException(sprintf('Destination directory "%s" is a file.', $path)); + } + } + else { + $this->fs->mkdir($path); + if (!is_readable($path) || !is_dir($path)) { + throw new \RuntimeException(sprintf('Destination directory "%s" is not readable or does not exist.', $path)); + } } } $this->config->set('VORTEX_INSTALL_DST_DIR', $path ?: static::getenvOrDefault('VORTEX_INSTALL_DST_DIR', $this->fsGetRootDir())); @@ -222,8 +238,6 @@ protected function doExecute(): void { $this->copyFiles(); $this->handleDemo(); - - $this->printFooter(); } protected function collectAnswers(): void { @@ -240,7 +254,7 @@ protected function collectAnswers(): void { $this->askForAnswer('module_prefix', 'What is your project-specific module prefix?'); $this->askForAnswer('profile', 'What is your custom profile machine name (leave empty to use "standard" profile)?'); $this->askForAnswer('theme', 'What is your theme machine name?'); - $this->askForAnswer('url', 'What is your site public URL?'); + $this->askForAnswer('domain', 'What is your site public domain?'); $this->askForAnswer('webroot', 'Web root (web, docroot)?'); $this->askForAnswer('provision_use_profile', 'Do you want to install from profile (leave empty or "n" for using database?'); @@ -300,7 +314,7 @@ protected function collectAnswers(): void { $this->printSummary(); if ($this->config->isInstallDebug()) { - $this->printBox($this->formatValuesList($this->getAnswers(), '', 80 - 6), 'DEBUG RESOLVED ANSWERS'); + $this->printBox($this->formatValuesList($this->getAnswers(), '', $this->getTuiWidth() - 2 - 2 * 2), 'DEBUG RESOLVED ANSWERS'); } } @@ -367,6 +381,7 @@ protected function replaceTokens(): void { 'preserve_vortex_info', 'vortex_internal', 'enable_commented_code', + 'empty_lines', ]; foreach ($processors as $name) { diff --git a/.vortex/installer/src/Traits/DownloadTrait.php b/.vortex/installer/src/Traits/DownloadTrait.php index 604c816f6..48831292d 100644 --- a/.vortex/installer/src/Traits/DownloadTrait.php +++ b/.vortex/installer/src/Traits/DownloadTrait.php @@ -57,7 +57,7 @@ protected function downloadScaffoldRemote(): void { $this->status('Done', self::INSTALLER_STATUS_SUCCESS); } - protected function findLatestVortexRelease(string $org, string $project, string $release_prefix): ?string { + protected function findLatestVortexRelease(string $org, string $project, ?string $release_prefix): ?string { $release_url = sprintf('https://api.github.com/repos/%s/%s/releases', $org, $project); $release_contents = file_get_contents($release_url, FALSE, stream_context_create([ 'http' => ['method' => 'GET', 'header' => ['User-Agent: PHP']], @@ -68,9 +68,15 @@ protected function findLatestVortexRelease(string $org, string $project, string } $records = json_decode($release_contents, TRUE); + + if (!$release_prefix) { + return is_scalar($records[0]['tag_name']) ? strval($records[0]['tag_name']) : NULL; + } + foreach ($records as $record) { - if (isset($record['tag_name']) && ($release_prefix && str_contains((string) $record['tag_name'], $release_prefix) || !$release_prefix)) { - return $record['tag_name']; + $tag_name = is_scalar($record['tag_name']) ? strval($record['tag_name']) : ''; + if (str_contains($tag_name, $release_prefix)) { + return $tag_name; } } diff --git a/.vortex/installer/src/Traits/PrinterTrait.php b/.vortex/installer/src/Traits/PrinterTrait.php index 9de6a4a25..dad8b059c 100644 --- a/.vortex/installer/src/Traits/PrinterTrait.php +++ b/.vortex/installer/src/Traits/PrinterTrait.php @@ -10,22 +10,36 @@ trait PrinterTrait { protected function out(string $text, ?string $color = NULL, bool $new_line = TRUE): void { - $styles = [ - 'success' => "\033[0;32m%s\033[0m", - 'error' => "\033[31;31m%s\033[0m", - ]; + $text = $color ? $this->formatColor($text, $color) : $text; - $format = '%s'; - - if (isset($styles[$color]) && $this->config->get('ANSI')) { - $format = $styles[$color]; + if ($new_line) { + $text .= PHP_EOL; } - if ($new_line) { - $format .= PHP_EOL; + print $text; + } + + protected function formatColor(string $text, string $color): string { + if (!$this->config->get('ANSI')) { + return $text; } - printf($format, $text); + $colors = [ + 'green' => "\033[0;32m%s\033[0m", + 'red' => "\033[0;31m%s\033[0m", + 'blue' => "\033[0;34m%s\033[0m", + 'yellow' => "\033[0;33m%s\033[0m", + 'cyan' => "\033[0;36m%s\033[0m", + 'magenta' => "\033[0;35m%s\033[0m", + 'white' => "\033[0;37m%s\033[0m", + 'success' => "\033[0;32m%s\033[0m", + 'error' => "\033[31;31m%s\033[0m", + 'info' => "\033[0;34m%s\033[0m", + ]; + + $format = $colors[$color] ?? '%s'; + + return sprintf($format, $text); } protected function debug(mixed $value, string $name = ''): void { @@ -37,16 +51,20 @@ protected function debug(mixed $value, string $name = ''): void { } protected function printTitle(string $text, string $fill = '-', int $width = 80, string $cols_delim = '|', bool $has_content = FALSE): void { + $width = $this->getTuiWidth($width); + $this->printDivider($fill, $width, 'down'); $lines = explode(PHP_EOL, wordwrap($text, $width - 4, PHP_EOL)); foreach ($lines as $line) { - $line = ' ' . $line . ' '; - print $cols_delim . str_pad($line, $width - 2, ' ', STR_PAD_BOTH) . $cols_delim . PHP_EOL; + $line = ' ' . $this->formatBold($line) . ' '; + print $cols_delim . str_pad($line, $width - 2 + (strlen($line) - $this->getVisibleLength($line)), ' ', STR_PAD_BOTH) . $cols_delim . PHP_EOL; } $this->printDivider($fill, $width, $has_content ? 'up' : 'both'); } protected function printSubtitle(string $text, string $fill = '=', int $width = 80): void { + $width = $this->getTuiWidth($width); + $is_multiline = strlen($text) + 4 >= $width; if ($is_multiline) { $this->printTitle($text, $fill, $width, 'both'); @@ -58,6 +76,8 @@ protected function printSubtitle(string $text, string $fill = '=', int $width = } protected function printDivider(string $fill = '-', int $width = 80, string $direction = 'none'): void { + $width = $this->getTuiWidth($width); + $start = $fill; $finish = $fill; switch ($direction) { @@ -81,12 +101,12 @@ protected function printDivider(string $fill = '-', int $width = 80, string $dir } protected function printBox(string $content, string $title = '', string $fill = 'ā”€', int $padding = 2, int $width = 80): void { - $cols = 'ā”‚'; + $width = $this->getTuiWidth($width); $max_width = $width - 2 - $padding * 2; $lines = explode(PHP_EOL, wordwrap(rtrim($content, PHP_EOL), $max_width, PHP_EOL)); $pad = str_pad(' ', $padding); - $mask = sprintf('%s%s%%-%ss%s%s', $cols, $pad, $max_width, $pad, $cols) . PHP_EOL; + $mask = sprintf('ā”‚%s%%-%ss%sā”‚', $pad, $max_width, $pad) . PHP_EOL; print PHP_EOL; if (!empty($title)) { @@ -132,7 +152,7 @@ protected function status(string $message, int $level = self::INSTALLER_STATUS_M break; case self::INSTALLER_STATUS_MESSAGE: - $prefix = 'iļø'; + $prefix = 'ā“˜ '; $color = 'info'; break; @@ -160,6 +180,8 @@ protected function status(string $message, int $level = self::INSTALLER_STATUS_M * Formatted values list. */ protected function formatValuesList(array $values, string $delim = '', int $width = 80): string { + $width = $this->getTuiWidth($width); + // Only keep the keys that are not numeric. $keys = array_filter(array_keys($values), static fn($key): bool => !is_numeric($key)); @@ -218,4 +240,15 @@ protected function formatNotEmpty(mixed $value, mixed $default): mixed { return empty($value) ? $default : $value; } + protected function formatBold(string $text): string { + return "\033[1m" . $text . "\033[0m"; + } + + protected function getVisibleLength(string $text): int { + // Remove ANSI escape sequences using a regex. + $plain_text = preg_replace('/\033\[[0-9;]*m/', '', $text); + + return mb_strlen($plain_text); + } + } diff --git a/.vortex/installer/src/Traits/PromptsTrait.php b/.vortex/installer/src/Traits/PromptsTrait.php index 108a80321..c3cfdbef5 100644 --- a/.vortex/installer/src/Traits/PromptsTrait.php +++ b/.vortex/installer/src/Traits/PromptsTrait.php @@ -50,7 +50,7 @@ protected function getDefaultValueTheme(): mixed { return $this->getAnswer('machine_name'); } - protected function getDefaultValueUrl(): string { + protected function getDefaultValueDomain(): string { $value = $this->getAnswer('machine_name'); $value = str_replace('_', '-', $value); @@ -307,7 +307,7 @@ protected function processDemoMode(string $dir): void { if ($this->getAnswer('provision_use_profile') === self::ANSWER_NO) { $download_source = $this->getAnswer('database_download_source'); $db_file = static::getenvOrDefault('VORTEX_DB_DIR', './.data') . DIRECTORY_SEPARATOR . static::getenvOrDefault('VORTEX_DB_FILE', 'db.sql'); - $has_comment = File::fileContains('to allow to demonstrate how Vortex works without', $this->config->getDstDir() . '/.env'); + $has_comment = File::fileContains('Override project-specific values for demonstration purposes', $this->config->getDstDir() . '/.env'); // Enable Vortex demo mode if download source is file AND // there is no downloaded file present OR if there is a demo comment in @@ -375,10 +375,16 @@ protected function processVortexInternal(string $dir): void { } protected function processEnableCommentedCode(string $dir): void { - // Enable_commented_code. File::dirReplaceContent('##### ', '', $dir); } + protected function processEmptyLines(string $dir): void { + $files = File::scandirRecursive($dir, File::ignorePaths()); + foreach ($files as $filename) { + File::fileReplaceContent('/(\n\s*\n)+/', "\n\n", $filename); + } + } + protected function processWebroot(string $dir): void { $new_name = $this->getAnswer('webroot', 'web'); @@ -494,7 +500,7 @@ protected function discoverValueProfile(): ?string { $this->config->getDstDir() . sprintf('/%s/profiles/custom/*/*.info.yml', $webroot), ]; - $name = File::findMatchingPath($locations, 'Drupal 10 profile implementation of'); + $name = File::findMatchingPath($locations, 'Drupal 11 profile implementation of'); if (empty($name)) { return NULL; @@ -537,35 +543,8 @@ protected function discoverValueTheme(): ?string { return str_replace(['.info.yml', '.info'], '', $name); } - protected function discoverValueUrl(): ?string { - $webroot = $this->getAnswer('webroot'); - - $origin = NULL; - $path = $this->config->getDstDir() . sprintf('/%s/sites/default/settings.php', $webroot); - - if (!is_readable($path)) { - return NULL; - } - - $contents = file_get_contents($path); - if (!$contents) { - return NULL; - } - - // Drupal 8 and 9. - if (preg_match('/\$config\s*\[\'stage_file_proxy.settings\'\]\s*\[\'origin\'\]\s*=\s*[\'"]([^\'"]+)[\'"];/', $contents, $matches)) { - $origin = $matches[1]; - } - // Drupal 7. - elseif (preg_match('/\$conf\s*\[\'stage_file_proxy_origin\'\]\s*=\s*[\'"]([^\'"]+)[\'"];/', $contents, $matches)) { - $origin = $matches[1]; - } - - if ($origin) { - $origin = parse_url($origin, PHP_URL_HOST); - } - - return empty($origin) ? NULL : $origin; + protected function discoverValueDomain(): ?string { + return $this->getValueFromDstDotenv('DRUPAL_STAGE_FILE_PROXY_ORIGIN'); } protected function discoverValueWebroot(): ?string { @@ -718,10 +697,13 @@ protected function normaliseAnswerTheme(string $value): string { return Converter::toMachineName($value); } - protected function normaliseAnswerUrl(string $url): string { - $url = trim($url); + protected function normaliseAnswerDomain(string $value): string { + $value = trim($value); + $value = rtrim($value, '/'); + $value = str_replace([' ', '_'], '-', $value); + $value = preg_replace('/^https?:\/\//', '', $value); - return str_replace([' ', '_'], '-', $url); + return preg_replace('/^www\./', '', $value); } protected function normaliseAnswerWebroot(string $value): string { @@ -904,43 +886,38 @@ protected function processStringTokens(string $dir): void { $module_prefix_uppercase = strtoupper($module_prefix_camel_cased); $theme_camel_cased = Converter::toCamelCase($this->getAnswer('theme'), TRUE); $vortex_version_urlencoded = str_replace('-', '--', (string) $this->config->get('VORTEX_VERSION')); - $url = $this->getAnswer('url'); - $host = parse_url($url, PHP_URL_HOST); - $domain = $host ?: $url; - $domain_non_www = str_starts_with((string) $domain, "www.") ? substr((string) $domain, 4) : $domain; $webroot = $this->getAnswer('webroot'); // @formatter:off // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma // phpcs:disable Drupal.WhiteSpace.Comma.TooManySpaces - File::dirReplaceContent('your_site_theme', $this->getAnswer('theme'), $dir); - File::dirReplaceContent('YourSiteTheme', $theme_camel_cased, $dir); - File::dirReplaceContent('your_org', $this->getAnswer('org_machine_name'), $dir); - File::dirReplaceContent('YOURORG', $this->getAnswer('org'), $dir); - File::dirReplaceContent('www.your-site-url.example', $domain, $dir); - File::dirReplaceContent('your-site-url.example', $domain_non_www, $dir); - File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); - File::dirReplaceContent('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . sprintf('/%s/modules/custom', $webroot)); - File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/themes/custom', $webroot)); - File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . '/scripts/custom'); - File::dirReplaceContent('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . '/scripts/custom'); - File::dirReplaceContent('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); - File::dirReplaceContent('YsSearch', $module_prefix_camel_cased . 'Search', $dir . sprintf('/%s/modules/custom', $webroot)); - File::dirReplaceContent('YSCODE', $module_prefix_uppercase, $dir); - File::dirReplaceContent('YSSEARCH', $module_prefix_uppercase, $dir); - File::dirReplaceContent('your-site', $machine_name_hyphenated, $dir); - File::dirReplaceContent('your_site', $this->getAnswer('machine_name'), $dir); - File::dirReplaceContent('YOURSITE', $this->getAnswer('name'), $dir); - File::dirReplaceContent('YourSite', $machine_name_camel_cased, $dir); - - File::replaceStringFilename('YourSiteTheme', $theme_camel_cased, $dir); - File::replaceStringFilename('your_site_theme', $this->getAnswer('theme'), $dir); - File::replaceStringFilename('YourSite', $machine_name_camel_cased, $dir); - File::replaceStringFilename('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); - File::replaceStringFilename('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . sprintf('/%s/modules/custom', $webroot)); - File::replaceStringFilename('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); - File::replaceStringFilename('your_org', $this->getAnswer('org_machine_name'), $dir); - File::replaceStringFilename('your_site', $this->getAnswer('machine_name'), $dir); + File::dirReplaceContent('your_site_theme', $this->getAnswer('theme'), $dir); + File::dirReplaceContent('YourSiteTheme', $theme_camel_cased, $dir); + File::dirReplaceContent('your_org', $this->getAnswer('org_machine_name'), $dir); + File::dirReplaceContent('YOURORG', $this->getAnswer('org'), $dir); + File::dirReplaceContent('your-site-domain.example', $this->getAnswer('domain'), $dir); + File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); + File::dirReplaceContent('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . sprintf('/%s/modules/custom', $webroot)); + File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/themes/custom', $webroot)); + File::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . '/scripts/custom'); + File::dirReplaceContent('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . '/scripts/custom'); + File::dirReplaceContent('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); + File::dirReplaceContent('YsSearch', $module_prefix_camel_cased . 'Search', $dir . sprintf('/%s/modules/custom', $webroot)); + File::dirReplaceContent('YSCODE', $module_prefix_uppercase, $dir); + File::dirReplaceContent('YSSEARCH', $module_prefix_uppercase, $dir); + File::dirReplaceContent('your-site', $machine_name_hyphenated, $dir); + File::dirReplaceContent('your_site', $this->getAnswer('machine_name'), $dir); + File::dirReplaceContent('YOURSITE', $this->getAnswer('name'), $dir); + File::dirReplaceContent('YourSite', $machine_name_camel_cased, $dir); + + File::replaceStringFilename('YourSiteTheme', $theme_camel_cased, $dir); + File::replaceStringFilename('your_site_theme', $this->getAnswer('theme'), $dir); + File::replaceStringFilename('YourSite', $machine_name_camel_cased, $dir); + File::replaceStringFilename('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); + File::replaceStringFilename('ys_search', $this->getAnswer('module_prefix') . '_search', $dir . sprintf('/%s/modules/custom', $webroot)); + File::replaceStringFilename('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); + File::replaceStringFilename('your_org', $this->getAnswer('org_machine_name'), $dir); + File::replaceStringFilename('your_site', $this->getAnswer('machine_name'), $dir); File::dirReplaceContent('VORTEX_VERSION_URLENCODED', $vortex_version_urlencoded, $dir); File::dirReplaceContent('VORTEX_VERSION', $this->config->get('VORTEX_VERSION'), $dir); diff --git a/.vortex/installer/src/Traits/TuiTrait.php b/.vortex/installer/src/Traits/TuiTrait.php index 2e82c965a..88437c9ca 100644 --- a/.vortex/installer/src/Traits/TuiTrait.php +++ b/.vortex/installer/src/Traits/TuiTrait.php @@ -27,25 +27,38 @@ trait TuiTrait { final const INSTALLER_STATUS_DEBUG = 3; + /** + * Width of the TUI. + */ + protected int $tuiWidth; + + /** + * Is Vortex initially installed. + */ + protected bool $isInitiallyInstalled = FALSE; + protected function ask(string $question, ?string $default, bool $close_handle = FALSE): ?string { if ($this->config->isQuiet()) { return $default; } - $question = sprintf('> %s [%s] ', $question, $default); + $this->out(sprintf('%s [%s] ', $this->formatColor('> ' . $question, 'green'), $this->formatColor($default, 'yellow')), NULL, FALSE); - $this->out($question, 'question', FALSE); $handle = $this->getStdinHandle(); $answer = fgets($handle); if ($answer !== FALSE) { $answer = trim($answer); } + $answer = empty($answer) ? $default : $answer; + + $this->out($answer, 'cyan'); + if ($close_handle) { $this->closeStdinHandle(); } - return empty($answer) ? $default : $answer; + return $answer; } protected function getStdinHandle(): mixed { @@ -68,6 +81,28 @@ protected function closeStdinHandle(): void { } protected function printHeader(): void { + $logo = <<getTuiWidth() >= 80) { + $this->out($logo, 'green'); + } + + $this->isInitiallyInstalled = $this->isInstalled(); + if ($this->config->isQuiet()) { $this->printHeaderQuiet(); } @@ -88,7 +123,7 @@ protected function printHeaderInteractive(): void { $content .= sprintf('This will install Vortex into your project at commit "%s".', $commit) . PHP_EOL; } $content .= PHP_EOL; - if ($this->isInstalled()) { + if ($this->isInitiallyInstalled) { $content .= 'It looks like Vortex is already installed into this project.' . PHP_EOL; $content .= PHP_EOL; } @@ -114,7 +149,7 @@ protected function printHeaderQuiet(): void { } $content .= PHP_EOL; - if ($this->isInstalled()) { + if ($this->isInitiallyInstalled) { $content .= 'It looks like Vortex is already installed into this project.' . PHP_EOL; $content .= PHP_EOL; } @@ -133,7 +168,7 @@ protected function printSummary(): void { $values['Vortex commit'] = $this->formatNotEmpty($this->config->get('VORTEX_INSTALL_COMMIT'), 'Latest'); $values[] = ''; - $values[] = str_repeat('ā”€', 80 - 2 - 2 * 2); + $values[] = str_repeat('ā”€', $this->getTuiWidth() - 2 - 2 * 2); $values[] = ''; $values['Name'] = $this->getAnswer('name'); @@ -143,7 +178,7 @@ protected function printSummary(): void { $values['Module prefix'] = $this->getAnswer('module_prefix'); $values['Profile'] = $this->getAnswer('profile'); $values['Theme name'] = $this->getAnswer('theme'); - $values['URL'] = $this->getAnswer('url'); + $values['Domain'] = $this->getAnswer('domain'); $values['Web root'] = $this->getAnswer('webroot'); $values['Install from profile'] = $this->formatYesNo($this->getAnswer('provision_use_profile')); @@ -166,7 +201,7 @@ protected function printSummary(): void { $values['Preserve docs in comments'] = $this->formatYesNo($this->getAnswer('preserve_doc_comments')); $values['Preserve Vortex comments'] = $this->formatYesNo($this->getAnswer('preserve_vortex_info')); - $content = $this->formatValuesList($values, '', 80 - 2 - 2 * 2); + $content = $this->formatValuesList($values, '', $this->getTuiWidth() - 2 - 2 * 2); $this->printBox($content, 'INSTALLATION SUMMARY'); } @@ -178,7 +213,7 @@ protected function printAbort(): void { protected function printFooter(): void { print PHP_EOL; - if ($this->isInstalled()) { + if ($this->isInitiallyInstalled) { $this->printBox('Finished updating Vortex. Review changes and commit required files.'); } else { @@ -204,6 +239,15 @@ protected function commandExists(string $command): void { } } + protected function getTuiWidth(int $max = 80): int { + if (!isset($this->tuiWidth)) { + $width = intval($this->doExec('tput cols')); + $this->tuiWidth = $width > 0 ? $width : $max; + } + + return min($this->tuiWidth, $max); + } + /** * Execute command. * @@ -266,7 +310,7 @@ protected function askShouldProceed(): bool { $proceed = self::ANSWER_YES; if (!$this->config->isQuiet()) { - $proceed = $this->ask(sprintf('Proceed with installing Vortex into your project\'s directory "%s"? (Y,n)', $this->config->getDstDir()), $proceed, TRUE); + $proceed = $this->ask(sprintf('Proceed with installing Vortex into your project\'s directory "%s"?', $this->config->getDstDir()), $proceed, TRUE); } // Kill-switch to not proceed with install. If false, the install will not diff --git a/.vortex/tests/bats/_helper.bash b/.vortex/tests/bats/_helper.bash index 45502d67e..a794838f8 100644 --- a/.vortex/tests/bats/_helper.bash +++ b/.vortex/tests/bats/_helper.bash @@ -541,7 +541,7 @@ assert_files_present_drupal() { assert_dir_not_contains_string "${dir}" "your_site_theme" assert_dir_not_contains_string "${dir}" "your_org" assert_dir_not_contains_string "${dir}" "YOURORG" - assert_dir_not_contains_string "${dir}" "www.your-site-url.example" + assert_dir_not_contains_string "${dir}" "www.your-site-domain.example" # Assert all special comments were removed. assert_dir_not_contains_string "${dir}" "#;" assert_dir_not_contains_string "${dir}" "#;<" @@ -1021,7 +1021,7 @@ create_fixture_readme() { cat <>"${dir}"/README.md # ${name} -Drupal 10 implementation of ${name} for ${org} +Drupal 11 implementation of ${name} for ${org} [![CircleCI](https://circleci.com/gh/your_org/your_site.svg?style=shield)](https://circleci.com/gh/your_org/your_site) @@ -1043,7 +1043,7 @@ create_fixture_composerjson() { cat <>"${dir}"/composer.json { "name": "${org_machine_name}/${machine_name}", - "description": "Drupal 10 implementation of ${name} for ${org}" + "description": "Drupal 11 implementation of ${name} for ${org}" } EOT } diff --git a/.vortex/tests/bats/install.parameters.bats b/.vortex/tests/bats/install.parameters.bats index 9bec299bf..6b738c662 100644 --- a/.vortex/tests/bats/install.parameters.bats +++ b/.vortex/tests/bats/install.parameters.bats @@ -64,7 +64,7 @@ load _helper.bash assert_output_contains " Module prefix: sw " assert_output_contains " Profile: standard " assert_output_contains " Theme name: star_wars " - assert_output_contains " URL: star-wars.com " + assert_output_contains " Domain: star-wars.com " assert_output_contains " Web root: web " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: curl " @@ -116,7 +116,7 @@ load _helper.bash assert_output_contains " Module prefix: sw " assert_output_contains " Profile: standard " assert_output_contains " Theme name: star_wars " - assert_output_contains " URL: star-wars.com " + assert_output_contains " Domain: star-wars.com " assert_output_contains " Web root: web " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: curl " @@ -170,7 +170,7 @@ load _helper.bash assert_output_contains " Module prefix: s_w " assert_output_contains " Profile: s_w_profile " assert_output_contains " Theme name: light_saber " - assert_output_contains " URL: resistance-forever.com " + assert_output_contains " Domain: resistance-forever.com " assert_output_contains " Web root: web " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: curl " @@ -223,7 +223,7 @@ load _helper.bash assert_output_contains " Module prefix: s_w " assert_output_contains " Profile: s_w_profile " assert_output_contains " Theme name: light_saber " - assert_output_contains " URL: resistance-forever.com " + assert_output_contains " Domain: resistance-forever.com " assert_output_contains " Web root: rootdoc " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: curl " @@ -256,7 +256,7 @@ load _helper.bash assert_output_contains " Profile: standard " assert_output_contains " Install from profile: No " assert_output_contains " Theme name: resisting " - assert_output_contains " URL: www.resistance-star-wars.com " + assert_output_contains " Domain: resistance-star-wars.com " assert_output_contains " Web root: web " assert_output_contains " Database download source: curl " assert_output_contains " Database store type: file " @@ -311,7 +311,7 @@ load _helper.bash assert_output_contains " Module prefix: another_resist " assert_output_contains " Profile: standard " assert_output_contains " Theme name: resisting " - assert_output_contains " URL: www.resistance-star-wars.com " + assert_output_contains " Domain: resistance-star-wars.com " assert_output_contains " Web root: web " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: curl " @@ -373,7 +373,7 @@ load _helper.bash assert_output_contains " Module prefix: w_s " assert_output_contains " Profile: s_w_profile " assert_output_contains " Theme name: light_saber " - assert_output_contains " URL: resistance-forever.com " + assert_output_contains " Domain: resistance-forever.com " assert_output_contains " Web root: web " assert_output_contains " Install from profile: No " assert_output_contains " Database download source: container_registry " @@ -415,10 +415,6 @@ fixture_preinstalled() { mktouch "${webroot}/sites/all/themes/custom/resisting/resisting.info.yml" mktouch "${webroot}/sites/all/themes/custom/yetanothertheme/yetanothertheme.info.yml" - # Sets 'url' to 'www.resistance-star-wars.com'. - mkdir -p "${webroot}/sites/default" - echo " \$config['stage_file_proxy.settings']['origin'] = 'http://www.resistance-star-wars.com/';" >"${webroot}/sites/default/settings.php" - # Sets 'ci_provider' to 'GitHub Actions'. mktouch ".github/workflows/build-test-deploy.yml" @@ -431,6 +427,9 @@ fixture_preinstalled() { echo "VORTEX_WEBROOT=${webroot}" >>.env + # Sets 'domain' to 'www.resistance-star-wars.com'. + echo "DRUPAL_STAGE_FILE_PROXY_ORIGIN=http://www.resistance-star-wars.com/" >>.env + # Sets 'fresh_install' to 'No'. echo "VORTEX_PROVISION_USE_PROFILE=0" >>.env diff --git a/README.dist.md b/README.dist.md index ba1e89408..43ba05405 100644 --- a/README.dist.md +++ b/README.dist.md @@ -1,5 +1,5 @@ # YOURSITE -Drupal 10 implementation of YOURSITE for YOURORG +Drupal 11 implementation of YOURSITE for YOURORG [//]: # (#;< CI_PROVIDER_CIRCLECI) @@ -13,7 +13,7 @@ Drupal 10 implementation of YOURSITE for YOURORG [//]: # (#;> CI_PROVIDER_GHA) -![Drupal 10](https://img.shields.io/badge/Drupal-10-blue.svg) +![Drupal 11](https://img.shields.io/badge/Drupal-10-blue.svg) [![codecov](https://codecov.io/gh/your_org/your_site/graph/badge.svg)](https://codecov.io/gh/your_org/your_site) [//]: # (#;< RENOVATEBOT) diff --git a/composer.json b/composer.json index 6c638baf0..d7d4978c3 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "your_org/your_site", - "description": "Drupal 10 implementation of YOURSITE for YOURORG", + "description": "Drupal 11 implementation of YOURSITE for YOURORG", "license": "proprietary", "type": "project", "require": { diff --git a/hooks/library/domains.txt b/hooks/library/domains.txt index aa6771663..0e31e9f2e 100644 --- a/hooks/library/domains.txt +++ b/hooks/library/domains.txt @@ -1 +1 @@ -$TARGET_ENV_REMAP.your-site-url.example +$TARGET_ENV_REMAP.your-site-domain.example