winipedia-utils 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- winipedia_utils/concurrent/concurrent.py +245 -245
- winipedia_utils/concurrent/multiprocessing.py +130 -130
- winipedia_utils/concurrent/multithreading.py +93 -93
- winipedia_utils/consts.py +21 -23
- winipedia_utils/data/__init__.py +1 -1
- winipedia_utils/data/dataframe/__init__.py +1 -1
- winipedia_utils/data/dataframe/cleaning.py +378 -378
- winipedia_utils/data/structures/__init__.py +1 -1
- winipedia_utils/data/structures/dicts.py +16 -16
- winipedia_utils/git/__init__.py +1 -1
- winipedia_utils/git/gitignore/__init__.py +1 -1
- winipedia_utils/git/gitignore/gitignore.py +136 -136
- winipedia_utils/git/pre_commit/__init__.py +1 -1
- winipedia_utils/git/pre_commit/config.py +70 -70
- winipedia_utils/git/pre_commit/hooks.py +109 -109
- winipedia_utils/git/pre_commit/run_hooks.py +49 -49
- winipedia_utils/iterating/__init__.py +1 -1
- winipedia_utils/iterating/iterate.py +29 -29
- winipedia_utils/logging/ansi.py +6 -6
- winipedia_utils/logging/config.py +64 -64
- winipedia_utils/logging/logger.py +26 -26
- winipedia_utils/modules/class_.py +119 -119
- winipedia_utils/modules/function.py +101 -101
- winipedia_utils/modules/module.py +379 -379
- winipedia_utils/modules/package.py +390 -390
- winipedia_utils/oop/mixins/meta.py +333 -333
- winipedia_utils/oop/mixins/mixin.py +37 -37
- winipedia_utils/os/__init__.py +1 -1
- winipedia_utils/os/os.py +63 -63
- winipedia_utils/projects/__init__.py +1 -1
- winipedia_utils/projects/poetry/__init__.py +1 -1
- winipedia_utils/projects/poetry/config.py +91 -91
- winipedia_utils/projects/poetry/poetry.py +31 -31
- winipedia_utils/projects/project.py +48 -48
- winipedia_utils/resources/__init__.py +1 -1
- winipedia_utils/resources/svgs/__init__.py +1 -1
- winipedia_utils/resources/svgs/download_arrow.svg +2 -2
- winipedia_utils/resources/svgs/exit_fullscreen_icon.svg +5 -5
- winipedia_utils/resources/svgs/fullscreen_icon.svg +2 -2
- winipedia_utils/resources/svgs/menu_icon.svg +3 -3
- winipedia_utils/resources/svgs/pause_icon.svg +3 -3
- winipedia_utils/resources/svgs/play_icon.svg +16 -16
- winipedia_utils/resources/svgs/plus_icon.svg +23 -23
- winipedia_utils/resources/svgs/svg.py +15 -15
- winipedia_utils/security/__init__.py +1 -1
- winipedia_utils/security/cryptography.py +29 -29
- winipedia_utils/security/keyring.py +70 -70
- winipedia_utils/setup.py +47 -47
- winipedia_utils/testing/assertions.py +23 -23
- winipedia_utils/testing/convention.py +177 -177
- winipedia_utils/testing/create_tests.py +291 -291
- winipedia_utils/testing/fixtures.py +28 -28
- winipedia_utils/testing/tests/base/fixtures/__init__.py +1 -1
- winipedia_utils/testing/tests/base/fixtures/fixture.py +6 -6
- winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +33 -33
- winipedia_utils/testing/tests/base/fixtures/scopes/function.py +7 -7
- winipedia_utils/testing/tests/base/fixtures/scopes/module.py +31 -31
- winipedia_utils/testing/tests/base/fixtures/scopes/package.py +7 -7
- winipedia_utils/testing/tests/base/fixtures/scopes/session.py +312 -312
- winipedia_utils/testing/tests/base/utils/utils.py +82 -82
- winipedia_utils/testing/tests/conftest.py +32 -32
- winipedia_utils/text/string.py +126 -126
- {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.2.dist-info}/METADATA +3 -5
- winipedia_utils-0.2.2.dist-info/RECORD +80 -0
- {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.2.dist-info}/licenses/LICENSE +21 -21
- winipedia_utils/django/__init__.py +0 -24
- winipedia_utils/django/bulk.py +0 -538
- winipedia_utils/django/command.py +0 -334
- winipedia_utils/django/database.py +0 -289
- winipedia_utils/pyside/__init__.py +0 -1
- winipedia_utils/pyside/core/__init__.py +0 -1
- winipedia_utils/pyside/core/py_qiodevice.py +0 -476
- winipedia_utils/pyside/ui/__init__.py +0 -1
- winipedia_utils/pyside/ui/base/__init__.py +0 -1
- winipedia_utils/pyside/ui/base/base.py +0 -180
- winipedia_utils/pyside/ui/pages/__init__.py +0 -1
- winipedia_utils/pyside/ui/pages/base/__init__.py +0 -1
- winipedia_utils/pyside/ui/pages/base/base.py +0 -92
- winipedia_utils/pyside/ui/pages/browser.py +0 -26
- winipedia_utils/pyside/ui/pages/player.py +0 -85
- winipedia_utils/pyside/ui/widgets/__init__.py +0 -1
- winipedia_utils/pyside/ui/widgets/browser.py +0 -243
- winipedia_utils/pyside/ui/widgets/clickable_widget.py +0 -57
- winipedia_utils/pyside/ui/widgets/media_player.py +0 -430
- winipedia_utils/pyside/ui/widgets/notification.py +0 -78
- winipedia_utils/pyside/ui/windows/__init__.py +0 -1
- winipedia_utils/pyside/ui/windows/base/__init__.py +0 -1
- winipedia_utils/pyside/ui/windows/base/base.py +0 -49
- winipedia_utils-0.2.0.dist-info/RECORD +0 -103
- {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.2.dist-info}/WHEEL +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
"""__init__ module."""
|
|
1
|
+
"""__init__ module."""
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"""Common dict utilities."""
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def reverse_dict(d: dict[Any, Any]) -> dict[Any, Any]:
|
|
7
|
-
"""Reverse a dictionary.
|
|
8
|
-
|
|
9
|
-
Args:
|
|
10
|
-
d: Dictionary to reverse
|
|
11
|
-
|
|
12
|
-
Returns:
|
|
13
|
-
Reversed dictionary
|
|
14
|
-
|
|
15
|
-
"""
|
|
16
|
-
return {v: k for k, v in d.items()}
|
|
1
|
+
"""Common dict utilities."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def reverse_dict(d: dict[Any, Any]) -> dict[Any, Any]:
|
|
7
|
+
"""Reverse a dictionary.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
d: Dictionary to reverse
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
Reversed dictionary
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
return {v: k for k, v in d.items()}
|
winipedia_utils/git/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"""__init__ module for winipedia_utils.git."""
|
|
1
|
+
"""__init__ module for winipedia_utils.git."""
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"""__init__ module for winipedia_utils.git.gitignore."""
|
|
1
|
+
"""__init__ module for winipedia_utils.git.gitignore."""
|
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
"""Git utilities for file and directory operations.
|
|
2
|
-
|
|
3
|
-
This module provides utility functions for working with Git repositories,
|
|
4
|
-
including checking if paths are in .gitignore and walking directories
|
|
5
|
-
while respecting gitignore patterns. These utilities help with file operations
|
|
6
|
-
that need to respect Git's ignore rules.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import os
|
|
10
|
-
from collections.abc import Generator
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
import pathspec
|
|
14
|
-
|
|
15
|
-
from winipedia_utils.logging.logger import get_logger
|
|
16
|
-
|
|
17
|
-
logger = get_logger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def path_is_in_gitignore(relative_path: str | Path) -> bool:
|
|
21
|
-
"""Check if a path matches any pattern in the .gitignore file.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
relative_path: The path to check, relative to the repository root
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
True if the path matches any pattern in .gitignore, False otherwise
|
|
28
|
-
|
|
29
|
-
"""
|
|
30
|
-
as_path = Path(relative_path)
|
|
31
|
-
is_dir = (
|
|
32
|
-
bool(as_path.suffix == "") or as_path.is_dir() or str(as_path).endswith(os.sep)
|
|
33
|
-
)
|
|
34
|
-
is_dir = is_dir and not as_path.is_file()
|
|
35
|
-
|
|
36
|
-
as_posix = as_path.as_posix()
|
|
37
|
-
if is_dir and not as_posix.endswith("/"):
|
|
38
|
-
as_posix += "/"
|
|
39
|
-
|
|
40
|
-
spec = pathspec.PathSpec.from_lines("gitwildmatch", load_gitignore())
|
|
41
|
-
|
|
42
|
-
return spec.match_file(as_posix)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def walk_os_skipping_gitignore_patterns(
|
|
46
|
-
folder: str | Path = ".",
|
|
47
|
-
) -> Generator[tuple[Path, list[str], list[str]], None, None]:
|
|
48
|
-
"""Walk a directory tree while skipping paths that match gitignore patterns.
|
|
49
|
-
|
|
50
|
-
Similar to os.walk, but skips directories and files that match patterns
|
|
51
|
-
in the .gitignore file.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
folder: The root directory to start walking from
|
|
55
|
-
|
|
56
|
-
Yields:
|
|
57
|
-
Tuples of (current_path, directories, files) for each directory visited
|
|
58
|
-
|
|
59
|
-
"""
|
|
60
|
-
folder = Path(folder)
|
|
61
|
-
for root, dirs, files in os.walk(folder):
|
|
62
|
-
rel_root = Path(root).relative_to(".")
|
|
63
|
-
|
|
64
|
-
# skip all in patterns in .gitignore
|
|
65
|
-
if path_is_in_gitignore(rel_root):
|
|
66
|
-
logger.info("Skipping %s because it is in .gitignore", rel_root)
|
|
67
|
-
dirs.clear()
|
|
68
|
-
continue
|
|
69
|
-
|
|
70
|
-
# remove all files that match patterns in .gitignore
|
|
71
|
-
valid_files = [f for f in files if not path_is_in_gitignore(rel_root / f)]
|
|
72
|
-
valid_dirs = [d for d in dirs if not path_is_in_gitignore(rel_root / d)]
|
|
73
|
-
|
|
74
|
-
yield rel_root, valid_dirs, valid_files
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def load_gitignore() -> list[str]:
|
|
78
|
-
"""Load the .gitignore file."""
|
|
79
|
-
gitignore_path = Path(".gitignore")
|
|
80
|
-
if not gitignore_path.exists():
|
|
81
|
-
gitignore_path.touch()
|
|
82
|
-
return gitignore_path.read_text().splitlines()
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def dump_gitignore(patterns: list[str]) -> None:
|
|
86
|
-
"""Dump the given patterns to a .gitignore file (overwrites it)."""
|
|
87
|
-
gitignore_path = Path(".gitignore")
|
|
88
|
-
gitignore_path.write_text("\n".join(patterns))
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def add_patterns_to_gitignore(patterns: list[str]) -> None:
|
|
92
|
-
"""Add the given patterns to the .gitignore file."""
|
|
93
|
-
existing_patterns = load_gitignore()
|
|
94
|
-
new_patterns = [p for p in patterns if p not in existing_patterns]
|
|
95
|
-
if new_patterns:
|
|
96
|
-
logger.info("Adding patterns to .gitignore: %s", new_patterns)
|
|
97
|
-
dump_gitignore(existing_patterns + new_patterns)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def _get_gitignore_patterns() -> list[str]:
|
|
101
|
-
"""Get the patterns that should be in the .gitignore file.
|
|
102
|
-
|
|
103
|
-
Those are the patterns that should be in there when using winipedia_utils.
|
|
104
|
-
"""
|
|
105
|
-
return [
|
|
106
|
-
"__pycache__/",
|
|
107
|
-
".idea/",
|
|
108
|
-
".mypy_cache/",
|
|
109
|
-
".pytest_cache/",
|
|
110
|
-
".ruff_cache/",
|
|
111
|
-
".vscode/",
|
|
112
|
-
"dist/",
|
|
113
|
-
"test.py", # I use this for testing code
|
|
114
|
-
".git/", # ignore the .git folder for walk_os_skipping_gitignore_patterns func
|
|
115
|
-
]
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def _get_missing_patterns() -> list[str]:
|
|
119
|
-
"""Get the patterns that are in the .gitignore file but shouldn't be."""
|
|
120
|
-
needed_patterns = _get_gitignore_patterns()
|
|
121
|
-
existing_patterns = load_gitignore()
|
|
122
|
-
return [p for p in needed_patterns if p not in existing_patterns]
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def _gitignore_is_correct() -> bool:
|
|
126
|
-
"""Check if the .gitignore file contains all the patterns it should."""
|
|
127
|
-
missing_patterns = _get_missing_patterns()
|
|
128
|
-
return not missing_patterns
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def _add_package_patterns_to_gitignore() -> None:
|
|
132
|
-
"""Add any missing patterns to the .gitignore file."""
|
|
133
|
-
if _gitignore_is_correct():
|
|
134
|
-
return
|
|
135
|
-
missing_patterns = _get_missing_patterns()
|
|
136
|
-
add_patterns_to_gitignore(missing_patterns)
|
|
1
|
+
"""Git utilities for file and directory operations.
|
|
2
|
+
|
|
3
|
+
This module provides utility functions for working with Git repositories,
|
|
4
|
+
including checking if paths are in .gitignore and walking directories
|
|
5
|
+
while respecting gitignore patterns. These utilities help with file operations
|
|
6
|
+
that need to respect Git's ignore rules.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from collections.abc import Generator
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import pathspec
|
|
14
|
+
|
|
15
|
+
from winipedia_utils.logging.logger import get_logger
|
|
16
|
+
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def path_is_in_gitignore(relative_path: str | Path) -> bool:
|
|
21
|
+
"""Check if a path matches any pattern in the .gitignore file.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
relative_path: The path to check, relative to the repository root
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
True if the path matches any pattern in .gitignore, False otherwise
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
as_path = Path(relative_path)
|
|
31
|
+
is_dir = (
|
|
32
|
+
bool(as_path.suffix == "") or as_path.is_dir() or str(as_path).endswith(os.sep)
|
|
33
|
+
)
|
|
34
|
+
is_dir = is_dir and not as_path.is_file()
|
|
35
|
+
|
|
36
|
+
as_posix = as_path.as_posix()
|
|
37
|
+
if is_dir and not as_posix.endswith("/"):
|
|
38
|
+
as_posix += "/"
|
|
39
|
+
|
|
40
|
+
spec = pathspec.PathSpec.from_lines("gitwildmatch", load_gitignore())
|
|
41
|
+
|
|
42
|
+
return spec.match_file(as_posix)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def walk_os_skipping_gitignore_patterns(
|
|
46
|
+
folder: str | Path = ".",
|
|
47
|
+
) -> Generator[tuple[Path, list[str], list[str]], None, None]:
|
|
48
|
+
"""Walk a directory tree while skipping paths that match gitignore patterns.
|
|
49
|
+
|
|
50
|
+
Similar to os.walk, but skips directories and files that match patterns
|
|
51
|
+
in the .gitignore file.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
folder: The root directory to start walking from
|
|
55
|
+
|
|
56
|
+
Yields:
|
|
57
|
+
Tuples of (current_path, directories, files) for each directory visited
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
folder = Path(folder)
|
|
61
|
+
for root, dirs, files in os.walk(folder):
|
|
62
|
+
rel_root = Path(root).relative_to(".")
|
|
63
|
+
|
|
64
|
+
# skip all in patterns in .gitignore
|
|
65
|
+
if path_is_in_gitignore(rel_root):
|
|
66
|
+
logger.info("Skipping %s because it is in .gitignore", rel_root)
|
|
67
|
+
dirs.clear()
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
# remove all files that match patterns in .gitignore
|
|
71
|
+
valid_files = [f for f in files if not path_is_in_gitignore(rel_root / f)]
|
|
72
|
+
valid_dirs = [d for d in dirs if not path_is_in_gitignore(rel_root / d)]
|
|
73
|
+
|
|
74
|
+
yield rel_root, valid_dirs, valid_files
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def load_gitignore() -> list[str]:
|
|
78
|
+
"""Load the .gitignore file."""
|
|
79
|
+
gitignore_path = Path(".gitignore")
|
|
80
|
+
if not gitignore_path.exists():
|
|
81
|
+
gitignore_path.touch()
|
|
82
|
+
return gitignore_path.read_text().splitlines()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def dump_gitignore(patterns: list[str]) -> None:
|
|
86
|
+
"""Dump the given patterns to a .gitignore file (overwrites it)."""
|
|
87
|
+
gitignore_path = Path(".gitignore")
|
|
88
|
+
gitignore_path.write_text("\n".join(patterns))
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def add_patterns_to_gitignore(patterns: list[str]) -> None:
|
|
92
|
+
"""Add the given patterns to the .gitignore file."""
|
|
93
|
+
existing_patterns = load_gitignore()
|
|
94
|
+
new_patterns = [p for p in patterns if p not in existing_patterns]
|
|
95
|
+
if new_patterns:
|
|
96
|
+
logger.info("Adding patterns to .gitignore: %s", new_patterns)
|
|
97
|
+
dump_gitignore(existing_patterns + new_patterns)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _get_gitignore_patterns() -> list[str]:
|
|
101
|
+
"""Get the patterns that should be in the .gitignore file.
|
|
102
|
+
|
|
103
|
+
Those are the patterns that should be in there when using winipedia_utils.
|
|
104
|
+
"""
|
|
105
|
+
return [
|
|
106
|
+
"__pycache__/",
|
|
107
|
+
".idea/",
|
|
108
|
+
".mypy_cache/",
|
|
109
|
+
".pytest_cache/",
|
|
110
|
+
".ruff_cache/",
|
|
111
|
+
".vscode/",
|
|
112
|
+
"dist/",
|
|
113
|
+
"test.py", # I use this for testing code
|
|
114
|
+
".git/", # ignore the .git folder for walk_os_skipping_gitignore_patterns func
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _get_missing_patterns() -> list[str]:
|
|
119
|
+
"""Get the patterns that are in the .gitignore file but shouldn't be."""
|
|
120
|
+
needed_patterns = _get_gitignore_patterns()
|
|
121
|
+
existing_patterns = load_gitignore()
|
|
122
|
+
return [p for p in needed_patterns if p not in existing_patterns]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _gitignore_is_correct() -> bool:
|
|
126
|
+
"""Check if the .gitignore file contains all the patterns it should."""
|
|
127
|
+
missing_patterns = _get_missing_patterns()
|
|
128
|
+
return not missing_patterns
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _add_package_patterns_to_gitignore() -> None:
|
|
132
|
+
"""Add any missing patterns to the .gitignore file."""
|
|
133
|
+
if _gitignore_is_correct():
|
|
134
|
+
return
|
|
135
|
+
missing_patterns = _get_missing_patterns()
|
|
136
|
+
add_patterns_to_gitignore(missing_patterns)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"""__init__ module for winipedia_utils.git.pre_commit."""
|
|
1
|
+
"""__init__ module for winipedia_utils.git.pre_commit."""
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
"""Has config utilities for pre-commit."""
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Any
|
|
5
|
-
|
|
6
|
-
import yaml
|
|
7
|
-
|
|
8
|
-
from winipedia_utils.logging.logger import get_logger
|
|
9
|
-
from winipedia_utils.os.os import run_subprocess
|
|
10
|
-
from winipedia_utils.projects.poetry.poetry import POETRY_RUN_ARGS
|
|
11
|
-
|
|
12
|
-
logger = get_logger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def load_pre_commit_config() -> dict[str, Any]:
|
|
16
|
-
"""Load the pre-commit config."""
|
|
17
|
-
path = Path(".pre-commit-config.yaml")
|
|
18
|
-
if not path.exists():
|
|
19
|
-
path.touch()
|
|
20
|
-
return yaml.safe_load(path.read_text()) or {}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def dump_pre_commit_config(config: dict[str, Any]) -> None:
|
|
24
|
-
"""Dump the pre-commit config."""
|
|
25
|
-
path = Path(".pre-commit-config.yaml")
|
|
26
|
-
with path.open("w") as f:
|
|
27
|
-
yaml.safe_dump(config, f, sort_keys=False)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _get_pre_commit_config_dict() -> dict[str, Any]:
|
|
31
|
-
"""Get the content for a pre-commit config file as a dictionary."""
|
|
32
|
-
return {
|
|
33
|
-
"repo": "local",
|
|
34
|
-
"hooks": [
|
|
35
|
-
{
|
|
36
|
-
"id": "winipedia-utils",
|
|
37
|
-
"name": "winipedia-utils",
|
|
38
|
-
"entry": "python -m winipedia_utils.git.pre_commit.run_hooks",
|
|
39
|
-
"language": "system",
|
|
40
|
-
"always_run": True,
|
|
41
|
-
"pass_filenames": False,
|
|
42
|
-
}
|
|
43
|
-
],
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _pre_commit_config_is_correct() -> bool:
|
|
48
|
-
"""Check if the pre-commit config is correct."""
|
|
49
|
-
config = load_pre_commit_config()
|
|
50
|
-
package_hook_config = _get_pre_commit_config_dict().get("hooks", [{}])[0]
|
|
51
|
-
return bool(
|
|
52
|
-
config.get("repos", [{}])[0].get("hooks", [{}])[0] == package_hook_config
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _add_package_hook_to_pre_commit_config() -> None:
|
|
57
|
-
"""Add the winipedia-utils hook to the pre-commit config."""
|
|
58
|
-
config = load_pre_commit_config()
|
|
59
|
-
package_hook_config = _get_pre_commit_config_dict()
|
|
60
|
-
# insert at the beginning of the list
|
|
61
|
-
if not _pre_commit_config_is_correct():
|
|
62
|
-
logger.info("Adding winipedia-utils hook to pre-commit config")
|
|
63
|
-
config["repos"] = [package_hook_config, *config.get("repos", [])]
|
|
64
|
-
dump_pre_commit_config(config)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def _pre_commit_install() -> None:
|
|
68
|
-
"""Install pre-commit."""
|
|
69
|
-
logger.info("Running pre-commit install")
|
|
70
|
-
run_subprocess([*POETRY_RUN_ARGS, "pre-commit", "install"], check=True)
|
|
1
|
+
"""Has config utilities for pre-commit."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import yaml
|
|
7
|
+
|
|
8
|
+
from winipedia_utils.logging.logger import get_logger
|
|
9
|
+
from winipedia_utils.os.os import run_subprocess
|
|
10
|
+
from winipedia_utils.projects.poetry.poetry import POETRY_RUN_ARGS
|
|
11
|
+
|
|
12
|
+
logger = get_logger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def load_pre_commit_config() -> dict[str, Any]:
|
|
16
|
+
"""Load the pre-commit config."""
|
|
17
|
+
path = Path(".pre-commit-config.yaml")
|
|
18
|
+
if not path.exists():
|
|
19
|
+
path.touch()
|
|
20
|
+
return yaml.safe_load(path.read_text()) or {}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def dump_pre_commit_config(config: dict[str, Any]) -> None:
|
|
24
|
+
"""Dump the pre-commit config."""
|
|
25
|
+
path = Path(".pre-commit-config.yaml")
|
|
26
|
+
with path.open("w") as f:
|
|
27
|
+
yaml.safe_dump(config, f, sort_keys=False)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _get_pre_commit_config_dict() -> dict[str, Any]:
|
|
31
|
+
"""Get the content for a pre-commit config file as a dictionary."""
|
|
32
|
+
return {
|
|
33
|
+
"repo": "local",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{
|
|
36
|
+
"id": "winipedia-utils",
|
|
37
|
+
"name": "winipedia-utils",
|
|
38
|
+
"entry": "python -m winipedia_utils.git.pre_commit.run_hooks",
|
|
39
|
+
"language": "system",
|
|
40
|
+
"always_run": True,
|
|
41
|
+
"pass_filenames": False,
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _pre_commit_config_is_correct() -> bool:
|
|
48
|
+
"""Check if the pre-commit config is correct."""
|
|
49
|
+
config = load_pre_commit_config()
|
|
50
|
+
package_hook_config = _get_pre_commit_config_dict().get("hooks", [{}])[0]
|
|
51
|
+
return bool(
|
|
52
|
+
config.get("repos", [{}])[0].get("hooks", [{}])[0] == package_hook_config
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _add_package_hook_to_pre_commit_config() -> None:
|
|
57
|
+
"""Add the winipedia-utils hook to the pre-commit config."""
|
|
58
|
+
config = load_pre_commit_config()
|
|
59
|
+
package_hook_config = _get_pre_commit_config_dict()
|
|
60
|
+
# insert at the beginning of the list
|
|
61
|
+
if not _pre_commit_config_is_correct():
|
|
62
|
+
logger.info("Adding winipedia-utils hook to pre-commit config")
|
|
63
|
+
config["repos"] = [package_hook_config, *config.get("repos", [])]
|
|
64
|
+
dump_pre_commit_config(config)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _pre_commit_install() -> None:
|
|
68
|
+
"""Install pre-commit."""
|
|
69
|
+
logger.info("Running pre-commit install")
|
|
70
|
+
run_subprocess([*POETRY_RUN_ARGS, "pre-commit", "install"], check=True)
|