Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/update-stylelint-rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: "Update Stylelint rules"
on:
workflow_dispatch:
push:
paths:
- '**update-stylelint-rules.yml'
- 'package.json'
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: '3.13' # Version range or exact version of a Python version to use, using SemVer's version range syntax
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
- name: Setup dependencies using pip
run: pip install -r requirements.txt
- name: Setup Node.js (v4 version 20.x)
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Setup npm packages
run: npm install --omit=dev
timeout-minutes: 30
- name: Update Stylelint Standard Rules
run: python default.py --update-stylelint-rules
- name: Create pull request
uses: peter-evans/create-pull-request@v7
with:
commit-message: Update Stylelint Configuration with Latest Rules
branch: stylelint-rules-updates
title: Update Stylelint Configuration with Latest Rules
body: |
This PR updates the stylelint configuration to include the latest rules from the most recent version of stylelint.
The focus is on rules that prevent the use of:
- unknown
- deprecated
- invalid
- vendor-prefixed
- empty
- non-standard
- important declarations

Specifically done by including all rules where name contains any followed:
- rule name include 'no-unknown'
- rule name include 'no-deprecated'
- rule name include 'no-invalid'
- rule name include 'no-vendor'
- rule name include 'no-empty'
- rule name include 'no-nonstandard'
- rule name include 'no-important'

Following files may be touched:
- configurations/css-stylelint-standard.json
assignees: 7h3Rabbit,cockroacher,marcusosterberg
reviewers: 7h3Rabbit,cockroacher,marcusosterberg
add-paths: |
configurations/css-stylelint-standard.json
configurations/css-stylelint-standard-sv.json
1 change: 1 addition & 0 deletions configurations/css-stylelint-standard.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"description": "This file is automatically generated. Do not edit this file. Instead update tools/update_stylelint.py.",
"rules": {
"annotation-no-unknown": [
true,
Expand Down
91 changes: 91 additions & 0 deletions tools/update_stylelint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
import json
import os
from pathlib import Path
import re
# import gettext


def replacer(match):
text = match.group(1)
text = re.sub(r'([\"])', '“', text, count=1)
text = re.sub(r'([\"])', '”', text, count=1)
return text


def update_stylelint_rules():
print('updates rules used in configurations/css-stylelint-standard.json')

base_directory = Path(os.path.dirname(
os.path.realpath(__file__)) + os.path.sep).parent
rules_path = os.path.join(base_directory, 'node_modules', 'stylelint', 'lib', 'rules')
rule_names = os.listdir(rules_path)

rules = {}
for rule_name in rule_names:
rule_config = True

rule_logic_path = os.path.join(base_directory, 'node_modules', 'stylelint', 'lib', 'rules', rule_name, 'index.mjs')
if os.path.exists(rule_logic_path):
with open(rule_logic_path, 'r', encoding='utf-8') as file:
rule_logic_content = file.read()
for line in rule_logic_content.splitlines():
stripped_line = line.strip()
if stripped_line.startswith('rejected:') and stripped_line.endswith('`,'):
message = stripped_line[stripped_line.find('`'):stripped_line.rfind('`,')].strip()
message = re.sub(r'\$\{[a-zA-Z]+\}', '%s', message).strip('`')
message = re.sub(r"([\"][^\"]+[\"])", replacer, message)
rule_config = [True, {"message": message}]
break

if 'no-unknown' in rule_name:
rules[rule_name] = rule_config
elif 'no-deprecated' in rule_name:
rules[rule_name] = rule_config
elif 'no-invalid' in rule_name:
rules[rule_name] = rule_config
elif 'no-empty' in rule_name:
rules[rule_name] = rule_config
elif 'no-nonstandard' in rule_name:
rules[rule_name] = rule_config

# Sort the rules dictionary by key
rules = dict(sorted(rules.items()))

stylelint_standard_path = os.path.join(base_directory, 'configurations', 'css-stylelint-standard.json')
with open(stylelint_standard_path, 'w', encoding='utf-8') as outfile:
json.dump({
'description': f'This file is automatically generated. Do not edit this file. Instead update tools/update_stylelint.py.',
'rules': rules
}, outfile, indent=4)

# available_languages = get_locales(base_directory)
# locales_dir = os.path.join(base_directory, 'locales')
# for language_code in available_languages:
# if language_code in ('en', 'gov'):
# continue

# print(f'updates rules used in configurations/css-stylelint-standard-{language_code}.json')

# language_rules = rules.copy()
# language = gettext.translation(
# 'css_linting', localedir=locales_dir, languages=[language_code])
# language.install()

# for rule_name, rule_items in language_rules.items():
# if rule_items is not True:
# msg_id = rule_items[1]['message']

# rule_items[1]['message'] = language.gettext(msg_id)

# stylelint_standard_path = os.path.join(base_directory, 'configurations', f'css-stylelint-standard-{language_code}.json')
# with open(stylelint_standard_path, 'w', encoding='utf-8') as outfile:
# json.dump({
# 'description': f'This file is automatically generated. Do not edit this file. Instead update the translation file locales/{language_code}/css_linting.po.',
# 'rules': language_rules
# }, outfile, indent=4)


if __name__ == '__main__':
update_stylelint_rules()
Loading