commit-code-check.sh

Same filename in other branches
  1. 9 core/scripts/dev/commit-code-check.sh
  2. 10 core/scripts/dev/commit-code-check.sh
  3. 11.x core/scripts/dev/commit-code-check.sh
#!/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:
# - File modes.
# - No changes to core/node_modules directory.
# - PHPCS checks PHP and YAML files.
# - Eslint checks JavaScript files.
# - Checks .es6.js and .js files are equivalent.
# - Stylelint checks CSS files.
# - Checks .pcss.css and .css files are equivalent.

# Searches an array.
contains_element() {
  local e
  for e in ${@:2}; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

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
      ;;
    *)
      break
      ;;
  esac
done

# 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);")
else
  red=$(tput setaf 1 && tput bold)
  green=$(tput setaf 2)
  reset=$(tput sgr0)
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)

# Build up a list of absolute file names.
ABS_FILES=
for FILE in $FILES; do
  ABS_FILES="$ABS_FILES $TOP_LEVEL/$FILE"
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

cd "$TOP_LEVEL"

# Add a separator line to make the output easier to read.
printf "\n"
printf -- '-%.0s' {1..100}
printf "\n"

for FILE in $FILES; do
  STATUS=0;
  # Print a line to separate 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
      # Ensure the file has the correct mode.
      STAT="$(stat -f "%A" $FILE 2>/dev/null)"
      if [ $? -ne 0 ]; then
        STAT="$(stat -c "%a" $FILE 2>/dev/null)"
      fi
      if [ "$STAT" -ne "644" ]; then
        printf "${red}check failed:${reset} file $FILE should be 644 not $STAT\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)$ ]]; then
    # Test files with phpcs rules.
    vendor/bin/phpcs "$TOP_LEVEL/$FILE" --runtime-set installed_paths "$TOP_LEVEL/vendor/drupal/coder/coder_sniffer" --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

  ############################################################################
  ### JAVASCRIPT FILES
  ############################################################################
  if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]] && [[ ! $FILE =~ ^core/tests/Drupal/Nightwatch ]] && [[ ! $FILE =~ ^core/assets/vendor/jquery.ui/ui ]]; then
    # Work out the root name of the JavaScript so we can ensure that the ES6
    # version has been compiled correctly.
    if [[ $FILE =~ \.es6\.js$ ]]; then
      BASENAME=${FILE%.es6.js}
      COMPILE_CHECK=1
    else
      BASENAME=${FILE%.js}
      # We only need to compile check if the .es6.js file is not also
      # changing. This is because the compile check will occur for the
      # .es6.js file. This might occur if the compile scripts have changed.
      contains_element "$BASENAME.es6.js" "${FILES[@]}"
      HASES6=$?
      if [ "$HASES6" -ne "0" ]; then
        COMPILE_CHECK=1
      else
        COMPILE_CHECK=0
      fi
    fi
    if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.es6.js" ]]; then
      cd "$TOP_LEVEL/core"
      yarn run build:js --check --file "$TOP_LEVEL/$BASENAME.es6.js"
      CORRECTJS=$?
      if [ "$CORRECTJS" -ne "0" ]; then
        # No need to write any output the yarn run command will do this for
        # us.
        STATUS=1
      fi
      # Check the coding standards.
      if [[ -f ".eslintrc.passing.json" ]]; then
        node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json "$TOP_LEVEL/$BASENAME.es6.js"
        CORRECTJS=$?
        if [ "$CORRECTJS" -ne "0" ]; then
          # No need to write any output the node command will do this for us.
          STATUS=1
        fi
      fi
      cd $TOP_LEVEL
    else
      # If there is no .es6.js file then there should be unless the .js is
      # not really Drupal's.
      if ! [[ "$FILE" =~ ^core/assets/vendor ]] && ! [[ "$FILE" =~ ^core/scripts/js ]] && ! [[ "$FILE" =~ ^core/scripts/css ]] && ! [[ "$FILE" =~ core/postcss.config.js ]] && ! [[ -f "$TOP_LEVEL/$BASENAME.es6.js" ]]; then
        printf "${red}FAILURE${reset} $FILE does not have a corresponding $BASENAME.es6.js\n"
        STATUS=1
      fi
    fi
  elif [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]] && [[ $FILE =~ ^core/assets/vendor/jquery.ui/ui ]]; then
    ## Check for minified file changes.
    if [[ $FILE =~ -min\.js$ ]]; then
      BASENAME=${FILE%-min.js}
      contains_element "$BASENAME.js" "${FILES[@]}"
      HASSRC=$?
      if [ "$HASSRC" -ne "0" ]; then
        COMPILE_CHECK=1
      else
        ## Source was also changed and will be checked.
        COMPILE_CHECK=0
      fi
    else
      ## Check for source changes.
      BASENAME=${FILE%.js}
      COMPILE_CHECK=1
    fi
    if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.js" ]]; then
      cd "$TOP_LEVEL/core"
      yarn run build:jqueryui --check --file "$TOP_LEVEL/$BASENAME.js"
      CORRECTJS=$?
      if [ "$CORRECTJS" -ne "0" ]; then
        # The yarn run command will write any error output.
        STATUS=1
      fi
      cd $TOP_LEVEL
    else
      # If there is no .js source file
      if ! [[ -f "$TOP_LEVEL/$BASENAME.js" ]]; then
        printf "${red}FAILURE${reset} $FILE does not have a corresponding $BASENAME.js\n"
        STATUS=1
      fi
    fi
  else
    # Check coding standards of Nightwatch files.
    if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]]; then
      cd "$TOP_LEVEL/core"
      # Check the coding standards.
      if [[ -f ".eslintrc.passing.json" ]]; then
        node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json "$TOP_LEVEL/$FILE"
        CORRECTJS=$?
        if [ "$CORRECTJS" -ne "0" ]; then
          # No need to write any output the node command will do this for us.
          STATUS=1
        fi
      fi
      cd $TOP_LEVEL
    fi
  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
        # No need to write any output the yarn run command will do this for
        # us.
        STATUS=1
      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 "$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

