Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

Add stylelint integration #239

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/

root = true

[*]
Expand All @@ -10,7 +10,7 @@ insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab

[{package.json,*.yml}]
[{*.json,*.yml,*.yaml,.stylelintrc,.jshintrc,.eslintrc,.jscsrc}]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is no longer needed, all .json files should now use tabs for indentation

See https://core.trac.wordpress.org/ticket/40946

indent_style = space
indent_size = 2

Expand Down
3 changes: 3 additions & 0 deletions .stylelintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "stylelint-config-wordpress"
}
54 changes: 52 additions & 2 deletions check-diff.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ function set_environment_variables {
ESLINT_IGNORE="$( upsearch .eslintignore )"
fi

if [ -z "$STYLELINT_CONFIG" ]; then
for SEARCHED_STYLELINT_CONFIG in .stylelintrc{,.yaml,.yml,.js,.json} stylelint.config.js; do
STYLELINT_CONFIG="$( upsearch $SEARCHED_STYLELINT_CONFIG )"
if [ ! -z "$STYLELINT_CONFIG" ]; then
break
fi
done
fi

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stylelint supports a few more config files, not sure if you want to include all possible combinations here

Via https://stylelint.io/user-guide/configuration/
The .stylelintrc file (without extension) can be in JSON or YAML format. Alternately, you can add a filename extension to designate JSON, YAML, or JS format: .stylelintrc.json, .stylelintrc.yaml, .stylelintrc.yml, .stylelintrc.js. You may want to use an extension so that your text editor can better interpret the file, and help with syntax checking and highlighting.

# Load any environment variable overrides from config files
ENV_FILE=$( upsearch .ci-env.sh )
if [ ! -z "$ENV_FILE" ]; then
Expand Down Expand Up @@ -245,7 +254,7 @@ function set_environment_variables {

cat "$TEMP_DIRECTORY/paths-scope" | grep -E '\.php(:|$)' | cat - > "$TEMP_DIRECTORY/paths-scope-php"
cat "$TEMP_DIRECTORY/paths-scope" | grep -E '\.jsx?(:|$)' | cat - > "$TEMP_DIRECTORY/paths-scope-js"
cat "$TEMP_DIRECTORY/paths-scope" | grep -E '\.(css|scss)(:|$)' | cat - > "$TEMP_DIRECTORY/paths-scope-scss"
cat "$TEMP_DIRECTORY/paths-scope" | grep -E '\.css(:|$)' | cat - > "$TEMP_DIRECTORY/paths-scope-css"
cat "$TEMP_DIRECTORY/paths-scope" | grep -E '\.(xml|svg|xml.dist)(:|$)' | cat - > "$TEMP_DIRECTORY/paths-scope-xml"

# Gather the proper states of files to run through linting (this won't apply to phpunit)
Expand Down Expand Up @@ -283,7 +292,7 @@ function set_environment_variables {
done

# Make sure linter configs get copied linting directory since upsearch is relative.
for linter_file in .jshintrc .jshintignore .jscsrc .jscs.json .eslintignore .eslintrc phpcs.ruleset.xml ruleset.xml; do
for linter_file in .jshintrc .jshintignore .jscsrc .jscs.json .eslintignore .eslintrc .stylelintrc{,.yaml,.yml,.js,.json} stylelint.config.js phpcs.ruleset.xml ruleset.xml; do
if git ls-files "$linter_file" --error-unmatch > /dev/null 2>&1; then
if [ -L $linter_file ]; then
ln -fs $(git show :"$linter_file") "$LINTING_DIRECTORY/$linter_file"
Expand Down Expand Up @@ -463,6 +472,18 @@ function install_tools {
fi
fi

# Install stylelint
if [ -n "$STYLELINT_CONFIG" ] && [ -e "$STYLELINT_CONFIG" ] && [ ! -e "$(npm bin)/stylelint" ] && check_should_execute 'stylelint'; then
echo "Installing stylelint"
if ! npm install -g stylelint 2>/dev/null; then
echo "Failed to install stylelint (try manually doing: sudo npm install -g stylelint), so skipping stylelint"
DEV_LIB_SKIP="$DEV_LIB_SKIP,stylelint"
elif ! -e node_modules/stylelint-formatter-compact; then
echo "The stylelint-formatter-compact node module is not installed, skipping stylelint."
DEV_LIB_SKIP="$DEV_LIB_SKIP,stylelint"
fi
fi

# YUI Compressor
if [ "$YUI_COMPRESSOR_CHECK" == 1 ] && command -v java >/dev/null 2>&1 && check_should_execute 'yuicompressor'; then
if [ ! -e "$YUI_COMPRESSOR_PATH" ]; then
Expand Down Expand Up @@ -776,6 +797,35 @@ function lint_js_files {
fi
}


function lint_css_files {
if [ ! -s "$TEMP_DIRECTORY/paths-scope-css" ]; then
return
fi

set -e

# Run stylelint.
if [ -n "$STYLELINT_CONFIG" ] && [ -e "$STYLELINT_CONFIG" ] && [ -e "$(npm bin)/stylelint" ] && check_should_execute 'stylelint'; then
(
echo "## stylelint"
cd "$LINTING_DIRECTORY"
if ! cat "$TEMP_DIRECTORY/paths-scope-css" | remove_diff_range | xargs "$(npm bin)/stylelint" --custom-formatter=node_modules/stylelint-formatter-compact --config="$STYLELINT_CONFIG" > "$TEMP_DIRECTORY/stylelint-report"; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the node_modules/stylelint-formatter-compact part. What if stylelint-formatter-compact is installed globally?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap the = for a space , i.e: --custom-formatter node_modules/stylelint-formatter-compact

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore that ^^, the = does not matter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't make a difference. Both --custom-formatter node_modules/stylelint-formatter-compact and --custom-formatter=node_modules/stylelint-formatter-compact have the same result.

Also, both --custom-formatter stylelint-formatter-compact and --custom-formatter=stylelint-formatter-compact fail with: “Error: Cannot find module”.

if [ "$CHECK_SCOPE" == 'patches' ]; then
cat "$TEMP_DIRECTORY/stylelint-report" | php "$DEV_LIB_PATH/diff-tools/filter-report-for-patch-ranges.php" "$TEMP_DIRECTORY/paths-scope-css" | cut -c$( expr ${#LINTING_DIRECTORY} + 2 )-
exit_code="${PIPESTATUS[1]}"
if [[ $exit_code != 0 ]]; then
return $exit_code
fi
elif [ -s "$TEMP_DIRECTORY/stylelint-report" ]; then
cat "$TEMP_DIRECTORY/stylelint-report" | cut -c$( expr ${#LINTING_DIRECTORY} + 2 )-
exit 1
fi
fi
)
fi
}

# @todo: This is wrong, as we should be doing `npm test` instead of calling `grunt qunit` directly.
function run_qunit {
if [ ! -s "$TEMP_DIRECTORY/paths-scope-js" ] || ! check_should_execute 'grunt'; then
Expand Down
1 change: 1 addition & 0 deletions pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ echo "## Checking files, scope $CHECK_SCOPE:"
cat "$TEMP_DIRECTORY/paths-scope"

check_execute_bit
lint_css_files
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above, in a follow up PR we can add lint_scss_files

lint_js_files
lint_php_files
lint_xml_files
Expand Down
8 changes: 5 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,25 @@ To install the pre-commit hook, symlink to [`pre-commit`](pre-commit) from your
./dev-lib/install-pre-commit-hook.sh
```

Also symlink (or copy) the [`.jshintrc`](.jshint), [`.jshintignore`](.jshintignore), [`.jscsrc`](.jscsrc), [`phpcs.ruleset.xml`](phpcs.ruleset.xml), and [`phpunit-plugin.xml`](phpunit-plugin.xml) (note the PHPUnit config will need its paths modified if it is copied instead of symlinked):
Also symlink (or copy) the desired linting configs and [`phpunit-plugin.xml`](phpunit-plugin.xml) (note the PHPUnit config will need its paths modified if it is copied instead of symlinked):

```bash
ln -s dev-lib/phpunit-plugin.xml phpunit.xml.dist && git add phpunit.xml.dist # (if working with a plugin)
ln -s dev-lib/.jshintrc . && git add .jshintrc
ln -s dev-lib/.jscsrc . && git add .jscsrc
ln -s dev-lib/.eslintrc . && git add .eslintrc
ln -s dev-lib/.eslintignore . && git add .eslintignore
ln -s dev-lib/.stylelintrc . && git add .stylelintrc
ln -s dev-lib/.editorconfig . && git add .editorconfig
cp dev-lib/.jshintignore . && git add .jshintignore # don't use symlink for this
```

For ESLint, you'll also likely want to make `eslint` as a dev dependency for your NPM package:
For ESLint and stylelint, you'll also likely want to make them dev dependencies for your NPM package:

```bash
npm init # if you don't have a package.json already
npm install --save-dev eslint
npm install --save-dev stylelint stylelint-formatter-compact
git add package.json
echo 'node_modules' >> .gitignore
git add .gitignore
Expand All @@ -62,7 +64,7 @@ git clone https://github.com/xwp/wp-dev-lib.git ~/Projects/wp-dev-lib

For the Travis CI checks, the `.travis.yml` copied and committed to the repo (see below) will clone the repo into the `dev-lib` directory if it doesn't exist (or whatever your `DEV_LIB_PATH` environment variable is set to).

To install the [`.jshintrc`](.jshint), [`.jshintignore`](.jshintignore), [`.jscsrc`](.jscsrc), and (especially optionally) [`phpcs.ruleset.xml`](phpcs.ruleset.xml), copy the files into the repo root (as opposed to creating symlinks, as when installing via submodule).
To install the [`.jshintrc`](.jshint), [`.jshintignore`](.jshintignore), [`.jscsrc`](.jscsrc), [`.eslintrc`](.eslintrc), [`.stylelintrc`](.stylelintrc), and (especially optionally) [`phpcs.ruleset.xml`](phpcs.ruleset.xml), copy the files into the repo root (as opposed to creating symlinks, as when installing via submodule).

To install dev-lib for all themes and plugins that don't already have a `pre-commit` hook installed, and to upgrade the dev-lib for any submodule installations, you can run the bundled script [`install-upgrade-pre-commit-hook.sh`](install-upgrade-pre-commit-hook.sh) which will look for any repos in the current directory tree and attempt to auto-install. For example:

Expand Down
1 change: 1 addition & 0 deletions travis.script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fi
echo

check_execute_bit
lint_css_files
lint_js_files
lint_php_files
lint_xml_files
Expand Down