diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 1abc6d5..aad3f84 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -2,7 +2,7 @@ self-hosted-runner: labels: [] config-variables: null paths: - . github/workflows/*.yml: - ignore: + . github/workflows/*.yml: + ignore: - 'SC2086' # Allow unquoted variables in shell (common in workflows) - ".+SC1090.+" diff --git a/.github/workflows/maintain-lists.yml b/.github/workflows/maintain-lists.yml index 9f49007..1a1c845 100644 --- a/.github/workflows/maintain-lists.yml +++ b/.github/workflows/maintain-lists.yml @@ -14,7 +14,7 @@ env: DEBIAN_FRONTEND: noninteractive LC_ALL: C GITHUB_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - + jobs: maintain: runs-on: ubuntu-latest diff --git a/.github/workflows/update-lists.yml b/.github/workflows/update-lists.yml index 3117073..1e58147 100644 --- a/.github/workflows/update-lists.yml +++ b/.github/workflows/update-lists.yml @@ -22,7 +22,7 @@ env: PYTHON_COLORS: 0 LC_ALL: C GITHUB_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} -jobs: +jobs: update-mirror: name: Download & Mirror AdLists runs-on: ubuntu-latest @@ -46,7 +46,7 @@ jobs: id: update run: | set -e; mkdir -p lists/mirror - uv run python3 -OO Scripts/update-lists.py --output-dir lists/mirror --max-concurrent 8 + uv run python3 -OO -m Scripts.update_lists --output-dir lists/mirror --max-concurrent 8 - name: Run dead domains linter if: success() continue-on-error: true @@ -60,7 +60,7 @@ jobs: run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git remote set-branches origin adlists-mirror || : + git remote set-branches origin adlists-mirror || : git fetch --depth=1 -nq origin adlists-mirror || git checkout -b adlists-mirror - name: Commit changes id: commit diff --git a/.serena/project.yml b/.serena/project.yml index 1c0ab96..6386032 100644 --- a/.serena/project.yml +++ b/.serena/project.yml @@ -58,7 +58,7 @@ read_only: false # list of tool names to exclude. We recommend not excluding any tools, see the readme for more details. # Below is the complete list of tools for convenience. -# To make sure you have the latest list of tools, and to view their descriptions, +# To make sure you have the latest list of tools, and to view their descriptions, # execute `uv run scripts/print_tool_overview.py`. # # * `activate_project`: Activates a project by name. diff --git a/.yamllint.yml b/.yamllint.yml index f8ce091..0ddde7f 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -2,7 +2,7 @@ extends: default rules: - line-length: + line-length: max: 120 level: warning indentation: @@ -10,7 +10,7 @@ rules: comments: min-spaces-from-content: 1 document-start: disable - truthy: + truthy: allowed-values: ["true", "false"] braces: max-spaces-inside: 0 diff --git a/Scripts/build.sh b/Scripts/build.sh index b3e4e4c..48952af 100755 --- a/Scripts/build.sh +++ b/Scripts/build.sh @@ -104,7 +104,7 @@ build_hostlist(){ } [[ -f configuration_popup_filter.json ]] && { hostlist-compiler -c configuration_popup_filter.json -o "$FILTER_OUT/adguard_popup_filter.txt" --verbose || warn "Popup filter compilation failed" - [[ -f scripts/popup_filter_build.js ]] && node scripts/popup_filter_build.js "$FILTER_OUT/adguard_popup_filter.txt" || : + [[ -f scripts/popup_filter_build.js ]] && node scripts/popup_filter_build.js "$FILTER_OUT/adguard_popup_filter.txt" || : } } @@ -179,15 +179,15 @@ build_userscripts(){ mapfile -t files < <(find "$SCRIPT_SRC" -type f -name "*.js" 2>/dev/null) (( ${#files[@]} == 0 )) && { log userscripts "No files in $SCRIPT_SRC"; return 0; } log userscripts "Processing ${#files[@]} files" - has eslint && eslint --fix --quiet --no-warn-ignored "${files[@]}" 2>/dev/null || : + has eslint && eslint --fix --quiet --no-warn-ignored "${files[@]}" 2>/dev/null || : export -f _process_js ok err warn export REPO SCRIPT_OUT R G Y N RUNNER RUNNER=$(runner) if [[ -n $(par) ]] && (( ${#files[@]} > 1 )); then - printf '%s\n' "${files[@]}" | "$(par)" -j "$(jobs)" --bar _process_js {} 2>/dev/null || : + printf '%s\n' "${files[@]}" | "$(par)" -j "$(jobs)" --bar _process_js {} 2>/dev/null || : else for f in "${files[@]}"; do - _process_js "$f" || : + _process_js "$f" || : done fi [[ -f $SCRIPT_LIST ]] && cp "$SCRIPT_LIST" "$SCRIPT_OUT/README.md" diff --git a/Scripts/deduplicate.py b/Scripts/deduplicate.py index 781ffd6..3d0dc5a 100755 --- a/Scripts/deduplicate.py +++ b/Scripts/deduplicate.py @@ -13,8 +13,7 @@ from dataclasses import dataclass from collections.abc import Iterable - -from common import is_valid_domain, write_lines +from Scripts.common import is_valid_domain, write_lines HEADER_PREFIXES = ("! ", "#", "[", ";") diff --git a/Scripts/hosts-creator.sh b/Scripts/hosts-creator.sh index 610c9b6..692a9b5 100644 --- a/Scripts/hosts-creator.sh +++ b/Scripts/hosts-creator.sh @@ -48,7 +48,7 @@ process(){ [[ ${RM_COMMENTS:-1} == 1 ]] && awk_cmd="!/^#/" [[ ${RM_TRAILING_SPACES:-1} == 1 ]] && awk_cmd="${awk_cmd:+$awk_cmd && }{gsub(/^ +| +$/,\"\");print}" [[ ${RM_DUPLICATE_LINES:-1} == 1 ]] && awk_cmd="${awk_cmd:+$awk_cmd && }! seen[\$0]++" - + if [[ -n $awk_cmd ]]; then local tmp tmp=$(mktemp) diff --git a/Scripts/move-pure-domains.py b/Scripts/move_pure_domains.py similarity index 98% rename from Scripts/move-pure-domains.py rename to Scripts/move_pure_domains.py index a7bc951..23be8a6 100644 --- a/Scripts/move-pure-domains.py +++ b/Scripts/move_pure_domains.py @@ -9,8 +9,7 @@ from collections import defaultdict # Import common utilities - -from common import is_valid_domain, read_lines, write_lines +from Scripts.common import is_valid_domain, read_lines, write_lines def is_pure_domain(line: str) -> bool: diff --git a/Scripts/test_common.py b/Scripts/test_common.py index 1cae1ba..2d66abf 100644 --- a/Scripts/test_common.py +++ b/Scripts/test_common.py @@ -1,10 +1,12 @@ import unittest import sys +import io +import tempfile from pathlib import Path import hashlib +from unittest.mock import patch - -from common import sanitize_filename, is_valid_domain, is_adguard_rule +from Scripts.common import sanitize_filename, is_valid_domain, is_adguard_rule, read_lines class TestCommon(unittest.TestCase): @@ -84,9 +86,27 @@ def test_is_adguard_rule(self): self.assertTrue(is_adguard_rule("! comment")) self.assertFalse(is_adguard_rule("example.com")) + def test_read_lines(self): + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir_path = Path(temp_dir) + target_file = temp_dir_path / "test.txt" + target_file.write_text("line1 \nline2\r\nline3", encoding="utf-8") + + lines = read_lines(target_file) + self.assertEqual(lines, ["line1", "line2", "line3"]) + + def test_read_lines_file_not_found(self): + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir_path = Path(temp_dir) + non_existent = temp_dir_path / "missing.txt" + + with patch("sys.stderr", new_callable=io.StringIO) as mock_stderr: + lines = read_lines(non_existent) + self.assertIsNone(lines) + self.assertIn(f"Error reading {non_existent}", mock_stderr.getvalue()) + def test_write_lines_atomic(self): - import tempfile - from common import write_lines + from Scripts.common import write_lines with tempfile.TemporaryDirectory() as temp_dir: temp_dir_path = Path(temp_dir) diff --git a/Scripts/test_deduplicate.py b/Scripts/test_deduplicate.py index 5a8a607..bf94def 100644 --- a/Scripts/test_deduplicate.py +++ b/Scripts/test_deduplicate.py @@ -1,9 +1,7 @@ import unittest -import sys -from pathlib import Path - -from deduplicate import process_content, is_header, is_valid_rule +# Add current directory to path to allow importing deduplicate +from Scripts.deduplicate import process_content, is_header, is_valid_rule class TestDeduplicate(unittest.TestCase): diff --git a/Scripts/test_is_pure_domain_logic.py b/Scripts/test_is_pure_domain_logic.py index c88da48..da50a7d 100644 --- a/Scripts/test_is_pure_domain_logic.py +++ b/Scripts/test_is_pure_domain_logic.py @@ -1,15 +1,11 @@ import unittest -import sys -from pathlib import Path import importlib - # Import ADGUARD_INDICATORS from common -from common import ADGUARD_INDICATORS +from Scripts.common import ADGUARD_INDICATORS # Import is_pure_domain from move-pure-domains -move_pure_domains = importlib.import_module("move-pure-domains") -is_pure_domain = move_pure_domains.is_pure_domain +from Scripts.move_pure_domains import is_pure_domain class TestIsPureDomain(unittest.TestCase): diff --git a/Scripts/test_move_pure_domains.py b/Scripts/test_move_pure_domains.py index 85548ec..1bbfb90 100644 --- a/Scripts/test_move_pure_domains.py +++ b/Scripts/test_move_pure_domains.py @@ -4,7 +4,7 @@ from unittest.mock import Mock, mock_open # Import the module dynamically -file_path = Path(__file__).parent / "move-pure-domains.py" +file_path = Path(__file__).parent / "move_pure_domains.py" spec = importlib.util.spec_from_file_location("move_pure_domains", file_path) if spec is None or spec.loader is None: raise ImportError("Could not load module") diff --git a/Scripts/test_update_lists.py b/Scripts/test_update_lists.py index 10de0ee..cc41513 100644 --- a/Scripts/test_update_lists.py +++ b/Scripts/test_update_lists.py @@ -20,7 +20,8 @@ class ClientError(Exception): sys.modules["aiohttp"] = aiohttp_mock sys.modules["aiofiles"] = MagicMock() -spec = importlib.util.spec_from_file_location("update_lists", "Scripts/update-lists.py") +spec = importlib.util.spec_from_file_location("update_lists", "Scripts/update_lists.py") +>>>>>>> origin/jules/fix-sys-path-boilerplate-6564146397324574189 update_lists = importlib.util.module_from_spec(spec) sys.modules["update_lists"] = update_lists spec.loader.exec_module(update_lists) diff --git a/Scripts/update-lists.py b/Scripts/update_lists.py similarity index 99% rename from Scripts/update-lists.py rename to Scripts/update_lists.py index 6181242..b70b2e1 100644 --- a/Scripts/update-lists.py +++ b/Scripts/update_lists.py @@ -21,8 +21,7 @@ import aiofiles # Import common utilities - -from common import sanitize_filename +from Scripts.common import sanitize_filename # ============================================================================ # CONFIGURATION diff --git a/Scripts/userscript.sh b/Scripts/userscript.sh index b6faf32..4ee7bc6 100644 --- a/Scripts/userscript.sh +++ b/Scripts/userscript.sh @@ -12,7 +12,7 @@ if has biome; then biome check --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --html-formatter-line-width=120 --css-formatter-line-width=120 --json-formatter-line-width=120 \ --use-editorconfig=true --indent-style=space --format-with-errors=true --files-ignore-unknown=true --vcs-use-ignore-file=false "$PWD" fi -if has ruff; then +if has ruff; then ruff format --line-length 120 --target-version py311 "$PWD" fi has yamlfmt && { yamlfmt -continue_on_error "*.yaml"; yamlfmt -continue_on_error "*.yml"; } diff --git a/mise.toml b/mise.toml index 41e68e5..db57547 100644 --- a/mise.toml +++ b/mise.toml @@ -40,7 +40,7 @@ PYTHONOPTIMIZE = "2" PYTHONDONTWRITEBYTECODE = "1" PYTHONNODEBUGRANGES = "1" PYTHONUTF8 = "1" -PYTHONIOENCODING = "UTF-8" +PYTHONIOENCODING = "UTF-8" UV_LINK_MODE = "hardlink" DO_NOT_TRACK = "1" CARGO_NET_GIT_FETCH_WITH_CLI = "false"