524 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			524 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| 
								 | 
							
								#!/bin/bash
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# This script performs code quality checks.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# @internal
							 | 
						||
| 
								 | 
							
								#   This script is not covered by Drupal core's backwards compatibility promise.
							 | 
						||
| 
								 | 
							
								#   It exists only for core development purposes.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# The script makes the following checks:
							 | 
						||
| 
								 | 
							
								# - Spell checking.
							 | 
						||
| 
								 | 
							
								# - File modes.
							 | 
						||
| 
								 | 
							
								# - No changes to core/node_modules directory.
							 | 
						||
| 
								 | 
							
								# - PHPCS checks PHP and YAML files.
							 | 
						||
| 
								 | 
							
								# - PHPStan checks PHP files.
							 | 
						||
| 
								 | 
							
								# - ESLint checks JavaScript and YAML files.
							 | 
						||
| 
								 | 
							
								# - Stylelint checks CSS files.
							 | 
						||
| 
								 | 
							
								# - Checks .pcss.css and .css files are equivalent.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# cSpell:disable
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Searches an array.
							 | 
						||
| 
								 | 
							
								contains_element() {
							 | 
						||
| 
								 | 
							
								  local e
							 | 
						||
| 
								 | 
							
								  for e in ${@:2}; do [[ "$e" == "$1" ]] && return 0; done
							 | 
						||
| 
								 | 
							
								  return 1
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MEMORY_UNLIMITED=0
							 | 
						||
| 
								 | 
							
								CACHED=0
							 | 
						||
| 
								 | 
							
								DRUPALCI=0
							 | 
						||
| 
								 | 
							
								BRANCH=""
							 | 
						||
| 
								 | 
							
								while test $# -gt 0; do
							 | 
						||
| 
								 | 
							
								  case "$1" in
							 | 
						||
| 
								 | 
							
								    -h|--help)
							 | 
						||
| 
								 | 
							
								      echo "Drupal code quality checks"
							 | 
						||
| 
								 | 
							
								      echo " "
							 | 
						||
| 
								 | 
							
								      echo "options:"
							 | 
						||
| 
								 | 
							
								      echo "-h, --help                show brief help"
							 | 
						||
| 
								 | 
							
								      echo "--branch BRANCH           creates list of files to check by comparing against a branch"
							 | 
						||
| 
								 | 
							
								      echo "--cached                  checks staged files"
							 | 
						||
| 
								 | 
							
								      echo "--drupalci                a special mode for DrupalCI"
							 | 
						||
| 
								 | 
							
								      echo " "
							 | 
						||
| 
								 | 
							
								      echo "Example usage: sh ./core/scripts/dev/commit-code-check.sh --branch 9.2.x"
							 | 
						||
| 
								 | 
							
								      exit 0
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								    --branch)
							 | 
						||
| 
								 | 
							
								      BRANCH="$2"
							 | 
						||
| 
								 | 
							
								      if [[ "$BRANCH" == "" ]]; then
							 | 
						||
| 
								 | 
							
								        printf "The --branch option requires a value. For example: --branch 9.2.x\n"
							 | 
						||
| 
								 | 
							
								        exit;
							 | 
						||
| 
								 | 
							
								      fi
							 | 
						||
| 
								 | 
							
								      shift 2
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								    --cached)
							 | 
						||
| 
								 | 
							
								      CACHED=1
							 | 
						||
| 
								 | 
							
								      shift
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								    --drupalci)
							 | 
						||
| 
								 | 
							
								      DRUPALCI=1
							 | 
						||
| 
								 | 
							
								      shift
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								    --memory-unlimited)
							 | 
						||
| 
								 | 
							
								      MEMORY_UNLIMITED=1
							 | 
						||
| 
								 | 
							
								      shift
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								    *)
							 | 
						||
| 
								 | 
							
								      break
							 | 
						||
| 
								 | 
							
								      ;;
							 | 
						||
| 
								 | 
							
								  esac
							 | 
						||
