From a77a37e10d0c33c5bc7cdcdc02c79152e77c8ea3 Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:07:04 +0900 Subject: [PATCH] chore: add color check script and update Makefile targets --- Makefile | 18 ++++-- check_scripts/check_colors.py | 118 ++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 check_scripts/check_colors.py diff --git a/Makefile b/Makefile index fbe063b..bf858a8 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -.PHONY: ci test-all lint repomix local-checks +.PHONY: ci test-all lint repomix local-check-scripts check-scripts -ci: local-checks check-only-ascii lint build-ui test-all +ci: local-check-scripts check-only-ascii lint build-ui test-all build-ui: cd ui && npm install && npm run build @@ -8,7 +8,7 @@ build-ui: watch-ui: cd ui && npm install && npm run dev -local-checks: +local-check-scripts: @if [ -d "local_check_scripts" ]; then \ for script in local_check_scripts/*.py; do \ if [ -f "$$script" ]; then \ @@ -21,12 +21,22 @@ local-checks: test-all: python -m unittest discover tests -lint: check-only-ascii check-ts-rules +lint: check-only-ascii check-ts-rules check-scripts python -m ruff format . python -m ruff check . --fix -python -m mypy py cd ui && npx @biomejs/biome check --write src --error-on-warnings +check-scripts: + @if [ -d "check_scripts" ]; then \ + for script in check_scripts/*.py; do \ + if [ -f "$$script" ]; then \ + echo "Running check script: $$script"; \ + python "$$script" || exit 1; \ + fi; \ + done; \ + fi + check-ts-rules: @echo "Checking for @ts-ignore..." @if git ls-files "ui/src/*.ts" "ui/src/*.tsx" | xargs grep -n "@ts-ignore"; then \ diff --git a/check_scripts/check_colors.py b/check_scripts/check_colors.py new file mode 100644 index 0000000..8e8d576 --- /dev/null +++ b/check_scripts/check_colors.py @@ -0,0 +1,118 @@ +import os +import re +import sys + +# Regex for hex colors, rgb/rgba, hsl/hsla +COLOR_PATTERNS = [ + r"#(?:[0-9a-fA-F]{3,4}){1,2}\b", + r"\brgba?\([^)]+\)", + r"\bhsla?\([^)]+\)", +] + +# Regex for opacity usage (e.g., opacity: 0.5, style={{ opacity: 0.6 }}) +# We want to catch values that are NOT exactly 0 or 1 +OPACITY_PATTERN = r"\bopacity\s*[:=]\s*(?:0\.[0-9]+|[1-9]\.[0-9]+)\b" + +# Combine patterns +COLOR_REGEX = re.compile("|".join(COLOR_PATTERNS)) +OPACITY_REGEX = re.compile(OPACITY_PATTERN) + + +def is_within_var(line: str, match_start: int) -> bool: + # Search backwards for 'var(' without finding a closing ')' + prefix = line[:match_start] + last_var = prefix.rfind("var(") + if last_var == -1: + return False + + # Check if there's a closing parenthesis between last_var and match_start + if ")" in prefix[last_var:]: + return False + return True + + +def check_file(filepath: str) -> list: + errors = [] + try: + with open(filepath, encoding="utf-8") as f: + for i, line in enumerate(f, 1): + # Remove inline comments for checking + code_part = re.sub(r"/\*.*?\*/", "", line) + code_part = re.sub(r"//.*", "", code_part).strip() + + if not code_part: + continue + + # Check for hardcoded colors + color_matches = list(COLOR_REGEX.finditer(code_part)) + for match in color_matches: + color = match.group() + if not is_within_var(code_part, match.start()): + errors.append((i, line.strip(), f"Hardcoded color: {color}")) + + # Check for opacity usage + opacity_matches = list(OPACITY_REGEX.finditer(code_part)) + for match in opacity_matches: + usage = match.group() + # We flag all direct opacity usage as it affects visibility in light themes + errors.append( + ( + i, + line.strip(), + f"Transparency usage: {usage} (Use secondary text variables instead)", + ) + ) + except Exception as e: + print(f"Error reading {filepath}: {e}") + return errors + + +def main() -> None: + # Only check ui/src directory as requested + target_dir = os.path.join("ui", "src") + has_errors = False + + # Files to check + extensions = (".css", ".ts", ".tsx") + + # Files/Dirs to ignore + ignore_files = {"types.d.ts"} + + # Get the base directory (workspace root) + base_dir = os.getcwd() + search_path = os.path.join(base_dir, target_dir) + + if not os.path.exists(search_path): + print(f"Directory not found: {search_path}") + return + + print(f"Checking for hardcoded colors and transparency in {target_dir}...") + + for root, _, files in os.walk(search_path): + for file in files: + if file.endswith(extensions) and file not in ignore_files: + filepath = os.path.join(root, file) + rel_path = os.path.relpath(filepath, base_dir) + errors = check_file(filepath) + if errors: + has_errors = True + print(f"\n[!] Theme compatibility issue found in {rel_path}:") + for line_num, line_content, reason in errors: + print(f" Line {line_num}: {line_content}") + print(f" -> {reason}") + + if has_errors: + print("\nError: Theme compatibility issues detected!") + print("1. Please use ComfyUI theme variables (e.g., var(--comfy-menu-bg)) instead of hardcoded colors.") + print( + "2. Avoid using 'opacity'. Use secondary text variables (e.g., --meld-text-secondary) for better visibility across themes." + ) + print("For instructions and available variables, please refer to: ui/sample-color.txt") + sys.exit(1) + else: + print("Compatibility check passed.") + sys.exit(0) + + +if __name__ == "__main__": + main()