From e9e1ebd46a932ad09ea1a7fe2a3d7f2f3c0bb789 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 29 May 2024 18:51:53 +1000 Subject: [PATCH] Updated DevTools. --- .circleci/config.yml | 88 ++++++- web/themes/contrib/civictheme/.ahoy.yml | 101 +++++++- .../contrib/civictheme/.devtools/README.nd | 3 + .../contrib/civictheme/.devtools/README.txt | 3 - .../contrib/civictheme/.devtools/assemble.sh | 166 +++++++++++++ .../contrib/civictheme/.devtools/build.sh | 219 ------------------ .../contrib/civictheme/.devtools/deploy.sh | 129 +++++++++++ .../contrib/civictheme/.devtools/lint-fix.sh | 22 -- .../contrib/civictheme/.devtools/lint.sh | 30 --- .../civictheme/.devtools/process-artifacts.sh | 15 -- .../contrib/civictheme/.devtools/provision.sh | 117 ++++++++++ .../contrib/civictheme/.devtools/start.sh | 71 ++++++ .../contrib/civictheme/.devtools/stop.sh | 35 +++ .../contrib/civictheme/.devtools/test.sh | 53 ----- .../contrib/civictheme/.twig-cs-fixer.php | 17 ++ web/themes/contrib/civictheme/.twig_cs.php | 16 -- web/themes/contrib/civictheme/README.md | 41 ++++ .../contrib/civictheme/composer.dev.json | 23 ++ web/themes/contrib/civictheme/phpunit.xml | 112 +++++++++ 19 files changed, 884 insertions(+), 377 deletions(-) create mode 100644 web/themes/contrib/civictheme/.devtools/README.nd delete mode 100644 web/themes/contrib/civictheme/.devtools/README.txt create mode 100755 web/themes/contrib/civictheme/.devtools/assemble.sh delete mode 100755 web/themes/contrib/civictheme/.devtools/build.sh create mode 100755 web/themes/contrib/civictheme/.devtools/deploy.sh delete mode 100755 web/themes/contrib/civictheme/.devtools/lint-fix.sh delete mode 100755 web/themes/contrib/civictheme/.devtools/lint.sh delete mode 100755 web/themes/contrib/civictheme/.devtools/process-artifacts.sh create mode 100755 web/themes/contrib/civictheme/.devtools/provision.sh create mode 100755 web/themes/contrib/civictheme/.devtools/start.sh create mode 100755 web/themes/contrib/civictheme/.devtools/stop.sh delete mode 100755 web/themes/contrib/civictheme/.devtools/test.sh create mode 100644 web/themes/contrib/civictheme/.twig-cs-fixer.php delete mode 100644 web/themes/contrib/civictheme/.twig_cs.php create mode 100644 web/themes/contrib/civictheme/composer.dev.json create mode 100644 web/themes/contrib/civictheme/phpunit.xml diff --git a/.circleci/config.yml b/.circleci/config.yml index b6fde8121c..6a18158dbf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -131,16 +131,86 @@ job-build-isolated: &job-build-isolated - attach_workspace: at: /tmp/workspace - checkout - - run: cd web/themes/contrib/civictheme && ./.devtools/build.sh - - run: cd web/themes/contrib/civictheme && ./.devtools/lint.sh - - run: cd web/themes/contrib/civictheme && ./.devtools/test.sh + - run: - command: cd web/themes/contrib/civictheme && ./.devtools/process-artifacts.sh - when: always + name: Upgrade sqlite3 + command: | + wget https://www.sqlite.org/2024/sqlite-autoconf-3450300.tar.gz -O /tmp/sqlite.tar.gz + tar -xzf /tmp/sqlite.tar.gz -C /tmp + cd /tmp/sqlite-autoconf-3450300 + ./configure CFLAGS="-DSQLITE_ENABLE_COLUMN_METADATA=1" --prefix=/usr/local + make && sudo make install + sudo ldconfig + echo "export LD_LIBRARY_PATH=/usr/local/lib" >> $BASH_ENV + + - run: + name: Install PCOV + command: | + sudo pecl install pcov + echo "extension=pcov.so" | sudo tee -a /usr/local/etc/php/conf.d/pcov.ini + echo "pcov.enabled=1" | sudo tee -a /usr/local/etc/php/conf.d/pcov.ini + + - run: + name: Assemble the codebase + command: .devtools/assemble.sh + working_directory: web/themes/contrib/civictheme + + - run: + name: Start built-in PHP server + command: .devtools/start.sh + working_directory: web/themes/contrib/civictheme + + - run: + name: Provision site + command: .devtools/provision.sh + working_directory: web/themes/contrib/civictheme + + - run: + name: Lint code with PHPCS + command: vendor/bin/phpcs || [ "${CI_PHPCS_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + + - run: + name: Lint code with PHPStan + command: vendor/bin/phpstan || [ "${CI_PHPSTAN_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + + - run: + name: Lint code with Rector + command: vendor/bin/rector --clear-cache --dry-run || [ "${CI_RECTOR_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + + - run: + name: Lint code with PHPMD + command: vendor/bin/phpmd . text phpmd.xml || [ "${CI_PHPMD_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + + - run: + name: Lint code with Twig CS Fixer + command: vendor/bin/twig-cs-fixer || [ "${CI_TWIGCSFIXER_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + + - run: + name: Run tests + command: vendor/bin/phpunit || [ "${CI_TEST_IGNORE_FAILURE:-0}" -eq 1 ] + working_directory: web/themes/contrib/civictheme/build + - store_test_results: - path: /tmp/test_results + path: web/themes/contrib/civictheme/.logs/test_results + + - store_artifacts: + path: web/themes/contrib/civictheme/build/web/sites/simpletest/browser_output + - store_artifacts: - path: /tmp/artifacts + path: web/themes/contrib/civictheme/.logs/coverage + + - run: + name: Upload code coverage reports to Codecov + command: | + if [ -z "${CIRCLE_TAG-}" ] && [ -n "${CODECOV_TOKEN-}" ] && [ -d .logs/coverage/phpunit ]; then + curl -Os https://cli.codecov.io/latest/linux/codecov && sudo chmod +x codecov + ./codecov --verbose upload-process --fail-on-error -n "circleci-$CIRCLE_JOB" -s web/themes/contrib/civictheme/.logs/coverage + fi job-build: &job-build parallelism: 2 @@ -262,8 +332,8 @@ jobs: docker: - image: cimg/php:8.3-browsers environment: - DRUPAL_VERSION: 11@alpha - DRUPAL_PROJECT_SHA: 11.x + DRUPAL_VERSION: 10@beta + DRUPAL_PROJECT_SHA: 10.x <<: *job-build-isolated # Used to pass the built code down the pipeline. diff --git a/web/themes/contrib/civictheme/.ahoy.yml b/web/themes/contrib/civictheme/.ahoy.yml index 9394fb08f2..78783b66ab 100644 --- a/web/themes/contrib/civictheme/.ahoy.yml +++ b/web/themes/contrib/civictheme/.ahoy.yml @@ -1,8 +1,5 @@ -# # Ahoy configuration file. # http://www.ahoycli.com/ -# -# Provides development experience shortcuts. --- ahoyapi: v2 @@ -10,16 +7,100 @@ commands: build: usage: Build or rebuild the project. - cmd: ./.devtools/build.sh + cmd: | + ahoy stop > /dev/null 2>&1 || true + ahoy assemble + ahoy start + ahoy provision + + assemble: + usage: Assemble a codebase using project code and all required dependencies. + cmd: ./.devtools/assemble.sh + + start: + usage: Start development environment. + cmd: ./.devtools/start.sh + + stop: + usage: Stop development environment. + cmd: ./.devtools/stop.sh + + provision: + usage: Provision application within assembled codebase. + cmd: ./.devtools/provision.sh + + drush: + usage: Run Drush command. + cmd: build/vendor/bin/drush -l http://${WEBSERVER_HOST:-localhost}:${WEBSERVER_PORT:-8000} $* + + login: + usage: Login to a website. + cmd: ahoy drush uli lint: - usage: Lint code. - cmd: ./.devtools/lint.sh + usage: Check coding standards for violations. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/phpcs + vendor/bin/phpstan + vendor/bin/rector --clear-cache --dry-run + vendor/bin/phpmd . text phpmd.xml + vendor/bin/twig-cs-fixer + popd >/dev/null || exit 1 lint-fix: - usage: Lint code. - cmd: ./.devtools/lint-fix.sh + usage: Fix violations in coding standards. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/rector --clear-cache + vendor/bin/phpcbf + popd >/dev/null || exit 1 test: - usage: Run all tests. - cmd: ./.devtools/test.sh + usage: Run tests. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/phpunit + popd >/dev/null || exit 1 + + test-unit: + usage: Run unit tests. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/phpunit --testsuite unit + popd >/dev/null || exit 1 + + test-kernel: + usage: Run kernel tests. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/phpunit --testsuite kernel + popd >/dev/null || exit 1 + + test-functional: + usage: Run functional tests. + cmd: | + pushd "build" >/dev/null || exit 1 + vendor/bin/phpunit --testsuite functional + popd >/dev/null || exit 1 + + reset: + usage: Reset project to the default state. + cmd: | + killall -9 php >/dev/null 2>&1 || true + chmod -Rf 777 build > /dev/null + rm -Rf build > /dev/null || true + rm -Rf .logs > /dev/null || true + +# Override entrypoint to alter default behaviour of Ahoy. +entrypoint: + - bash + - -c + - -e + - | + extension="$(basename -s .info.yml -- ./*.info.yml)" + export SIMPLETEST_BASE_URL=http://${WEBSERVER_HOST:-localhost}:${WEBSERVER_PORT:-8000} + export SIMPLETEST_DB=sqlite://localhost/drupal_test_${extension}.sqlite + bash -e -c "$0" "$@" + - '{{cmd}}' + - '{{name}}' diff --git a/web/themes/contrib/civictheme/.devtools/README.nd b/web/themes/contrib/civictheme/.devtools/README.nd new file mode 100644 index 0000000000..59e2745329 --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/README.nd @@ -0,0 +1,3 @@ +This directory contains scripts used for development. + +These can be used locally and in the CI environment. diff --git a/web/themes/contrib/civictheme/.devtools/README.txt b/web/themes/contrib/civictheme/.devtools/README.txt deleted file mode 100644 index cdda9a51a5..0000000000 --- a/web/themes/contrib/civictheme/.devtools/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains development tools to help with building and testing. - -These can be used locally and in the CI environment. diff --git a/web/themes/contrib/civictheme/.devtools/assemble.sh b/web/themes/contrib/civictheme/.devtools/assemble.sh new file mode 100755 index 0000000000..03b92c1360 --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/assemble.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +## +# Assemble a codebase using project code and all required dependencies. +# +# Allows to use the latest Drupal core as well as specified versions (for +# testing backward compatibility). +# +# - Retrieves the scaffold from drupal-composer/drupal-project or custom scaffold. +# - Builds Drupal site codebase with current extension and it's dependencies. +# - Adds development dependencies. +# - Installs composer dependencies. +# +# This script will re-build the codebase from scratch every time it runs. + +# shellcheck disable=SC2015,SC2094,SC2002 + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +#------------------------------------------------------------------------------- +# Variables (passed from environment; provided for reference only). +#------------------------------------------------------------------------------- + +# Drupal core version to use. If not provided - the latest stable version will be used. +# Must be coupled with DRUPAL_PROJECT_SHA below. +DRUPAL_VERSION="${DRUPAL_VERSION:-10}" + +# Commit SHA of the drupal-project to install custom core version. If not +# provided - the latest version will be used. +# Must be coupled with DRUPAL_VERSION above. +DRUPAL_PROJECT_SHA="${DRUPAL_PROJECT_SHA:-10.x}" + +# Repository for "drupal-composer/drupal-project" project. +# May be overwritten to use forked repos that may have not been accepted +# yet (i.e., when major Drupal version is about to be released). +DRUPAL_PROJECT_REPO="${DRUPAL_PROJECT_REPO:-https://github.com/drupal-composer/drupal-project.git}" + +#------------------------------------------------------------------------------- + +# @formatter:off +note() { printf " %s\n" "${1}"; } +info() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[34m[INFO] %s\033[0m\n" "${1}" || printf "[INFO] %s\n" "${1}"; } +pass() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[32m[ OK ] %s\033[0m\n" "${1}" || printf "[ OK ] %s\n" "${1}"; } +fail() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[31m[FAIL] %s\033[0m\n" "${1}" || printf "[FAIL] %s\n" "${1}"; } +# @formatter:on + +#------------------------------------------------------------------------------- + +echo "===============================" +echo " 🏗️ ASSEMBLE " +echo "===============================" +echo + +# Make sure Composer doesn't run out of memory. +export COMPOSER_MEMORY_LIMIT=-1 + +info "Validate tools." +! command -v git >/dev/null && echo "ERROR: Git is required for this script to run." && exit 1 +! command -v php >/dev/null && echo "ERROR: PHP is required for this script to run." && exit 1 +! command -v composer >/dev/null && echo "ERROR: Composer (https://getcomposer.org/) is required for this script to run." && exit 1 +! command -v jq >/dev/null && echo "ERROR: jq (https://stedolan.github.io/jq/) is required for this script to run." && exit 1 +pass "Tools are valid." + +# Extension name, taken from the .info file. +extension="$(basename -s .info.yml -- ./*.info.yml)" +[ "${extension}" == "*" ] && echo "ERROR: No .info.yml file found." && exit 1 + +# Extension type. +type=$(grep -q "type: theme" "${extension}.info.yml" && echo "themes" || echo "modules") + +info "Validate Composer configuration." +composer validate --ansi --strict + +# Reset the environment. +if [ -d "build" ]; then + info "Removing existing build directory." + chmod -Rf 777 "build" >/dev/null || true + rm -rf "build" >/dev/null || true + pass "Existing build directory removed." +fi + +info "Creating Drupal codebase." +# Allow installing custom version of Drupal core from drupal-composer/drupal-project, +# but only coupled with drupal-project SHA (required to get correct dependencies). +if [ -n "${DRUPAL_VERSION:-}" ] && [ -n "${DRUPAL_PROJECT_SHA:-}" ]; then + note "Initialising Drupal site from the scaffold repo ${DRUPAL_PROJECT_REPO} commit ${DRUPAL_PROJECT_SHA}." + + # Clone Drupal core at the specific commit SHA. + git clone -n "${DRUPAL_PROJECT_REPO}" "build" + git --git-dir="build/.git" --work-tree="build" checkout "${DRUPAL_PROJECT_SHA}" + rm -rf "build/.git" >/dev/null + + note "Pin Drupal to a specific version ${DRUPAL_VERSION}." + sed_opts=(-i) && [ "$(uname)" == "Darwin" ] && sed_opts=(-i '') + sed "${sed_opts[@]}" 's|\(.*"drupal\/core"\): "\(.*\)",.*|\1: '"\"$DRUPAL_VERSION\",|" "build/composer.json" + cat "build/composer.json" +else + note "Initialising Drupal site from the latest scaffold." + # There are no releases in "drupal-composer/drupal-project", so have to use "@dev". + composer create-project drupal-composer/drupal-project:@dev "build" --no-interaction --no-install +fi +pass "Drupal codebase created." + +info "Merging configuration from composer.dev.json." +php -r "echo json_encode(array_replace_recursive(json_decode(file_get_contents('composer.dev.json'), true),json_decode(file_get_contents('build/composer.json'), true)),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);" >"build/composer2.json" && mv -f "build/composer2.json" "build/composer.json" + +info "Merging configuration from extension's composer.json." +php -r "echo json_encode(array_replace_recursive(json_decode(file_get_contents('composer.json'), true),json_decode(file_get_contents('build/composer.json'), true)),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);" >"build/composer2.json" && mv -f "build/composer2.json" "build/composer.json" + +if [ -n "${GITHUB_TOKEN:-}" ]; then + info "Adding GitHub authentication token if provided." + composer config --global github-oauth.github.com "${GITHUB_TOKEN}" + composer config --global github-oauth.github.com | grep -q "gh" || fail "GitHub token not added." + pass "GitHub token added." +fi + +info "Creating custom directories." +mkdir -p build/web/modules/custom build/web/themes/custom + +info "Installing dependencies." +composer --working-dir="build" install +pass "Dependencies installed." + +# Suggested dependencies allow to install them for testing without requiring +# them in extension's composer.json. +info "Installing suggested dependencies from extension's composer.json." +composer_suggests=$(cat composer.json | jq -r 'select(.suggest != null) | .suggest | keys[]') +for composer_suggest in $composer_suggests; do + composer --working-dir="build" require "${composer_suggest}" +done +pass "Suggested dependencies installed." + +info "Copying tools configuration files." +cp phpcs.xml phpstan.neon phpmd.xml rector.php .twig-cs-fixer.php phpunit.xml "build/" +pass "Tools configuration files copied." + +info "Symlinking extension's code." +rm -rf "build/web/${type}/custom" >/dev/null && mkdir -p "build/web/${type}/custom/${extension}" +ln -s "$(pwd)"/* "build/web/${type}/custom/${extension}" && rm "build/web/${type}/custom/${extension}/build" +pass "Extension's code symlinked." + +# If front-end dependencies are used in the project, package-lock.json is +# expected to be committed to the repository. +if [ -f "build/web/${type}/custom/${extension}/package-lock.json" ]; then + pushd "build/web/${type}/custom/${extension}" >/dev/null || exit 1 + + info "Installing front-end dependencies." + if [ -f ".nvmrc" ]; then nvm use; fi + if [ ! -d "node_modules" ]; then npm ci; fi + # Disable building front-end dependencies for now. + # echo "> Build front-end dependencies." + # npm run build + pass "Front-end dependencies installed." + + popd >/dev/null || exit 1 +fi + +echo +echo "===============================" +echo " 🏗 ASSEMBLE COMPLETE ✅ " +echo "===============================" +echo +echo "> Next steps:" +echo " .devtools/start.sh # Start the webserver" +echo " .devtools/provision.sh # Provision the website" +echo diff --git a/web/themes/contrib/civictheme/.devtools/build.sh b/web/themes/contrib/civictheme/.devtools/build.sh deleted file mode 100755 index cbe733abdb..0000000000 --- a/web/themes/contrib/civictheme/.devtools/build.sh +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env bash -## -# Build Drupal site using SQLite database, install current theme and serve -# using in-built PHP server. -# -# Allows to use the latest Drupal core as well as specified versions (for -# testing backward compatibility). -# -# - Retrieves the scaffold from drupal-composer/drupal-project or custom scaffold. -# - Builds Drupal site codebase with current theme and it's dependencies. -# - Installs Drupal using SQLite database. -# - Starts in-built PHP-server -# - Enables theme -# - Serves site and generates one-time login link -# -# This script will re-build everything from scratch every time it runs. - -# shellcheck disable=SC2015,SC2094,SC2002 - -set -eu -[ -n "${DEBUG:-}" ] && set -x - -#------------------------------------------------------------------------------- -# Variables (passed from environment; provided for reference only). -#------------------------------------------------------------------------------- - -# Webserver hostname. -WEBSERVER_HOST="${WEBSERVER_HOST:-localhost}" - -# Webserver port. -WEBSERVER_PORT="${WEBSERVER_PORT:-8000}" - -# Drupal core version to use. If not provided - the latest stable version will be used. -# Must be coupled with DRUPAL_PROJECT_SHA below. -DRUPAL_VERSION="${DRUPAL_VERSION:-}" - -# Commit SHA of the drupal-project to install custom core version. If not -# provided - the latest version will be used. -# Must be coupled with DRUPAL_VERSION above. -DRUPAL_PROJECT_SHA="${DRUPAL_PROJECT_SHA:-}" - -# Repository for "drupal-composer/drupal-project" project. -# May be overwritten to use forked repos that may have not been accepted -# yet (i.e., when major Drupal version is about to be released). -DRUPAL_PROJECT_REPO="${DRUPAL_PROJECT_REPO:-https://github.com/drupal-composer/drupal-project.git}" - -# Drupal profile to use when installing the site. -DRUPAL_PROFILE="${DRUPAL_PROFILE:-standard}" - -#------------------------------------------------------------------------------- - -echo -echo "==> Started build in \"build\" directory." -echo - -echo "-------------------------------" -echo " Validating requirements " -echo "-------------------------------" - -echo " > Validating tools." -! command -v git > /dev/null && echo "ERROR: Git is required for this script to run." && exit 1 -! command -v php > /dev/null && echo "ERROR: PHP is required for this script to run." && exit 1 -! command -v composer > /dev/null && echo "ERROR: Composer (https://getcomposer.org/) is required for this script to run." && exit 1 -! command -v jq > /dev/null && echo "ERROR: jq (https://stedolan.github.io/jq/) is required for this script to run." && exit 1 - -drush() { "build/vendor/bin/drush" -r "$(pwd)/build/web" -y "$@"; } - -# Theme name, taken from the .info file. -theme="$(basename -s .info.yml -- ./*.info.yml)" -[ "${theme}" == "*" ] && echo "ERROR: No .info.yml file found." && exit 1 - -# Database file path. -db_file="/tmp/site_${theme}.sqlite" - -export COMPOSER_MEMORY_LIMIT=-1 - -echo " > Validating Composer configuration." -composer validate --ansi --strict - -# Reset the environment. -[ -d "build" ] && echo " > Removing existing build directory." && chmod -Rf 777 "build" && rm -rf "build" - -echo "-------------------------------" -echo " Installing Composer packages " -echo "-------------------------------" - -# Allow installing custom version of Drupal core from drupal-composer/drupal-project, -# but only coupled with drupal-project SHA (required to get correct dependencies). -if [ -n "${DRUPAL_VERSION:-}" ] && [ -n "${DRUPAL_PROJECT_SHA:-}" ]; then - echo " > Initialising Drupal site from the scaffold repo ${DRUPAL_PROJECT_REPO} commit ${DRUPAL_PROJECT_SHA}." - - # Clone Drupal core at the specific commit SHA. - git clone -n "${DRUPAL_PROJECT_REPO}" "build" - git --git-dir="build/.git" --work-tree="build" checkout "${DRUPAL_PROJECT_SHA}" - rm -rf "build/.git" > /dev/null - - echo " > Pinning Drupal to a specific version ${DRUPAL_VERSION}." - sed_opts=(-i) && [ "$(uname)" == "Darwin" ] && sed_opts=(-i '') - sed "${sed_opts[@]}" 's|\(.*"drupal\/core"\): "\(.*\)",.*|\1: '"\"$DRUPAL_VERSION\",|" "build/composer.json" - cat "build/composer.json" -else - echo " > Initialising Drupal site from the latest scaffold." - # There are no releases in "drupal-composer/drupal-project", so have to use "@dev". - composer create-project drupal-composer/drupal-project:@dev "build" --no-interaction --no-install -fi - -echo " > Updating scaffold." -composer --working-dir="build" config allow-plugins.php-http/discovery true -cat <<< "$(jq --indent 4 '.extra["enable-patching"] = true' "build/composer.json")" > "build/composer.json" -cat <<< "$(jq --indent 4 '.extra["phpcodesniffer-search-depth"] = 10' "build/composer.json")" > "build/composer.json" - -echo " > Merging configuration from theme's composer.json." -php -r "echo json_encode(array_replace_recursive(json_decode(file_get_contents('composer.json'), true),json_decode(file_get_contents('build/composer.json'), true)),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);" > "build/composer2.json" && mv -f "build/composer2.json" "build/composer.json" - -echo " > Adding custom patches." -cat <<< "$(jq --indent 4 '.extra.patches = {"drupal/core": {"Builds failing on missing layout column plugin": "https://www.drupal.org/files/issues/2023-07-16/3204271-20-missing-layout-exception.patch"}}' "build/composer.json")" > "build/composer.json" - -echo " > Creating GitHub authentication token if provided." -[ -n "${GITHUB_TOKEN:-}" ] && composer config --global github-oauth.github.com "${GITHUB_TOKEN}" && echo "Token: " && composer config --global github-oauth.github.com - -echo " > Installing dependencies." -composer --working-dir="build" install - -# Suggested dependencies allow to install them for testing without requiring -# them in theme's composer.json. -echo " > Installing suggested dependencies from theme's composer.json." -composer_suggests=$(cat composer.json | jq -r 'select(.suggest != null) | .suggest | keys[]') -for composer_suggest in $composer_suggests; do - composer --working-dir="build" require "${composer_suggest}" -done - -echo " > Installing other dev dependencies." -composer --working-dir="build" config allow-plugins.phpstan/extension-installer true -composer --working-dir="build" require --dev \ - dealerdirect/phpcodesniffer-composer-installer \ - phpspec/prophecy-phpunit:^2 \ - phpstan/extension-installer \ - phpcompatibility/php-compatibility \ - phpmd/phpmd \ - mglaman/phpstan-drupal:^1.2 \ - palantirnet/drupal-rector:^0.20 \ - friendsoftwig/twigcs:^6.2 - -echo " > Symlinking theme code." -rm -rf "build/web/themes/custom" > /dev/null && mkdir -p "build/web/themes/custom/${theme}" -ln -s "$(pwd)"/* "build/web/themes/custom/${theme}" && rm "build/web/themes/custom/${theme}/build" - -if [ -f "build/web/themes/custom/${theme}/package-lock.json" ]; then - pushd "build/web/themes/custom/${theme}/" > /dev/null || exit 1 - echo " > Installing theme assets." - if [ -f ".nvmrc" ]; then nvm use; fi - if [ ! -d "node_modules" ]; then npm ci; fi - popd > /dev/null || exit 1 -fi - -echo "-------------------------------" -echo " Starting builtin PHP server " -echo "-------------------------------" - -# Stop previously started services. -killall -9 php > /dev/null 2>&1 || true -# Start the PHP webserver. -nohup php -S "${WEBSERVER_HOST}:${WEBSERVER_PORT}" -t "$(pwd)/build/web" "$(pwd)/build/web/.ht.router.php" > /tmp/php.log 2>&1 & -sleep 4 # Waiting for the server to be ready. -netstat_opts='-tulpn'; [ "$(uname)" == "Darwin" ] && netstat_opts='-anv' || true; -# Check that the server was started. -netstat "${netstat_opts[@]}" | grep -q "${WEBSERVER_PORT}" || (echo "ERROR: Unable to start inbuilt PHP server" && cat /tmp/php.log && exit 1) -# Check that the server can serve content. -curl -s -o /dev/null -w "%{http_code}" -L -I "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" | grep -q 200 || (echo "ERROR: Server is started, but site cannot be served" && exit 1) -echo " > Started builtin PHP server at http://${WEBSERVER_HOST}:${WEBSERVER_PORT} in $(pwd)/build/web." - -echo "-------------------------------" -echo " Installing Drupal and themes " -echo "-------------------------------" - -echo " > Installing Drupal into SQLite database ${db_file}." -drush si "${DRUPAL_PROFILE}" -y --db-url "sqlite://${db_file}" --account-name=admin install_configure_form.enable_update_status_theme=NULL install_configure_form.enable_update_status_emails=NULL -drush status - -######################################## - -echo " > Enabling theme ${theme} dependent modules." -drush -r "build/web" php:eval "require_once dirname(\Drupal::getContainer()->get('theme_handler')->rebuildThemeData()['civictheme']->getPathname()) . '/theme-settings.provision.inc'; civictheme_enable_modules();" - -echo " > Enabling theme ${theme}." -drush -r "build/web" theme:install "${theme}" -y -drush -r "build/web" cr - -echo " > Setting theme ${theme} as default." -drush -r "build/web" config:set system.theme default "${theme}" -y - -echo " > Provisioning content from theme defaults." -drush -r "build/web" php:eval "require_once dirname(\Drupal::getContainer()->get('theme_handler')->rebuildThemeData()['civictheme']->getPathname()) . '/theme-settings.provision.inc'; civictheme_provision_cli();" - -######################################## - -echo " > Enabling suggested modules, if any." -drupal_suggests=$(cat composer.json | jq -r 'select(.suggest != null) | .suggest | keys[]' | sed "s/drupal\///" | cut -f1 -d":") -for drupal_suggest in $drupal_suggests; do - drush pm:enable "${drupal_suggest}" -y -done - -# Visit site to pre-warm caches. -curl -s "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" > /dev/null - -echo -echo "-------------------------------" -echo " Build finished 🚀🚀🚀" -echo "-------------------------------" -echo -echo " > Site URL: http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" -echo -n " > One-time login link: " -drush -l "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" uli --no-browser -echo -echo " > Available commands:" -echo " ahoy build # rebuild" -echo " ahoy lint # check code standards" -echo " ahoy test # run tests" -echo diff --git a/web/themes/contrib/civictheme/.devtools/deploy.sh b/web/themes/contrib/civictheme/.devtools/deploy.sh new file mode 100755 index 0000000000..dfdccf6411 --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/deploy.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +## +# Deploy code to a remote repository. +# +# - configures local git +# - force-pushes code to a remote code repository branch +# +# Add the following variables through CI provider UI. +# - DEPLOY_USER_NAME - name of the user who will be committing to a remote repository. +# - DEPLOY_USER_EMAIL - email address of the user who will be committing to a remote repository. +# - DEPLOY_REMOTE - remote repository to push code to. +# - DEPLOY_PROCEED - set to 1 if the deployment should proceed. Useful for testing CI configuration before an actual code push. + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +#------------------------------------------------------------------------------- +# Variables (passed from environment; provided for reference only). +#------------------------------------------------------------------------------- + +# Name of the user who will be committing to a remote repository. +DEPLOY_USER_NAME="${DEPLOY_USER_NAME:-}" + +# Email address of the user who will be committing to a remote repository. +DEPLOY_USER_EMAIL="${DEPLOY_USER_EMAIL:-}" + +# Remote repository to push code to. +DEPLOY_REMOTE="${DEPLOY_REMOTE:-}" + +# Git branch to deploy. If not provided - current branch will be used. +DEPLOY_BRANCH="${DEPLOY_BRANCH:-}" + +# Set to 1 if the deployment should proceed. Useful for testing CI configuration +# before an actual code push. +DEPLOY_PROCEED="${DEPLOY_PROCEED:-0}" + +# The fingerprint of the SSH key. +DEPLOY_SSH_KEY_FINGERPRINT="${DEPLOY_SSH_KEY_FINGERPRINT:-}" + +#------------------------------------------------------------------------------- + +# @formatter:off +note() { printf " %s\n" "${1}"; } +info() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[34m[INFO] %s\033[0m\n" "${1}" || printf "[INFO] %s\n" "${1}"; } +pass() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[32m[ OK ] %s\033[0m\n" "${1}" || printf "[ OK ] %s\n" "${1}"; } +fail() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[31m[FAIL] %s\033[0m\n" "${1}" || printf "[FAIL] %s\n" "${1}"; } +# @formatter:on + +#------------------------------------------------------------------------------- + +if [ -n "${DEPLOY_SSH_KEY_FINGERPRINT}" ]; then + echo "-------------------------------" + echo " Setup SSH " + echo "-------------------------------" + + mkdir -p "${HOME}/.ssh/" + echo -e "\nHost *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n" >"${HOME}/.ssh/config" + + # Find the MD5 hash if the SSH_KEY_FINGERPRINT starts with SHA256. + if [ "${DEPLOY_SSH_KEY_FINGERPRINT#SHA256:}" != "${DEPLOY_SSH_KEY_FINGERPRINT}" ]; then + for file in "${HOME}"/.ssh/id_rsa*; do + calculated_sha256_fingerprint=$(ssh-keygen -l -E sha256 -f "${file}" | awk '{print $2}') + if [ "${calculated_sha256_fingerprint}" = "${DEPLOY_SSH_KEY_FINGERPRINT}" ]; then + DEPLOY_SSH_KEY_FINGERPRINT=$(ssh-keygen -l -E md5 -f "${file}" | awk '{print $2}') + DEPLOY_SSH_KEY_FINGERPRINT="${DEPLOY_SSH_KEY_FINGERPRINT#MD5:}" + break + fi + done + fi + + file="${DEPLOY_SSH_KEY_FINGERPRINT//:/}" + file="${HOME}/.ssh/id_rsa_${file//\"/}" + + if [ ! -f "${file:-}" ]; then + fail "ERROR: Unable to find SSH key file ${file}." + exit 1 + fi + + if [ -z "${SSH_AGENT_PID:-}" ]; then + eval "$(ssh-agent)" + fi + + ssh-add -D + ssh-add "${file}" + ssh-add -l +fi + +echo "===============================" +echo " 🚚 DEPLOY " +echo "===============================" +echo + +[ -z "${DEPLOY_USER_NAME}" ] && fail "ERROR: Missing required value for DEPLOY_USER_NAME" && exit 1 +[ -z "${DEPLOY_USER_EMAIL}" ] && fail "ERROR: Missing required value for DEPLOY_USER_EMAIL" && exit 1 +[ -z "${DEPLOY_REMOTE}" ] && fail "ERROR: Missing required value for DEPLOY_REMOTE" && exit 1 + +[ "${DEPLOY_PROCEED}" != "1" ] && pass "Skip deployment because $DEPLOY_PROCEED is not set to 1" && exit 0 + +[ "$(git config --global user.name)" == "" ] && note "Configuring global git user name ${DEPLOY_USER_NAME}." && git config --global user.name "${DEPLOY_USER_NAME}" +[ "$(git config --global user.email)" == "" ] && note "Configuring global git user email ${DEPLOY_USER_EMAIL}." && git config --global user.email "${DEPLOY_USER_EMAIL}" + +note "Setting git to push to a matching remote branch." +git config --global push.default matching + +note "> Adding remote ${DEPLOY_REMOTE}." +git remote add deployremote "${DEPLOY_REMOTE}" + +if [ -z "${DEPLOY_BRANCH}" ]; then + DEPLOY_BRANCH="$(git symbolic-ref --short HEAD)" +fi + +info "Pushing code to branch ${DEPLOY_BRANCH}." +git push --force deployremote HEAD:"${DEPLOY_BRANCH}" +pass "Code pushed to ${DEPLOY_REMOTE}:${DEPLOY_BRANCH}." + +info "Pushing tags." +git push --force --tags deployremote || true +pass "Tags pushed to ${DEPLOY_REMOTE}." + +echo "===============================" +echo " 🚚 DEPLOY COMPLETE ✅ " +echo "===============================" +echo +echo "Remote URL : ${DEPLOY_REMOTE}" +echo "Remote branch : ${DEPLOY_BRANCH}" +echo +echo "> Next steps:" +echo " Navigate to Drupal.org and check that the code was successfully pushed." +echo diff --git a/web/themes/contrib/civictheme/.devtools/lint-fix.sh b/web/themes/contrib/civictheme/.devtools/lint-fix.sh deleted file mode 100755 index 2f99f9405e..0000000000 --- a/web/themes/contrib/civictheme/.devtools/lint-fix.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -## -# Run lint checks. -# - -set -eu -[ -n "${DEBUG:-}" ] && set -x - -BUILD_DIR="${BUILD_DIR:-build}" - -echo -echo "-------------------------------" -echo " Fixing theme code " -echo "-------------------------------" -echo - -echo " > Running Drupal Rector fixer." -"${BUILD_DIR}"/vendor/bin/rector --clear-cache - -echo " > Running PHPCS fixer." -"${BUILD_DIR}"/vendor/bin/phpcbf - diff --git a/web/themes/contrib/civictheme/.devtools/lint.sh b/web/themes/contrib/civictheme/.devtools/lint.sh deleted file mode 100755 index c6167020e8..0000000000 --- a/web/themes/contrib/civictheme/.devtools/lint.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -## -# Run lint checks. -# - -set -eu -[ -n "${DEBUG:-}" ] && set -x - -BUILD_DIR="${BUILD_DIR:-build}" - -echo -echo "-------------------------------" -echo " Linting theme code " -echo "-------------------------------" -echo - -echo " > Running PHPCS." -"${BUILD_DIR}"/vendor/bin/phpcs - -echo " > Running TWIGCS." -"${BUILD_DIR}"/vendor/bin/twigcs - -echo " > Running phpstan." -"${BUILD_DIR}"/vendor/bin/phpstan - -echo " > Running Drupal Rector." -"${BUILD_DIR}"/vendor/bin/rector --dry-run --clear-cache - -echo " > Running PHPMD." -"${BUILD_DIR}"/vendor/bin/phpmd . text phpmd.xml diff --git a/web/themes/contrib/civictheme/.devtools/process-artifacts.sh b/web/themes/contrib/civictheme/.devtools/process-artifacts.sh deleted file mode 100755 index bec5ee0dd0..0000000000 --- a/web/themes/contrib/civictheme/.devtools/process-artifacts.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -## -# Process test artifacts. -# -# This runs only in CI. -# - -set -eu -[ -n "${DEBUG:-}" ] && set -x - -if [ -d "$(pwd)/build/web/sites/simpletest/browser_output" ]; then - echo "==> Copying Simpletest test artifacts" - mkdir -p /tmp/artifacts/simpletest - cp -Rf "$(pwd)/build/web/sites/simpletest/browser_output/." /tmp/artifacts/simpletest -fi diff --git a/web/themes/contrib/civictheme/.devtools/provision.sh b/web/themes/contrib/civictheme/.devtools/provision.sh new file mode 100755 index 0000000000..ca6973ba3e --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/provision.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +## +# Provision a website using existing codebase. +# +# - Installs Drupal using SQLite database. +# - Enables modules +# - Serves site and generates one-time login link +# +# shellcheck disable=SC2015,SC2094,SC2002 + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +#------------------------------------------------------------------------------- +# Variables (passed from environment; provided for reference only). +#------------------------------------------------------------------------------- + +# Webserver hostname. +WEBSERVER_HOST="${WEBSERVER_HOST:-localhost}" + +# Webserver port. +WEBSERVER_PORT="${WEBSERVER_PORT:-8000}" + +# Drupal profile to use when installing the site. +DRUPAL_PROFILE="${DRUPAL_PROFILE:-standard}" + +#------------------------------------------------------------------------------- + +# @formatter:off +note() { printf " %s\n" "${1}"; } +info() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[34m[INFO] %s\033[0m\n" "${1}" || printf "[INFO] %s\n" "${1}"; } +pass() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[32m[ OK ] %s\033[0m\n" "${1}" || printf "[ OK ] %s\n" "${1}"; } +fail() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[31m[FAIL] %s\033[0m\n" "${1}" || printf "[FAIL] %s\n" "${1}"; } +# @formatter:on + +drush() { "build/vendor/bin/drush" -r "$(pwd)/build/web" -y "$@"; } + +#------------------------------------------------------------------------------- + +echo "===============================" +echo " 🚀 PROVISION " +echo "===============================" +echo + +# Extension name, taken from .info file. +extension="$(basename -s .info.yml -- ./*.info.yml)" +[ "${extension}" == "*" ] && fail "ERROR: No .info.yml file found." && exit 1 +extension_type="module" +if cat "${extension}.info.yml" | grep -Fq "type: theme"; then + extension_type="theme" +fi + +# Database file path. +db_file="/tmp/site_${extension}.sqlite" + +info "Installing Drupal into SQLite database ${db_file}." +drush site-install "${DRUPAL_PROFILE}" -y --db-url="sqlite://localhost/${db_file}" --account-name=admin install_configure_form.enable_update_status_module=NULL install_configure_form.enable_update_status_emails=NULL + +pass "Drupal installed." + +drush status + +######################################## +# CIVICTHEME SPECIFIC +######################################## + +info "Enabling extension ${extension}." +drush -r "build/web" php:eval "require_once dirname(\Drupal::getContainer()->get('theme_handler')->rebuildThemeData()['civictheme']->getPathname()) . '/theme-settings.provision.inc'; civictheme_enable_modules();" + +######################################## + +echo " > Enabling theme ${extension} dependent modules." +if [ "${extension_type}" = "theme" ]; then + drush theme:enable "${extension}" -y +else + drush pm:enable "${extension}" -y +fi + +info "Clearing caches." +drush cr + +######################################## +# CIVICTHEME SPECIFIC +######################################## + +echo " > Setting theme ${extension} as default." +drush -r "build/web" config:set system.theme default "${extension}" -y + +echo " > Provisioning content from theme defaults." +drush -r "build/web" php:eval "require_once dirname(\Drupal::getContainer()->get('theme_handler')->rebuildThemeData()['civictheme']->getPathname()) . '/theme-settings.provision.inc'; civictheme_provision_cli();" + +######################################## + +info "Enabling suggested modules, if any." +drupal_suggests=$(cat composer.json | jq -r 'select(.suggest != null) | .suggest | keys[]' | sed "s/drupal\///" | cut -f1 -d":") +for drupal_suggest in $drupal_suggests; do + drush pm:enable "${drupal_suggest}" -y +done +pass "Suggested modules enabled." + +info "Pre-warming caches." +curl -s "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" >/dev/null + +echo +echo "===============================" +echo " 🚀 PROVISION COMPLETE ✅ " +echo "===============================" +echo +echo "Site URL: http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" +echo -n "One-time login link: " +drush -l "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" uli --no-browser +echo +echo "> Available commands:" +echo " ahoy build # Rebuild" +echo " ahoy lint # Check coding standards" +echo " ahoy test # Run tests" +echo diff --git a/web/themes/contrib/civictheme/.devtools/start.sh b/web/themes/contrib/civictheme/.devtools/start.sh new file mode 100755 index 0000000000..7eb950553e --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/start.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +## +# Start development environment. +# +# shellcheck disable=SC2015,SC2094,SC2002 + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +#------------------------------------------------------------------------------- +# Variables (passed from environment; provided for reference only). +#------------------------------------------------------------------------------- + +# Webserver hostname. +WEBSERVER_HOST="${WEBSERVER_HOST:-localhost}" + +# Webserver port. +WEBSERVER_PORT="${WEBSERVER_PORT:-8000}" + +# Webserver wait timeout. +WEBSERVER_WAIT_TIMEOUT="${WEBSERVER_WAIT_TIMEOUT:-5}" + +#------------------------------------------------------------------------------- + +# @formatter:off +note() { printf " %s\n" "${1}"; } +info() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[34m[INFO] %s\033[0m\n" "${1}" || printf "[INFO] %s\n" "${1}"; } +pass() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[32m[ OK ] %s\033[0m\n" "${1}" || printf "[ OK ] %s\n" "${1}"; } +fail() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[31m[FAIL] %s\033[0m\n" "${1}" || printf "[FAIL] %s\n" "${1}"; } +# @formatter:on + +#------------------------------------------------------------------------------- + +echo "===============================" +echo " 💻 START ENVIRONMENT " +echo "===============================" +echo + +info "Stopping previously started services, if any." +killall -9 php >/dev/null 2>&1 || true + +info "Starting the PHP webserver." +nohup php -S "${WEBSERVER_HOST}:${WEBSERVER_PORT}" -t "$(pwd)/build/web" "$(pwd)/build/web/.ht.router.php" >/tmp/php.log 2>&1 & + +note "Waiting ${WEBSERVER_WAIT_TIMEOUT} seconds for the server to be ready." +sleep "${WEBSERVER_WAIT_TIMEOUT}" + +note "Checking that the server was started." +netstat_opts='-tulpn' +[ "$(uname)" == "Darwin" ] && netstat_opts='-anv' || true +netstat "${netstat_opts[@]}" | grep -q "${WEBSERVER_PORT}" || (echo "ERROR: Unable to start inbuilt PHP server" && cat /tmp/php.log && exit 1) + +pass "Server started successfully." + +info "Checking that the server can serve content." +curl -s -o /dev/null -w "%{http_code}" -L -I "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" | grep -q 200 || (echo "ERROR: Server is started, but site cannot be served" && exit 1) +pass "Server can serve content." + +echo +echo "===============================" +echo " 💻 ENVIRONMENT READY ✅ " +echo "===============================" +echo +echo "Directory : $(pwd)/build/web" +echo "URL : http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" +echo +echo "Re-run when you enable or disable XDebug." +echo +echo "> Next steps:" +echo " .devtools/provision.sh # Provision the website" +echo diff --git a/web/themes/contrib/civictheme/.devtools/stop.sh b/web/themes/contrib/civictheme/.devtools/stop.sh new file mode 100755 index 0000000000..d629d6f08d --- /dev/null +++ b/web/themes/contrib/civictheme/.devtools/stop.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +## +# Stop development environment. +# +# shellcheck disable=SC2015,SC2094,SC2002 + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +#------------------------------------------------------------------------------- + +# @formatter:off +note() { printf " %s\n" "${1}"; } +info() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[34m[INFO] %s\033[0m\n" "${1}" || printf "[INFO] %s\n" "${1}"; } +pass() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[32m[ OK ] %s\033[0m\n" "${1}" || printf "[ OK ] %s\n" "${1}"; } +fail() { [ "${TERM:-}" != "dumb" ] && tput colors >/dev/null 2>&1 && printf "\033[31m[FAIL] %s\033[0m\n" "${1}" || printf "[FAIL] %s\n" "${1}"; } +# @formatter:on + +#------------------------------------------------------------------------------- + +echo "===============================" +echo " 💻 STOP ENVIRONMENT " +echo "===============================" +echo + +info "Stopping previously started services, if any." +killall -9 php >/dev/null 2>&1 || true +sleep 1 +pass "Services stopped." + +echo +echo "===============================" +echo " 💻 ENVIRONMENT STOPPED ✅ " +echo "===============================" +echo diff --git a/web/themes/contrib/civictheme/.devtools/test.sh b/web/themes/contrib/civictheme/.devtools/test.sh deleted file mode 100755 index e9b2bc1393..0000000000 --- a/web/themes/contrib/civictheme/.devtools/test.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -## -# Run tests. -# - -set -eu -[ -n "${DEBUG:-}" ] && set -x - -#------------------------------------------------------------------------------- -# Variables (passed from environment; provided for reference only). -#------------------------------------------------------------------------------- - -# Webserver hostname. -WEBSERVER_HOST="${WEBSERVER_HOST:-localhost}" - -# Webserver port. -WEBSERVER_PORT="${WEBSERVER_PORT:-8000}" - -# Directory to store test results. -TEST_RESULTS_DIR="${TEST_RESULTS_DIR:-/tmp/test_results/simpletest}" - -#------------------------------------------------------------------------------- - -echo "==> Run tests." - -# Do not fail if there are no tests. -[ ! -d "tests" ] && echo "==> No tests were found. Skipping." && exit 0 - -# Module name, taken from .info file. -theme="$(basename -s .info.yml -- ./*.info.yml)" -[ "${theme}" == "*" ] && echo "ERROR: No .info.yml file found." && exit 1 - -# Test database file path. -test_db_file="/tmp/test_${theme}.sqlite" - -# Re-create test results directory. -rm -rf "${TEST_RESULTS_DIR}" > /dev/null -mkdir -p "${TEST_RESULTS_DIR}" - -# Remove existing test DB file. -rm -f "${test_db_file}" > /dev/null - -# Run tests using script provided by Drupal. -php "./build/web/core/scripts/run-tests.sh" \ - --sqlite "${test_db_file}" \ - --dburl "sqlite://localhost/${test_db_file}" \ - --url "http://${WEBSERVER_HOST}:${WEBSERVER_PORT}" \ - --non-html \ - --xml "${TEST_RESULTS_DIR}" \ - --color \ - --verbose \ - --suppress-deprecations \ - --module "${theme}" diff --git a/web/themes/contrib/civictheme/.twig-cs-fixer.php b/web/themes/contrib/civictheme/.twig-cs-fixer.php new file mode 100644 index 0000000000..0ba5c63fbc --- /dev/null +++ b/web/themes/contrib/civictheme/.twig-cs-fixer.php @@ -0,0 +1,17 @@ +addStandard(new TwigCsFixer\Standard\Twig()); + +$finder = new TwigCsFixer\File\Finder(); +$finder->in(__DIR__ . '/templates'); +$finder->in(__DIR__ . '/civictheme_starter_kit/components'); +$finder->in(__DIR__ . '/civictheme_starter_kit/templates'); + +$config = new TwigCsFixer\Config\Config(); +$config->setRuleset($ruleset); +$config->setFinder($finder); + +return $config; diff --git a/web/themes/contrib/civictheme/.twig_cs.php b/web/themes/contrib/civictheme/.twig_cs.php deleted file mode 100644 index 68b90d424f..0000000000 --- a/web/themes/contrib/civictheme/.twig_cs.php +++ /dev/null @@ -1,16 +0,0 @@ -setName('custom-config') - ->setSeverity('error') - ->setReporter('console') - ->setRuleSet(Twigcs\Ruleset\Official::class) - ->addFinder(Twigcs\Finder\TemplateFinder::create()->in([ - __DIR__ . '/templates', - __DIR__ . '/civictheme_starter_kit/components', - __DIR__ . '/civictheme_starter_kit/templates', - ])->followLinks()); diff --git a/web/themes/contrib/civictheme/README.md b/web/themes/contrib/civictheme/README.md index 694db08d1a..6e1fe40f34 100644 --- a/web/themes/contrib/civictheme/README.md +++ b/web/themes/contrib/civictheme/README.md @@ -38,6 +38,47 @@ See [Color selector](https://docs.civictheme.io/development/drupal-theme/color-s ## Development +### Local development + +Provided that you have PHP installed locally, you can develop an extension using +the provided scripts. + +#### Build + +Run `.devtools/assemble.sh` (or `ahoy assemble` +if [Ahoy](https://github.com/ahoy-cli/ahoy) is installed) to start inbuilt PHP +server locally and run the same commands as in CI, plus installing a site and +your extension automatically. + +#### Code linting + +Run tools individually (or `ahoy lint` to run all tools +if [Ahoy](https://github.com/ahoy-cli/ahoy) is installed) to lint your code +according to +the [Drupal coding standards](https://www.drupal.org/docs/develop/standards). + +``` +cd build + +vendor/bin/phpcs +vendor/bin/phpstan +vendor/bin/rector --clear-cache --dry-run +vendor/bin/phpmd . text phpmd.xml +vendor/bin/twig-cs-fixer +``` + +- PHPCS config: [`phpcs.xml`](phpcs.xml) +- PHPStan config: [`phpstan.neon`](phpstan.neon) +- PHPMD config: [`phpmd.xml`](phpmd.xml) +- Rector config: [`rector.php`](rector.php) +- Twig CS Fixer config: [`.twig-cs-fixer.php`](.twig-cs-fixer.php) + +### Browsing SQLite database + +To browse the contents of created SQLite database +(located at `/tmp/site_[EXTENSION_NAME].sqlite`), +use [DB Browser for SQLite](https://sqlitebrowser.org/). + ### Switching to a new version of the UI Kit The UI Kit is included as a dependency in the `package.json` file and then diff --git a/web/themes/contrib/civictheme/composer.dev.json b/web/themes/contrib/civictheme/composer.dev.json new file mode 100644 index 0000000000..84ae2445a3 --- /dev/null +++ b/web/themes/contrib/civictheme/composer.dev.json @@ -0,0 +1,23 @@ +{ + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "jangregor/phpstan-prophecy": "^1.0", + "mglaman/phpstan-drupal": "^1.2", + "palantirnet/drupal-rector": "^0.18", + "phpcompatibility/php-compatibility": "^9.3", + "phpmd/phpmd": "^2.15", + "phpspec/prophecy-phpunit": "^2", + "phpstan/extension-installer": "^1.3", + "vincentlanglet/twig-cs-fixer": "^2.8" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true + } + }, + "extra": { + "phpcodesniffer-search-depth": 10, + "patches": {} + } +} diff --git a/web/themes/contrib/civictheme/phpunit.xml b/web/themes/contrib/civictheme/phpunit.xml new file mode 100644 index 0000000000..47285753fa --- /dev/null +++ b/web/themes/contrib/civictheme/phpunit.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + web/modules/custom/*/tests/src/Unit + web/themes/custom/*/tests/src/Unit + + + web/modules/custom/*/tests/src/Kernel + web/themes/custom/*/tests/src/Kernel + + + web/modules/custom/*/tests/src/Functional + web/themes/custom/*/tests/src/Functional + + + + + + + + + + + + + + + web/modules/custom + web/themes/custom + + + + web/modules/custom/*/tests + web/themes/custom/*/tests + web/modules/custom/civictheme/rector.php + web/themes/custom/civictheme/rector.php + + + + + + + +