| 
								 | 
							
								done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								memory_limit=""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [[ "$MEMORY_UNLIMITED" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  memory_limit="--memory-limit=-1"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Set up variables to make colored output simple. Color output is disabled on
							 | 
						||
| 
								 | 
							
								# DrupalCI because it is breaks reporting.
							 | 
						||
| 
								 | 
							
								# @todo https://www.drupal.org/project/drupalci_testbot/issues/3181869
							 | 
						||
| 
								 | 
							
								if [[ "$DRUPALCI" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  red=""
							 | 
						||
| 
								 | 
							
								  green=""
							 | 
						||
| 
								 | 
							
								  reset=""
							 | 
						||
| 
								 | 
							
								  DRUPAL_VERSION=$(php -r "include 'vendor/autoload.php'; print preg_replace('#\.[0-9]+-dev#', '.x', \Drupal::VERSION);")
							 | 
						||
| 
								 | 
							
								  GIT="sudo -u www-data git"
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  red=$(tput setaf 1 && tput bold)
							 | 
						||
| 
								 | 
							
								  green=$(tput setaf 2)
							 | 
						||
| 
								 | 
							
								  reset=$(tput sgr0)
							 | 
						||
| 
								 | 
							
								  GIT="git"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Gets list of files to check.
							 | 
						||
| 
								 | 
							
								if [[ "$BRANCH" != "" ]]; then
							 | 
						||
| 
								 | 
							
								  FILES=$($GIT diff --name-only $BRANCH HEAD);
							 | 
						||
| 
								 | 
							
								elif [[ "$CACHED" == "0" ]]; then
							 | 
						||
| 
								 | 
							
								  # For DrupalCI patch testing or when running without --cached or --branch,
							 | 
						||
| 
								 | 
							
								  # list of all changes in the working directory.
							 | 
						||
| 
								 | 
							
								  FILES=$($GIT ls-files --other --modified --exclude-standard --exclude=vendor)
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  # Check staged files only.
							 | 
						||
| 
								 | 
							
								  if $GIT rev-parse --verify HEAD >/dev/null 2>&1
							 | 
						||
| 
								 | 
							
								  then
							 | 
						||
| 
								 | 
							
								    AGAINST=HEAD
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    # Initial commit: diff against an empty tree object
							 | 
						||
| 
								 | 
							
								    AGAINST=4b825dc642cb6eb9a060e54bf8d69288fbee4904
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  FILES=$($GIT diff --cached --name-only $AGAINST);
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [[ "$FILES" == "" ]] && [[ "$DRUPALCI" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  # If the FILES is empty we might be testing a merge request on DrupalCI. We
							 | 
						||
| 
								 | 
							
								  # need to diff against the Drupal branch or tag related to the Drupal version.
							 | 
						||
| 
								 | 
							
								  printf "Creating list of files to check by comparing branch to %s\n" "$DRUPAL_VERSION"
							 | 
						||
| 
								 | 
							
								  # On DrupalCI there's a merge commit so we can compare to HEAD~1.
							 | 
						||
| 
								 | 
							
								  FILES=$($GIT diff --name-only HEAD~1 HEAD);
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TOP_LEVEL=$($GIT rev-parse --show-toplevel)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when the file core/phpcs.xml.dist is changed.
							 | 
						||
| 
								 | 
							
								PHPCS_XML_DIST_FILE_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when the files core/.phpstan-baseline.php or
							 | 
						||
| 
								 | 
							
								# core/phpstan.neon.dist are changed.
							 | 
						||
| 
								 | 
							
								PHPSTAN_DIST_FILE_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when one of the eslint config file is
							 | 
						||
| 
								 | 
							
								# changed:
							 | 
						||
| 
								 | 
							
								#  - core/.eslintrc.passing.json
							 | 
						||
| 
								 | 
							
								#  - core/.eslintrc.json
							 | 
						||
| 
								 | 
							
								#  - core/.eslintrc.jquery.json
							 | 
						||
| 
								 | 
							
								ESLINT_CONFIG_PASSING_FILE_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when the stylelint config file is changed.
							 | 
						||
| 
								 | 
							
								# changed:
							 | 
						||
| 
								 | 
							
								#  - core/.stylelintignore
							 | 
						||
| 
								 | 
							
								#  - core/.stylelintrc.json
							 | 
						||
| 
								 | 
							
								STYLELINT_CONFIG_FILE_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when JavaScript packages files are changed.
							 | 
						||
| 
								 | 
							
								# changed:
							 | 
						||
| 
								 | 
							
								#  - core/package.json
							 | 
						||
| 
								 | 
							
								#  - core/yarn.lock
							 | 
						||
| 
								 | 
							
								JAVASCRIPT_PACKAGES_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set when a Drupal-specific CKEditor 5 plugin has changed
							 | 
						||
| 
								 | 
							
								# it is used to make sure the compiled JS is valid.
							 | 
						||
| 
								 | 
							
								CKEDITOR5_PLUGINS_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This variable will be set to one when either of the core dictionaries or the
							 | 
						||
| 
								 | 
							
								# .cspell.json config has changed.
							 | 
						||
| 
								 | 
							
								CSPELL_DICTIONARY_FILE_CHANGED=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Build up a list of absolute file names.
							 | 
						||
| 
								 | 
							
								ABS_FILES=
							 | 
						||
| 
								 | 
							
								for FILE in $FILES; do
							 | 
						||
| 
								 | 
							
								  if [ -f "$TOP_LEVEL/$FILE" ]; then
							 | 
						||
| 
								 | 
							
								    ABS_FILES="$ABS_FILES $TOP_LEVEL/$FILE"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/phpcs.xml.dist" ]]; then
							 | 
						||
| 
								 | 
							
								    PHPCS_XML_DIST_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/.phpstan-baseline.php" || $FILE == "core/phpstan.neon.dist" ]]; then
							 | 
						||
| 
								 | 
							
								    PHPSTAN_DIST_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/.eslintrc.json" || $FILE == "core/.eslintrc.passing.json" || $FILE == "core/.eslintrc.jquery.json" ]]; then
							 | 
						||
| 
								 | 
							
								    ESLINT_CONFIG_PASSING_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/.stylelintignore" || $FILE == "core/.stylelintrc.json" ]]; then
							 | 
						||
| 
								 | 
							
								    STYLELINT_CONFIG_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # If JavaScript packages change, then rerun all JavaScript style checks.
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/package.json" || $FILE == "core/yarn.lock" ]]; then
							 | 
						||
| 
								 | 
							
								    ESLINT_CONFIG_PASSING_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								    STYLELINT_CONFIG_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								    JAVASCRIPT_PACKAGES_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]] && [[ $FILE =~ ^core/modules/ckeditor5/js/build || $FILE =~ ^core/modules/ckeditor5/js/ckeditor5_plugins ]]; then
							 | 
						||
| 
								 | 
							
								    CKEDITOR5_PLUGINS_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ $FILE == "core/misc/cspell/dictionary.txt" || $FILE == "core/misc/cspell/drupal-dictionary.txt" || $FILE == "core/.cspell.json" ]]; then
							 | 
						||
| 
								 | 
							
								    CSPELL_DICTIONARY_FILE_CHANGED=1;
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Exit early if there are no files.
							 | 
						||
| 
								 | 
							
								if [[ "$ABS_FILES" == "" ]]; then
							 | 
						||
| 
								 | 
							
								  printf "There are no files to check. If you have staged a commit use the --cached option.\n"
							 | 
						||
| 
								 | 
							
								  exit;
							 | 
						||
| 
								 | 
							
								fi;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# This script assumes that composer install and yarn install have already been
							 | 
						||
| 
								 | 
							
								# run and all dependencies are updated.
							 | 
						||
| 
								 | 
							
								FINAL_STATUS=0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEPENDENCIES_NEED_INSTALLING=0
							 | 
						||
| 
								 | 
							
								# Ensure PHP development dependencies are installed.
							 | 
						||
| 
								 | 
							
								# @todo https://github.com/composer/composer/issues/4497 Improve this to
							 | 
						||
| 
								 | 
							
								#  determine if dependencies in the lock file match the installed versions.
							 | 
						||
| 
								 | 
							
								#  Using composer install --dry-run is not valid because it would depend on
							 | 
						||
| 
								 | 
							
								#  user-facing strings in Composer.
							 | 
						||
| 
								 | 
							
								if ! [[ -f 'vendor/bin/phpcs' ]]; then
							 | 
						||
| 
								 | 
							
								  printf "Drupal's PHP development dependencies are not installed. Run 'composer install' from the root directory.\n"
							 | 
						||
| 
								 | 
							
								  DEPENDENCIES_NEED_INSTALLING=1;
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Ensure JavaScript development dependencies are installed.
							 | 
						||
| 
								 | 
							
								yarn --version
							 | 
						||
| 
								 | 
							
								yarn >/dev/null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Check all files for spelling in one go for better performance.
							 | 
						||
| 
								 | 
							
								if [[ $CSPELL_DICTIONARY_FILE_CHANGED == "1" ]] ; then
							 | 
						||
| 
								 | 
							
								  printf "\nRunning spellcheck on *all* files.\n"
							 | 
						||
| 
								 | 
							
								  yarn run spellcheck:core --no-must-find-files --no-progress
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  # Check all files for spelling in one go for better performance. We pipe the
							 | 
						||
| 
								 | 
							
								  # list files in so we obey the globs set on the spellcheck:core command in
							 | 
						||
| 
								 | 
							
								  # core/package.json.
							 | 
						||
| 
								 | 
							
								  echo "${ABS_FILES}" | tr ' ' '\n' | yarn run spellcheck:core --no-must-find-files --file-list stdin
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [ "$?" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								  # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								  FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								  printf "\nCSpell: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  printf "\nCSpell: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								cd "$TOP_LEVEL"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								printf "\n"
							 | 
						||
| 
								 | 
							
								printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								printf "\n"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Run PHPStan on all files on DrupalCI or when phpstan files are changed.
							 | 
						||
| 
								 | 
							
								# APCu is disabled to ensure that the composer classmap is not corrupted.
							 | 
						||
| 
								 | 
							
								if [[ $PHPSTAN_DIST_FILE_CHANGED == "1" ]] || [[ "$DRUPALCI" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  printf "\nRunning PHPStan on *all* files.\n"
							 | 
						||
| 
								 | 
							
								  php -d apc.enabled=0 -d apc.enable_cli=0 vendor/bin/phpstan analyze --no-progress --configuration="$TOP_LEVEL/core/phpstan.neon.dist" $memory_limit
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  # Only run PHPStan on changed files locally.
							 | 
						||
| 
								 | 
							
								  printf "\nRunning PHPStan on changed files.\n"
							 | 
						||
| 
								 | 
							
								  php -d apc.enabled=0 -d apc.enable_cli=0 vendor/bin/phpstan analyze --no-progress --configuration="$TOP_LEVEL/core/phpstan-partial.neon" $ABS_FILES $memory_limit
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [ "$?" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								  # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								  FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								  printf "\nPHPStan: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								else
							 | 
						||
| 
								 | 
							
								  printf "\nPHPStan: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								printf "\n"
							 | 
						||
| 
								 | 
							
								printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								printf "\n"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Run PHPCS on all files on DrupalCI or when phpcs files are changed.
							 | 
						||
| 
								 | 
							
								if [[ $PHPCS_XML_DIST_FILE_CHANGED == "1" ]] || [[ "$DRUPALCI" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  # Test all files with phpcs rules.
							 | 
						||
| 
								 | 
							
								  vendor/bin/phpcs -ps --parallel="$( (nproc || sysctl -n hw.logicalcpu || echo 4) 2>/dev/null)" --standard="$TOP_LEVEL/core/phpcs.xml.dist"
							 | 
						||
| 
								 | 
							
								  PHPCS=$?
							 | 
						||
| 
								 | 
							
								  if [ "$PHPCS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								    # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    printf "\nPHPCS: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    printf "\nPHPCS: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  # Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# When the eslint config has been changed, then eslint must check all files.
							 | 
						||
| 
								 | 
							
								if [[ $ESLINT_CONFIG_PASSING_FILE_CHANGED == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								  yarn run lint:core-js-passing "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								  CORRECTJS=$?
							 | 
						||
| 
								 | 
							
								  if [ "$CORRECTJS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								    # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    printf "\neslint: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    printf "\neslint: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  # Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# When the stylelint config has been changed, then stylelint must check all files.
							 | 
						||
| 
								 | 
							
								if [[ $STYLELINT_CONFIG_FILE_CHANGED == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								  yarn run lint:css
							 | 
						||
| 
								 | 
							
								  if [ "$?" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								    # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    printf "\nstylelint: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    printf "\nstylelint: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  # Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# When a Drupal-specific CKEditor 5 plugin changed ensure that it is compiled
							 | 
						||
| 
								 | 
							
								# properly. Only check on DrupalCI, since we're concerned about the build being
							 | 
						||
| 
								 | 
							
								# run with the expected package versions and making sure the result of the build
							 | 
						||
| 
								 | 
							
								# is in sync and conform to expectations.
							 | 
						||
| 
								 | 
							
								if [[ "$DRUPALCI" == "1" ]] && [[ $CKEDITOR5_PLUGINS_CHANGED == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								  yarn run check:ckeditor5
							 | 
						||
| 
								 | 
							
								  if [ "$?" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								    # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    printf "\nDrupal-specific CKEditor 5 plugins: ${red}failed${reset}\n"
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    printf "\nDrupal-specific CKEditor 5 plugins: ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  # Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# When JavaScript packages change, then rerun all JavaScript style checks.
							 | 
						||
| 
								 | 
							
								if [[ "$JAVASCRIPT_PACKAGES_CHANGED" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								  yarn run build:css --check
							 | 
						||
| 
								 | 
							
								  CORRECTCSS=$?
							 | 
						||
| 
								 | 
							
								  if [ "$CORRECTCSS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    printf "\n${red}ERROR: The compiled CSS from the PCSS files"
							 | 
						||
| 
								 | 
							
								    printf "\n       does not match the current CSS files. Some added"
							 | 
						||
| 
								 | 
							
								    printf "\n       or updated JavaScript package made changes."
							 | 
						||
| 
								 | 
							
								    printf "\n       Recompile the CSS with: yarn run build:css${reset}\n\n"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  # Add a separator line to make the output easier to read.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								for FILE in $FILES; do
							 | 
						||
| 
								 | 
							
								  STATUS=0;
							 | 
						||
| 
								 | 
							
								  # Print a line to separate spellcheck output from per file output.
							 | 
						||
| 
								 | 
							
								  printf "Checking %s\n" "$FILE"
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # Ensure the file still exists (i.e. is not being deleted).
							 | 
						||
| 
								 | 
							
								  if [ -a $FILE ]; then
							 | 
						||
| 
								 | 
							
								    if [ ${FILE: -3} != ".sh" ]; then
							 | 
						||
| 
								 | 
							
								      if [ -x $FILE ]; then
							 | 
						||
| 
								 | 
							
								        printf "${red}check failed:${reset} file $FILE should not be executable\n"
							 | 
						||
| 
								 | 
							
								        STATUS=1
							 | 
						||
| 
								 | 
							
								      fi
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # Don't commit changes to vendor.
							 | 
						||
| 
								 | 
							
								  if [[ "$FILE" =~ ^vendor/ ]]; then
							 | 
						||
| 
								 | 
							
								    printf "${red}check failed:${reset} file in vendor directory being committed ($FILE)\n"
							 | 
						||
| 
								 | 
							
								    STATUS=1
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # Don't commit changes to core/node_modules.
							 | 
						||
| 
								 | 
							
								  if [[ "$FILE" =~ ^core/node_modules/ ]]; then
							 | 
						||
| 
								 | 
							
								    printf "${red}check failed:${reset} file in core/node_modules directory being committed ($FILE)\n"
							 | 
						||
| 
								 | 
							
								    STATUS=1
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  ### PHP AND YAML FILES
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.(inc|install|module|php|profile|test|theme|yml)$ ]] && [[ $PHPCS_XML_DIST_FILE_CHANGED == "0" ]] && [[ "$DRUPALCI" == "0" ]]; then
							 | 
						||
| 
								 | 
							
								    # Test files with phpcs rules.
							 | 
						||
| 
								 | 
							
								    vendor/bin/phpcs "$TOP_LEVEL/$FILE" --standard="$TOP_LEVEL/core/phpcs.xml.dist"
							 | 
						||
| 
								 | 
							
								    PHPCS=$?
							 | 
						||
| 
								 | 
							
								    if [ "$PHPCS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								      # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								      STATUS=1
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      printf "PHPCS: $FILE ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  ### YAML FILES
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.yml$ ]]; then
							 | 
						||
| 
								 | 
							
								    # Test files with ESLint.
							 | 
						||
| 
								 | 
							
								    cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								    node ./node_modules/eslint/bin/eslint.js --quiet --resolve-plugins-relative-to . "$TOP_LEVEL/$FILE"
							 | 
						||
| 
								 | 
							
								    YAMLLINT=$?
							 | 
						||
| 
								 | 
							
								    if [ "$YAMLLINT" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								      # If there are failures set the status to a number other than 0.
							 | 
						||
| 
								 | 
							
								      STATUS=1
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      printf "ESLint: $FILE ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  ### JAVASCRIPT FILES
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]]; then
							 | 
						||
| 
								 | 
							
								    cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								    # Check the coding standards.
							 | 
						||
| 
								 | 
							
								    node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json "$TOP_LEVEL/$FILE"
							 | 
						||
| 
								 | 
							
								    JSLINT=$?
							 | 
						||
| 
								 | 
							
								    if [ "$JSLINT" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								      # No need to write any output the node command will do this for us.
							 | 
						||
| 
								 | 
							
								      STATUS=1
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      printf "ESLint: $FILE ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  ### CSS FILES
							 | 
						||
| 
								 | 
							
								  ############################################################################
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.css$ ]]; then
							 | 
						||
| 
								 | 
							
								    # Work out the root name of the CSS so we can ensure that the PostCSS
							 | 
						||
| 
								 | 
							
								    # version has been compiled correctly.
							 | 
						||
| 
								 | 
							
								    if [[ $FILE =~ \.pcss\.css$ ]]; then
							 | 
						||
| 
								 | 
							
								      BASENAME=${FILE%.pcss.css}
							 | 
						||
| 
								 | 
							
								      COMPILE_CHECK=1
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      BASENAME=${FILE%.css}
							 | 
						||
| 
								 | 
							
								      # We only need to compile check if the .pcss.css file is not also
							 | 
						||
| 
								 | 
							
								      # changing. This is because the compile check will occur for the
							 | 
						||
| 
								 | 
							
								      # .pcss.css file. This might occur if the compiled stylesheets have
							 | 
						||
| 
								 | 
							
								      # changed.
							 | 
						||
| 
								 | 
							
								      contains_element "$BASENAME.pcss.css" "${FILES[@]}"
							 | 
						||
| 
								 | 
							
								      HASPOSTCSS=$?
							 | 
						||
| 
								 | 
							
								      if [ "$HASPOSTCSS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								        COMPILE_CHECK=1
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        COMPILE_CHECK=0
							 | 
						||
| 
								 | 
							
								      fi
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    # PostCSS
							 | 
						||
| 
								 | 
							
								    if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.pcss.css" ]]; then
							 | 
						||
| 
								 | 
							
								      cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								      yarn run build:css --check --file "$TOP_LEVEL/$BASENAME.pcss.css"
							 | 
						||
| 
								 | 
							
								      CORRECTCSS=$?
							 | 
						||
| 
								 | 
							
								      if [ "$CORRECTCSS" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								        # If the CSS does not match the PCSS, set the status to a number other
							 | 
						||
| 
								 | 
							
								        # than 0.
							 | 
						||
| 
								 | 
							
								        STATUS=1
							 | 
						||
| 
								 | 
							
								        printf "\n${red}ERROR: The compiled CSS from"
							 | 
						||
| 
								 | 
							
								        printf "\n       ${BASENAME}.pcss.css"
							 | 
						||
| 
								 | 
							
								        printf "\n       does not match its CSS file. Recompile the CSS with:"
							 | 
						||
| 
								 | 
							
								        printf "\n       yarn run build:css${reset}\n\n"
							 | 
						||
| 
								 | 
							
								      fi
							 | 
						||
| 
								 | 
							
								      cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.css$ ]] && [[ -f "core/node_modules/.bin/stylelint" ]]; then
							 | 
						||
| 
								 | 
							
								    BASENAME=${FILE%.css}
							 | 
						||
| 
								 | 
							
								    # We only need to use stylelint on the .pcss.css file. So if this CSS file
							 | 
						||
| 
								 | 
							
								    # has a corresponding .pcss don't do stylelint.
							 | 
						||
| 
								 | 
							
								    if [[ $FILE =~ \.pcss\.css$ ]] || [[ ! -f "$TOP_LEVEL/$BASENAME.pcss.css" ]]; then
							 | 
						||
| 
								 | 
							
								      cd "$TOP_LEVEL/core"
							 | 
						||
| 
								 | 
							
								      node_modules/.bin/stylelint --allow-empty-input "$TOP_LEVEL/$FILE"
							 | 
						||
| 
								 | 
							
								      if [ "$?" -ne "0" ]; then
							 | 
						||
| 
								 | 
							
								        STATUS=1
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        printf "STYLELINT: $FILE ${green}passed${reset}\n"
							 | 
						||
| 
								 | 
							
								      fi
							 | 
						||
| 
								 | 
							
								      cd $TOP_LEVEL
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if [[ "$STATUS" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								    FINAL_STATUS=1
							 | 
						||
| 
								 | 
							
								    # There is no need to print a failure message. The fail will be described
							 | 
						||
| 
								 | 
							
								    # already.
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    printf "%s ${green}passed${reset}\n" "$FILE"
							 | 
						||
| 
								 | 
							
								  fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # Print a line to separate each file's checks.
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								  printf -- '-%.0s' {1..100}
							 | 
						||
| 
								 | 
							
								  printf "\n"
							 | 
						||
| 
								 | 
							
								done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [[ "$FINAL_STATUS" == "1" ]] && [[ "$DRUPALCI" == "1" ]]; then
							 | 
						||
| 
								 | 
							
								  printf "${red}Drupal code quality checks failed.${reset}\n"
							 | 
						||
| 
								 | 
							
								  printf "To reproduce this output locally:\n"
							 | 
						||
| 
								 | 
							
								  printf "* Apply the change as a patch\n"
							 | 
						||
| 
								 | 
							
								  printf "* Run this command locally: sh ./core/scripts/dev/commit-code-check.sh\n"
							 | 
						||
| 
								 | 
							
								  printf "OR:\n"
							 | 
						||
| 
								 | 
							
								  printf "* From the merge request branch\n"
							 | 
						||
| 
								 | 
							
								  printf "* Run this command locally: sh ./core/scripts/dev/commit-code-check.sh --branch %s\n" "$DRUPAL_VERSION"
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								exit $FINAL_STATUS
							 |