File

core/scripts/dev/commit-code-check.sh

View source
  1. #!/bin/bash
  2. #
  3. # This script performs code quality checks.
  4. #
  5. # @internal
  6. # This script is not covered by Drupal core's backwards compatibility promise.
  7. # It exists only for core development purposes.
  8. #
  9. # The script makes the following checks:
  10. # - File modes.
  11. # - No changes to core/node_modules directory.
  12. # - PHPCS checks PHP and YAML files.
  13. # - Eslint checks JavaScript files.
  14. # - Checks .es6.js and .js files are equivalent.
  15. # - Stylelint checks CSS files.
  16. # - Checks .pcss.css and .css files are equivalent.
  17. # Searches an array.
  18. contains_element() {
  19. local e
  20. for e in ${@:2}; do [[ "$e" == "$1" ]] && return 0; done
  21. return 1
  22. }
  23. CACHED=0
  24. DRUPALCI=0
  25. BRANCH=""
  26. while test $# -gt 0; do
  27. case "$1" in
  28. -h|--help)
  29. echo "Drupal code quality checks"
  30. echo " "
  31. echo "options:"
  32. echo "-h, --help show brief help"
  33. echo "--branch BRANCH creates list of files to check by comparing against a branch"
  34. echo "--cached checks staged files"
  35. echo "--drupalci a special mode for DrupalCI"
  36. echo " "
  37. echo "Example usage: sh ./core/scripts/dev/commit-code-check.sh --branch 9.2.x"
  38. exit 0
  39. ;;
  40. --branch)
  41. BRANCH="$2"
  42. if [[ "$BRANCH" == "" ]]; then
  43. printf "The --branch option requires a value. For example: --branch 9.2.x\n"
  44. exit;
  45. fi
  46. shift 2
  47. ;;
  48. --cached)
  49. CACHED=1
  50. shift
  51. ;;
  52. --drupalci)
  53. DRUPALCI=1
  54. shift
  55. ;;
  56. *)
  57. break
  58. ;;
  59. esac
  60. done
  61. # Set up variables to make colored output simple. Color output is disabled on
  62. # DrupalCI because it is breaks reporting.
  63. # @todo https://www.drupal.org/project/drupalci_testbot/issues/3181869
  64. if [[ "$DRUPALCI" == "1" ]]; then
  65. red=""
  66. green=""
  67. reset=""
  68. DRUPAL_VERSION=$(php -r "include 'vendor/autoload.php'; print preg_replace('#\.[0-9]+-dev#', '.x', \Drupal::VERSION);")
  69. else
  70. red=$(tput setaf 1 && tput bold)
  71. green=$(tput setaf 2)
  72. reset=$(tput sgr0)
  73. fi
  74. # Gets list of files to check.
  75. if [[ "$BRANCH" != "" ]]; then
  76. FILES=$(git diff --name-only $BRANCH HEAD);
  77. elif [[ "$CACHED" == "0" ]]; then
  78. # For DrupalCI patch testing or when running without --cached or --branch,
  79. # list of all changes in the working directory.
  80. FILES=$(git ls-files --other --modified --exclude-standard --exclude=vendor)
  81. else
  82. # Check staged files only.
  83. if git rev-parse --verify HEAD >/dev/null 2>&1
  84. then
  85. AGAINST=HEAD
  86. else
  87. # Initial commit: diff against an empty tree object
  88. AGAINST=4b825dc642cb6eb9a060e54bf8d69288fbee4904
  89. fi
  90. FILES=$(git diff --cached --name-only $AGAINST);
  91. fi
  92. if [[ "$FILES" == "" ]] && [[ "$DRUPALCI" == "1" ]]; then
  93. # If the FILES is empty we might be testing a merge request on DrupalCI. We
  94. # need to diff against the Drupal branch or tag related to the Drupal version.
  95. printf "Creating list of files to check by comparing branch to %s\n" "$DRUPAL_VERSION"
  96. # On DrupalCI there's a merge commit so we can compare to HEAD~1.
  97. FILES=$(git diff --name-only HEAD~1 HEAD);
  98. fi
  99. TOP_LEVEL=$(git rev-parse --show-toplevel)
  100. # Build up a list of absolute file names.
  101. ABS_FILES=
  102. for FILE in $FILES; do
  103. ABS_FILES="$ABS_FILES $TOP_LEVEL/$FILE"
  104. done
  105. # Exit early if there are no files.
  106. if [[ "$ABS_FILES" == "" ]]; then
  107. printf "There are no files to check. If you have staged a commit use the --cached option.\n"
  108. exit;
  109. fi;
  110. # This script assumes that composer install and yarn install have already been
  111. # run and all dependencies are updated.
  112. FINAL_STATUS=0
  113. cd "$TOP_LEVEL"
  114. # Add a separator line to make the output easier to read.
  115. printf "\n"
  116. printf -- '-%.0s' {1..100}
  117. printf "\n"
  118. for FILE in $FILES; do
  119. STATUS=0;
  120. # Print a line to separate output.
  121. printf "Checking %s\n" "$FILE"
  122. printf "\n"
  123. # Ensure the file still exists (i.e. is not being deleted).
  124. if [ -a $FILE ]; then
  125. if [ ${FILE: -3} != ".sh" ]; then
  126. # Ensure the file has the correct mode.
  127. STAT="$(stat -f "%A" $FILE 2>/dev/null)"
  128. if [ $? -ne 0 ]; then
  129. STAT="$(stat -c "%a" $FILE 2>/dev/null)"
  130. fi
  131. if [ "$STAT" -ne "644" ]; then
  132. printf "${red}check failed:${reset} file $FILE should be 644 not $STAT\n"
  133. STATUS=1
  134. fi
  135. fi
  136. fi
  137. # Don't commit changes to vendor.
  138. if [[ "$FILE" =~ ^vendor/ ]]; then
  139. printf "${red}check failed:${reset} file in vendor directory being committed ($FILE)\n"
  140. STATUS=1
  141. fi
  142. # Don't commit changes to core/node_modules.
  143. if [[ "$FILE" =~ ^core/node_modules/ ]]; then
  144. printf "${red}check failed:${reset} file in core/node_modules directory being committed ($FILE)\n"
  145. STATUS=1
  146. fi
  147. ############################################################################
  148. ### PHP AND YAML FILES
  149. ############################################################################
  150. if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.(inc|install|module|php|profile|test|theme|yml)$ ]]; then
  151. # Test files with phpcs rules.
  152. vendor/bin/phpcs "$TOP_LEVEL/$FILE" --runtime-set installed_paths "$TOP_LEVEL/vendor/drupal/coder/coder_sniffer" --standard="$TOP_LEVEL/core/phpcs.xml.dist"
  153. PHPCS=$?
  154. if [ "$PHPCS" -ne "0" ]; then
  155. # If there are failures set the status to a number other than 0.
  156. STATUS=1
  157. else
  158. printf "PHPCS: $FILE ${green}passed${reset}\n"
  159. fi
  160. fi
  161. ############################################################################
  162. ### JAVASCRIPT FILES
  163. ############################################################################
  164. if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]] && [[ ! $FILE =~ ^core/tests/Drupal/Nightwatch ]] && [[ ! $FILE =~ ^core/assets/vendor/jquery.ui/ui ]]; then
  165. # Work out the root name of the JavaScript so we can ensure that the ES6
  166. # version has been compiled correctly.
  167. if [[ $FILE =~ \.es6\.js$ ]]; then
  168. BASENAME=${FILE%.es6.js}
  169. COMPILE_CHECK=1
  170. else
  171. BASENAME=${FILE%.js}
  172. # We only need to compile check if the .es6.js file is not also
  173. # changing. This is because the compile check will occur for the
  174. # .es6.js file. This might occur if the compile scripts have changed.
  175. contains_element "$BASENAME.es6.js" "${FILES[@]}"
  176. HASES6=$?
  177. if [ "$HASES6" -ne "0" ]; then
  178. COMPILE_CHECK=1
  179. else
  180. COMPILE_CHECK=0
  181. fi
  182. fi
  183. if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.es6.js" ]]; then
  184. cd "$TOP_LEVEL/core"
  185. yarn run build:js --check --file "$TOP_LEVEL/$BASENAME.es6.js"
  186. CORRECTJS=$?
  187. if [ "$CORRECTJS" -ne "0" ]; then
  188. # No need to write any output the yarn run command will do this for
  189. # us.
  190. STATUS=1
  191. fi
  192. # Check the coding standards.
  193. if [[ -f ".eslintrc.passing.json" ]]; then
  194. node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json "$TOP_LEVEL/$BASENAME.es6.js"
  195. CORRECTJS=$?
  196. if [ "$CORRECTJS" -ne "0" ]; then
  197. # No need to write any output the node command will do this for us.
  198. STATUS=1
  199. fi
  200. fi
  201. cd $TOP_LEVEL
  202. else
  203. # If there is no .es6.js file then there should be unless the .js is
  204. # not really Drupal's.
  205. if ! [[ "$FILE" =~ ^core/assets/vendor ]] && ! [[ "$FILE" =~ ^core/scripts/js ]] && ! [[ "$FILE" =~ ^core/scripts/css ]] && ! [[ "$FILE" =~ core/postcss.config.js ]] && ! [[ -f "$TOP_LEVEL/$BASENAME.es6.js" ]]; then
  206. printf "${red}FAILURE${reset} $FILE does not have a corresponding $BASENAME.es6.js\n"
  207. STATUS=1
  208. fi
  209. fi
  210. elif [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]] && [[ $FILE =~ ^core/assets/vendor/jquery.ui/ui ]]; then
  211. ## Check for minified file changes.
  212. if [[ $FILE =~ -min\.js$ ]]; then
  213. BASENAME=${FILE%-min.js}
  214. contains_element "$BASENAME.js" "${FILES[@]}"
  215. HASSRC=$?
  216. if [ "$HASSRC" -ne "0" ]; then
  217. COMPILE_CHECK=1
  218. else
  219. ## Source was also changed and will be checked.
  220. COMPILE_CHECK=0
  221. fi
  222. else
  223. ## Check for source changes.
  224. BASENAME=${FILE%.js}
  225. COMPILE_CHECK=1
  226. fi
  227. if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.js" ]]; then
  228. cd "$TOP_LEVEL/core"
  229. yarn run build:jqueryui --check --file "$TOP_LEVEL/$BASENAME.js"
  230. CORRECTJS=$?
  231. if [ "$CORRECTJS" -ne "0" ]; then
  232. # The yarn run command will write any error output.
  233. STATUS=1
  234. fi
  235. cd $TOP_LEVEL
  236. else
  237. # If there is no .js source file
  238. if ! [[ -f "$TOP_LEVEL/$BASENAME.js" ]]; then
  239. printf "${red}FAILURE${reset} $FILE does not have a corresponding $BASENAME.js\n"
  240. STATUS=1
  241. fi
  242. fi
  243. else
  244. # Check coding standards of Nightwatch files.
  245. if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.js$ ]]; then
  246. cd "$TOP_LEVEL/core"
  247. # Check the coding standards.
  248. if [[ -f ".eslintrc.passing.json" ]]; then
  249. node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json "$TOP_LEVEL/$FILE"
  250. CORRECTJS=$?
  251. if [ "$CORRECTJS" -ne "0" ]; then
  252. # No need to write any output the node command will do this for us.
  253. STATUS=1
  254. fi
  255. fi
  256. cd $TOP_LEVEL
  257. fi
  258. fi
  259. ############################################################################
  260. ### CSS FILES
  261. ############################################################################
  262. if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.css$ ]]; then
  263. # Work out the root name of the CSS so we can ensure that the PostCSS
  264. # version has been compiled correctly.
  265. if [[ $FILE =~ \.pcss\.css$ ]]; then
  266. BASENAME=${FILE%.pcss.css}
  267. COMPILE_CHECK=1
  268. else
  269. BASENAME=${FILE%.css}
  270. # We only need to compile check if the .pcss.css file is not also
  271. # changing. This is because the compile check will occur for the
  272. # .pcss.css file. This might occur if the compiled stylesheets have
  273. # changed.
  274. contains_element "$BASENAME.pcss.css" "${FILES[@]}"
  275. HASPOSTCSS=$?
  276. if [ "$HASPOSTCSS" -ne "0" ]; then
  277. COMPILE_CHECK=1
  278. else
  279. COMPILE_CHECK=0
  280. fi
  281. fi
  282. # PostCSS
  283. if [[ "$COMPILE_CHECK" == "1" ]] && [[ -f "$TOP_LEVEL/$BASENAME.pcss.css" ]]; then
  284. cd "$TOP_LEVEL/core"
  285. yarn run build:css --check --file "$TOP_LEVEL/$BASENAME.pcss.css"
  286. CORRECTCSS=$?
  287. if [ "$CORRECTCSS" -ne "0" ]; then
  288. # No need to write any output the yarn run command will do this for
  289. # us.
  290. STATUS=1
  291. fi
  292. cd $TOP_LEVEL
  293. fi
  294. fi
  295. if [[ -f "$TOP_LEVEL/$FILE" ]] && [[ $FILE =~ \.css$ ]] && [[ -f "core/node_modules/.bin/stylelint" ]]; then
  296. BASENAME=${FILE%.css}
  297. # We only need to use stylelint on the .pcss.css file. So if this CSS file
  298. # has a corresponding .pcss don't do stylelint.
  299. if [[ $FILE =~ \.pcss\.css$ ]] || [[ ! -f "$TOP_LEVEL/$BASENAME.pcss.css" ]]; then
  300. cd "$TOP_LEVEL/core"
  301. node_modules/.bin/stylelint "$TOP_LEVEL/$FILE"
  302. if [ "$?" -ne "0" ]; then
  303. STATUS=1
  304. else
  305. printf "STYLELINT: $FILE ${green}passed${reset}\n"
  306. fi
  307. cd $TOP_LEVEL
  308. fi
  309. fi
  310. if [[ "$STATUS" == "1" ]]; then
  311. FINAL_STATUS=1
  312. # There is no need to print a failure message. The fail will be described
  313. # already.
  314. else
  315. printf "%s ${green}passed${reset}\n" "$FILE"
  316. fi
  317. # Print a line to separate each file's checks.
  318. printf "\n"
  319. printf -- '-%.0s' {1..100}
  320. printf "\n"
  321. done
  322. if [[ "$FINAL_STATUS" == "1" ]] && [[ "$DRUPALCI" == "1" ]]; then
  323. printf "${red}Drupal code quality checks failed.${reset}\n"
  324. printf "To reproduce this output locally:\n"
  325. printf "* Apply the change as a patch\n"
  326. printf "* Run this command locally: sh ./core/scripts/dev/commit-code-check.sh\n"
  327. printf "OR:\n"
  328. printf "* From the merge request branch\n"
  329. printf "* Run this command locally: sh ./core/scripts/dev/commit-code-check.sh --branch %s\n" "$DRUPAL_VERSION"
  330. fi
  331. exit $FINAL_STATUS

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.