dycw-actions 0.6.4__py3-none-any.whl → 0.7.7__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.
- actions/__init__.py +1 -1
- actions/action_dicts/lib.py +8 -8
- actions/clean_dir/cli.py +0 -12
- actions/clean_dir/constants.py +7 -0
- actions/clean_dir/lib.py +1 -0
- actions/cli.py +90 -29
- actions/constants.py +5 -1
- actions/pre_commit/click.py +15 -0
- actions/{conformalize_repo → pre_commit/conformalize_repo}/cli.py +2 -14
- actions/{conformalize_repo → pre_commit/conformalize_repo}/constants.py +8 -2
- actions/{conformalize_repo → pre_commit/conformalize_repo}/lib.py +97 -313
- actions/{conformalize_repo → pre_commit/conformalize_repo}/settings.py +1 -1
- actions/pre_commit/constants.py +8 -0
- actions/pre_commit/format_requirements/cli.py +24 -0
- actions/pre_commit/format_requirements/constants.py +7 -0
- actions/pre_commit/format_requirements/lib.py +52 -0
- actions/pre_commit/replace_sequence_strs/__init__.py +1 -0
- actions/pre_commit/replace_sequence_strs/cli.py +24 -0
- actions/pre_commit/replace_sequence_strs/constants.py +7 -0
- actions/{replace_sequence_strs → pre_commit/replace_sequence_strs}/lib.py +16 -22
- actions/pre_commit/touch_empty_py/__init__.py +1 -0
- actions/pre_commit/touch_empty_py/cli.py +24 -0
- actions/pre_commit/touch_empty_py/constants.py +7 -0
- actions/pre_commit/touch_empty_py/lib.py +62 -0
- actions/pre_commit/touch_py_typed/__init__.py +1 -0
- actions/pre_commit/touch_py_typed/cli.py +24 -0
- actions/pre_commit/touch_py_typed/constants.py +7 -0
- actions/pre_commit/touch_py_typed/lib.py +72 -0
- actions/pre_commit/update_requirements/__init__.py +1 -0
- actions/pre_commit/update_requirements/classes.py +130 -0
- actions/pre_commit/update_requirements/cli.py +24 -0
- actions/pre_commit/update_requirements/constants.py +7 -0
- actions/pre_commit/update_requirements/lib.py +140 -0
- actions/pre_commit/utilities.py +386 -0
- actions/publish_package/cli.py +7 -19
- actions/publish_package/constants.py +7 -0
- actions/publish_package/lib.py +3 -3
- actions/py.typed +0 -0
- actions/random_sleep/cli.py +6 -15
- actions/random_sleep/constants.py +7 -0
- actions/register_gitea_runner/__init__.py +1 -0
- actions/register_gitea_runner/cli.py +32 -0
- actions/register_gitea_runner/configs/config.yml +110 -0
- actions/register_gitea_runner/configs/entrypoint.sh +23 -0
- actions/register_gitea_runner/constants.py +23 -0
- actions/register_gitea_runner/lib.py +289 -0
- actions/register_gitea_runner/settings.py +33 -0
- actions/run_hooks/cli.py +3 -15
- actions/run_hooks/constants.py +7 -0
- actions/run_hooks/lib.py +2 -2
- actions/setup_cronjob/cli.py +0 -12
- actions/setup_cronjob/constants.py +5 -1
- actions/tag_commit/cli.py +7 -19
- actions/tag_commit/constants.py +7 -0
- actions/tag_commit/lib.py +8 -8
- actions/types.py +4 -1
- actions/utilities.py +68 -14
- {dycw_actions-0.6.4.dist-info → dycw_actions-0.7.7.dist-info}/METADATA +5 -3
- dycw_actions-0.7.7.dist-info/RECORD +84 -0
- actions/format_requirements/cli.py +0 -37
- actions/format_requirements/lib.py +0 -121
- actions/publish_package/doc.py +0 -6
- actions/random_sleep/doc.py +0 -6
- actions/replace_sequence_strs/cli.py +0 -37
- actions/run_hooks/doc.py +0 -6
- actions/tag_commit/doc.py +0 -6
- dycw_actions-0.6.4.dist-info/RECORD +0 -56
- /actions/{conformalize_repo → pre_commit}/__init__.py +0 -0
- /actions/{format_requirements → pre_commit/conformalize_repo}/__init__.py +0 -0
- /actions/{conformalize_repo → pre_commit/conformalize_repo}/configs/gitignore +0 -0
- /actions/{replace_sequence_strs → pre_commit/format_requirements}/__init__.py +0 -0
- {dycw_actions-0.6.4.dist-info → dycw_actions-0.7.7.dist-info}/WHEEL +0 -0
- {dycw_actions-0.6.4.dist-info → dycw_actions-0.7.7.dist-info}/entry_points.txt +0 -0
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
import sys
|
|
5
4
|
from contextlib import contextmanager, suppress
|
|
6
|
-
from
|
|
5
|
+
from hashlib import blake2b
|
|
7
6
|
from itertools import product
|
|
8
7
|
from pathlib import Path
|
|
9
|
-
from re import MULTILINE, escape, sub
|
|
8
|
+
from re import MULTILINE, escape, search, sub
|
|
10
9
|
from shlex import join
|
|
11
10
|
from string import Template
|
|
12
11
|
from subprocess import CalledProcessError
|
|
13
|
-
from typing import TYPE_CHECKING,
|
|
12
|
+
from typing import TYPE_CHECKING, Literal, assert_never
|
|
14
13
|
|
|
15
14
|
import tomlkit
|
|
16
|
-
from rich.pretty import pretty_repr
|
|
17
15
|
from ruamel.yaml.scalarstring import LiteralScalarString
|
|
18
|
-
from tomlkit import TOMLDocument,
|
|
16
|
+
from tomlkit import TOMLDocument, table
|
|
19
17
|
from tomlkit.exceptions import NonExistentKey
|
|
20
|
-
from tomlkit.items import AoT, Array, Table
|
|
21
|
-
from utilities.atomicwrites import writer
|
|
22
|
-
from utilities.functions import ensure_class
|
|
23
18
|
from utilities.inflect import counted_noun
|
|
24
|
-
from utilities.iterables import OneEmptyError, OneNonUniqueError, one
|
|
25
|
-
from utilities.pathlib import get_repo_root
|
|
26
19
|
from utilities.re import extract_groups
|
|
27
|
-
from utilities.subprocess import
|
|
28
|
-
from utilities.tempfile import TemporaryFile
|
|
20
|
+
from utilities.subprocess import ripgrep
|
|
29
21
|
from utilities.text import repr_str, strip_and_dedent
|
|
22
|
+
from utilities.throttle import throttle
|
|
30
23
|
from utilities.version import ParseVersionError, Version, parse_version
|
|
31
|
-
from utilities.whenever import HOUR
|
|
32
|
-
from whenever import ZonedDateTime
|
|
33
|
-
from xdg_base_dirs import xdg_cache_home
|
|
24
|
+
from utilities.whenever import HOUR
|
|
34
25
|
|
|
35
26
|
from actions import __version__
|
|
36
27
|
from actions.action_dicts.lib import (
|
|
@@ -41,9 +32,12 @@ from actions.action_dicts.lib import (
|
|
|
41
32
|
run_action_ruff_dict,
|
|
42
33
|
run_action_tag_dict,
|
|
43
34
|
)
|
|
44
|
-
from actions.
|
|
35
|
+
from actions.constants import PATH_THROTTLE_CACHE, YAML_INSTANCE
|
|
36
|
+
from actions.logging import LOGGER
|
|
37
|
+
from actions.pre_commit.conformalize_repo.constants import (
|
|
45
38
|
ACTIONS_URL,
|
|
46
39
|
BUMPVERSION_TOML,
|
|
40
|
+
CONFORMALIZE_REPO_SUB_CMD,
|
|
47
41
|
COVERAGERC_TOML,
|
|
48
42
|
DOCKERFMT_URL,
|
|
49
43
|
ENVRC,
|
|
@@ -65,16 +59,39 @@ from actions.conformalize_repo.constants import (
|
|
|
65
59
|
TAPLO_URL,
|
|
66
60
|
UV_URL,
|
|
67
61
|
)
|
|
68
|
-
from actions.conformalize_repo.settings import SETTINGS
|
|
69
|
-
from actions.constants import
|
|
70
|
-
from actions.
|
|
62
|
+
from actions.pre_commit.conformalize_repo.settings import SETTINGS
|
|
63
|
+
from actions.pre_commit.format_requirements.constants import FORMAT_REQUIREMENTS_SUB_CMD
|
|
64
|
+
from actions.pre_commit.replace_sequence_strs.constants import (
|
|
65
|
+
REPLACE_SEQUENCE_STRS_SUB_CMD,
|
|
66
|
+
)
|
|
67
|
+
from actions.pre_commit.touch_empty_py.constants import TOUCH_EMPTY_PY_SUB_CMD
|
|
68
|
+
from actions.pre_commit.touch_py_typed.constants import TOUCH_PY_TYPED_SUB_CMD
|
|
69
|
+
from actions.pre_commit.update_requirements.constants import UPDATE_REQUIREMENTS_SUB_CMD
|
|
70
|
+
from actions.pre_commit.utilities import (
|
|
71
|
+
ensure_aot_contains,
|
|
72
|
+
ensure_contains,
|
|
73
|
+
ensure_contains_partial_dict,
|
|
74
|
+
ensure_contains_partial_str,
|
|
75
|
+
ensure_not_contains,
|
|
76
|
+
get_aot,
|
|
77
|
+
get_array,
|
|
78
|
+
get_dict,
|
|
79
|
+
get_list,
|
|
80
|
+
get_table,
|
|
81
|
+
yield_json_dict,
|
|
82
|
+
yield_text_file,
|
|
83
|
+
yield_toml_doc,
|
|
84
|
+
yield_yaml_dict,
|
|
85
|
+
)
|
|
86
|
+
from actions.utilities import logged_run
|
|
71
87
|
|
|
72
88
|
if TYPE_CHECKING:
|
|
73
|
-
from collections.abc import
|
|
89
|
+
from collections.abc import Iterator, MutableSet
|
|
74
90
|
|
|
91
|
+
from tomlkit.items import Table
|
|
75
92
|
from utilities.types import PathLike
|
|
76
93
|
|
|
77
|
-
from actions.types import
|
|
94
|
+
from actions.types import StrDict
|
|
78
95
|
|
|
79
96
|
|
|
80
97
|
def conformalize_repo(
|
|
@@ -267,6 +284,7 @@ def conformalize_repo(
|
|
|
267
284
|
pytest__ubuntu=github__pull_request__pytest__ubuntu,
|
|
268
285
|
pytest__timeout=pytest__timeout,
|
|
269
286
|
python_version=python_version,
|
|
287
|
+
repo_name=repo_name,
|
|
270
288
|
ruff=ruff,
|
|
271
289
|
script=script,
|
|
272
290
|
)
|
|
@@ -411,31 +429,27 @@ def add_envrc(
|
|
|
411
429
|
python_version: str = SETTINGS.python_version,
|
|
412
430
|
script: str | None = SETTINGS.script,
|
|
413
431
|
) -> None:
|
|
414
|
-
with yield_text_file(ENVRC, modifications=modifications) as
|
|
432
|
+
with yield_text_file(ENVRC, modifications=modifications) as context:
|
|
415
433
|
shebang = strip_and_dedent("""
|
|
416
434
|
#!/usr/bin/env sh
|
|
417
435
|
# shellcheck source=/dev/null
|
|
418
436
|
""")
|
|
419
|
-
|
|
437
|
+
if search(escape(shebang), context.output, flags=MULTILINE) is None:
|
|
438
|
+
context.output += f"\n\n{shebang}"
|
|
420
439
|
|
|
421
440
|
echo = strip_and_dedent("""
|
|
422
441
|
# echo
|
|
423
442
|
echo_date() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2; }
|
|
424
443
|
""")
|
|
425
|
-
|
|
444
|
+
if search(escape(echo), context.output, flags=MULTILINE) is None:
|
|
445
|
+
context.output += f"\n\n{echo}"
|
|
426
446
|
|
|
427
447
|
if uv:
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
_add_envrc_uv_text(
|
|
431
|
-
native_tls=uv__native_tls,
|
|
432
|
-
python_version=python_version,
|
|
433
|
-
script=script,
|
|
434
|
-
),
|
|
435
|
-
skip_if_present=True,
|
|
436
|
-
flags=MULTILINE,
|
|
437
|
-
blank_lines=2,
|
|
448
|
+
uv_text = _add_envrc_uv_text(
|
|
449
|
+
native_tls=uv__native_tls, python_version=python_version, script=script
|
|
438
450
|
)
|
|
451
|
+
if search(escape(uv_text), context.output, flags=MULTILINE) is None:
|
|
452
|
+
context.output += f"\n\n{echo}"
|
|
439
453
|
|
|
440
454
|
|
|
441
455
|
def _add_envrc_uv_text(
|
|
@@ -491,6 +505,7 @@ def add_github_pull_request_yaml(
|
|
|
491
505
|
pytest__windows: bool = SETTINGS.github__pull_request__pytest__windows,
|
|
492
506
|
pytest__timeout: int | None = SETTINGS.pytest__timeout,
|
|
493
507
|
python_version: str = SETTINGS.python_version,
|
|
508
|
+
repo_name: str | None = SETTINGS.repo_name,
|
|
494
509
|
ruff: bool = SETTINGS.github__pull_request__ruff,
|
|
495
510
|
script: str | None = SETTINGS.script,
|
|
496
511
|
) -> None:
|
|
@@ -503,7 +518,7 @@ def add_github_pull_request_yaml(
|
|
|
503
518
|
branches = get_list(pull_request, "branches")
|
|
504
519
|
ensure_contains(branches, "master")
|
|
505
520
|
schedule = get_list(on, "schedule")
|
|
506
|
-
ensure_contains(schedule, {"cron":
|
|
521
|
+
ensure_contains(schedule, {"cron": get_cron_job(repo_name=repo_name)})
|
|
507
522
|
jobs = get_dict(dict_, "jobs")
|
|
508
523
|
if pre_commit:
|
|
509
524
|
pre_commit_dict = get_dict(jobs, "pre-commit")
|
|
@@ -615,9 +630,10 @@ def add_github_push_yaml(
|
|
|
615
630
|
|
|
616
631
|
|
|
617
632
|
def add_gitignore(*, modifications: MutableSet[Path] | None = None) -> None:
|
|
618
|
-
with yield_text_file(GITIGNORE, modifications=modifications) as
|
|
633
|
+
with yield_text_file(GITIGNORE, modifications=modifications) as context:
|
|
619
634
|
text = (PATH_CONFIGS / "gitignore").read_text()
|
|
620
|
-
|
|
635
|
+
if search(escape(text), context.output, flags=MULTILINE) is None:
|
|
636
|
+
context.output += f"\n\n{text}"
|
|
621
637
|
|
|
622
638
|
|
|
623
639
|
##
|
|
@@ -636,7 +652,7 @@ def add_pre_commit_config_yaml(
|
|
|
636
652
|
script: str | None = SETTINGS.script,
|
|
637
653
|
) -> None:
|
|
638
654
|
with yield_yaml_dict(PRE_COMMIT_CONFIG_YAML, modifications=modifications) as dict_:
|
|
639
|
-
_add_pre_commit_config_repo(dict_, ACTIONS_URL,
|
|
655
|
+
_add_pre_commit_config_repo(dict_, ACTIONS_URL, CONFORMALIZE_REPO_SUB_CMD)
|
|
640
656
|
_add_pre_commit_config_repo(
|
|
641
657
|
dict_, PRE_COMMIT_HOOKS_URL, "check-executables-have-shebangs"
|
|
642
658
|
)
|
|
@@ -675,8 +691,13 @@ def add_pre_commit_config_yaml(
|
|
|
675
691
|
types_or=["markdown", "yaml"],
|
|
676
692
|
)
|
|
677
693
|
if python:
|
|
678
|
-
_add_pre_commit_config_repo(dict_, ACTIONS_URL,
|
|
679
|
-
_add_pre_commit_config_repo(
|
|
694
|
+
_add_pre_commit_config_repo(dict_, ACTIONS_URL, FORMAT_REQUIREMENTS_SUB_CMD)
|
|
695
|
+
_add_pre_commit_config_repo(
|
|
696
|
+
dict_, ACTIONS_URL, REPLACE_SEQUENCE_STRS_SUB_CMD
|
|
697
|
+
)
|
|
698
|
+
_add_pre_commit_config_repo(dict_, ACTIONS_URL, TOUCH_EMPTY_PY_SUB_CMD)
|
|
699
|
+
_add_pre_commit_config_repo(dict_, ACTIONS_URL, TOUCH_PY_TYPED_SUB_CMD)
|
|
700
|
+
_add_pre_commit_config_repo(dict_, ACTIONS_URL, UPDATE_REQUIREMENTS_SUB_CMD)
|
|
680
701
|
if ruff:
|
|
681
702
|
_add_pre_commit_config_repo(
|
|
682
703
|
dict_, RUFF_URL, "ruff-check", args=("add", ["--fix"])
|
|
@@ -730,11 +751,11 @@ def _add_pre_commit_config_repo(
|
|
|
730
751
|
args: tuple[Literal["add", "exact"], list[str]] | None = None,
|
|
731
752
|
) -> None:
|
|
732
753
|
repos_list = get_list(pre_commit_dict, "repos")
|
|
733
|
-
repo_dict =
|
|
754
|
+
repo_dict = ensure_contains_partial_dict(
|
|
734
755
|
repos_list, {"repo": url}, extra={} if url == "local" else {"rev": "master"}
|
|
735
756
|
)
|
|
736
757
|
hooks_list = get_list(repo_dict, "hooks")
|
|
737
|
-
hook_dict =
|
|
758
|
+
hook_dict = ensure_contains_partial_dict(hooks_list, {"id": id_})
|
|
738
759
|
if name is not None:
|
|
739
760
|
hook_dict["name"] = name
|
|
740
761
|
if entry is not None:
|
|
@@ -785,12 +806,13 @@ def add_pyproject_toml(
|
|
|
785
806
|
project.setdefault("version", "0.1.0")
|
|
786
807
|
dependency_groups = get_table(doc, "dependency-groups")
|
|
787
808
|
dev = get_array(dependency_groups, "dev")
|
|
788
|
-
|
|
789
|
-
|
|
809
|
+
_ = ensure_contains_partial_str(dev, "dycw-utilities[test]")
|
|
810
|
+
_ = ensure_contains_partial_str(dev, "pyright")
|
|
811
|
+
_ = ensure_contains_partial_str(dev, "rich")
|
|
790
812
|
if optional_dependencies__scripts:
|
|
791
813
|
optional_dependencies = get_table(project, "optional-dependencies")
|
|
792
814
|
scripts = get_array(optional_dependencies, "scripts")
|
|
793
|
-
|
|
815
|
+
_ = ensure_contains_partial_str(scripts, "click")
|
|
794
816
|
if python_package_name is not None:
|
|
795
817
|
tool = get_table(doc, "tool")
|
|
796
818
|
uv = get_table(tool, "uv")
|
|
@@ -921,13 +943,15 @@ def add_readme_md(
|
|
|
921
943
|
name: str | None = SETTINGS.package_name,
|
|
922
944
|
description: str | None = SETTINGS.description,
|
|
923
945
|
) -> None:
|
|
924
|
-
with yield_text_file(README_MD, modifications=modifications) as
|
|
946
|
+
with yield_text_file(README_MD, modifications=modifications) as context:
|
|
925
947
|
lines: list[str] = []
|
|
926
948
|
if name is not None:
|
|
927
949
|
lines.append(f"# `{name}`")
|
|
928
950
|
if description is not None:
|
|
929
951
|
lines.append(description)
|
|
930
|
-
|
|
952
|
+
text = "\n\n".join(lines)
|
|
953
|
+
if search(escape(text), context.output, flags=MULTILINE) is None:
|
|
954
|
+
context.output += f"\n\n{text}"
|
|
931
955
|
|
|
932
956
|
|
|
933
957
|
##
|
|
@@ -1029,107 +1053,15 @@ def check_versions() -> None:
|
|
|
1029
1053
|
##
|
|
1030
1054
|
|
|
1031
1055
|
|
|
1032
|
-
def
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
raise TypeError(msg)
|
|
1042
|
-
for obj in objs:
|
|
1043
|
-
if obj not in array:
|
|
1044
|
-
array.append(obj)
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
def ensure_contains_partial(
|
|
1048
|
-
container: HasAppend, partial: StrDict, /, *, extra: StrDict | None = None
|
|
1049
|
-
) -> StrDict:
|
|
1050
|
-
try:
|
|
1051
|
-
return get_partial_dict(container, partial, skip_log=True)
|
|
1052
|
-
except OneEmptyError:
|
|
1053
|
-
dict_ = partial | ({} if extra is None else extra)
|
|
1054
|
-
container.append(dict_)
|
|
1055
|
-
return dict_
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
def ensure_not_contains(array: Array, /, *objs: Any) -> None:
|
|
1059
|
-
for obj in objs:
|
|
1060
|
-
try:
|
|
1061
|
-
index = next(i for i, o in enumerate(array) if o == obj)
|
|
1062
|
-
except StopIteration:
|
|
1063
|
-
pass
|
|
1064
|
-
else:
|
|
1065
|
-
del array[index]
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
##
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
def get_aot(container: HasSetDefault, key: str, /) -> AoT:
|
|
1072
|
-
return ensure_class(container.setdefault(key, aot()), AoT)
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
def get_array(container: HasSetDefault, key: str, /) -> Array:
|
|
1076
|
-
return ensure_class(container.setdefault(key, array()), Array)
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
def get_dict(container: HasSetDefault, key: str, /) -> StrDict:
|
|
1080
|
-
return ensure_class(container.setdefault(key, {}), dict)
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
def get_list(container: HasSetDefault, key: str, /) -> list[Any]:
|
|
1084
|
-
return ensure_class(container.setdefault(key, []), list)
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
def get_table(container: HasSetDefault, key: str, /) -> Table:
|
|
1088
|
-
return ensure_class(container.setdefault(key, table()), Table)
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
##
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
def get_partial_dict(
|
|
1095
|
-
iterable: Iterable[Any], dict_: StrDict, /, *, skip_log: bool = False
|
|
1096
|
-
) -> StrDict:
|
|
1097
|
-
try:
|
|
1098
|
-
return one(i for i in iterable if is_partial_dict(dict_, i))
|
|
1099
|
-
except OneEmptyError:
|
|
1100
|
-
if not skip_log:
|
|
1101
|
-
LOGGER.exception(
|
|
1102
|
-
"Expected %s to contain %s (as a partial)",
|
|
1103
|
-
pretty_repr(iterable),
|
|
1104
|
-
pretty_repr(dict_),
|
|
1105
|
-
)
|
|
1106
|
-
raise
|
|
1107
|
-
except OneNonUniqueError as error:
|
|
1108
|
-
LOGGER.exception(
|
|
1109
|
-
"Expected %s to contain %s uniquely (as a partial); got %s, %s and perhaps more",
|
|
1110
|
-
pretty_repr(iterable),
|
|
1111
|
-
pretty_repr(dict_),
|
|
1112
|
-
pretty_repr(error.first),
|
|
1113
|
-
pretty_repr(error.second),
|
|
1114
|
-
)
|
|
1115
|
-
raise
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
def is_partial_dict(obj: Any, dict_: StrDict, /) -> bool:
|
|
1119
|
-
if not isinstance(obj, dict):
|
|
1120
|
-
return False
|
|
1121
|
-
results: dict[str, bool] = {}
|
|
1122
|
-
for key, obj_value in obj.items():
|
|
1123
|
-
try:
|
|
1124
|
-
dict_value = dict_[key]
|
|
1125
|
-
except KeyError:
|
|
1126
|
-
results[key] = False
|
|
1127
|
-
else:
|
|
1128
|
-
if isinstance(obj_value, dict) and isinstance(dict_value, dict):
|
|
1129
|
-
results[key] = is_partial_dict(obj_value, dict_value)
|
|
1130
|
-
else:
|
|
1131
|
-
results[key] = obj_value == dict_value
|
|
1132
|
-
return all(results.values())
|
|
1056
|
+
def get_cron_job(*, repo_name: str | None = SETTINGS.repo_name) -> str:
|
|
1057
|
+
if repo_name is None:
|
|
1058
|
+
hour = minute = 0
|
|
1059
|
+
else:
|
|
1060
|
+
digest = blake2b(repo_name.encode(), digest_size=8).digest()
|
|
1061
|
+
value = int.from_bytes(digest, "big")
|
|
1062
|
+
minute = value % 60
|
|
1063
|
+
hour = (value // 60) % 24
|
|
1064
|
+
return f"{hour} {minute} * * *"
|
|
1133
1065
|
|
|
1134
1066
|
|
|
1135
1067
|
##
|
|
@@ -1168,12 +1100,12 @@ def get_version_from_bumpversion_toml(
|
|
|
1168
1100
|
|
|
1169
1101
|
|
|
1170
1102
|
def get_version_from_git_show() -> Version:
|
|
1171
|
-
text =
|
|
1103
|
+
text = logged_run("git", "show", f"origin/master:{BUMPVERSION_TOML}", return_=True)
|
|
1172
1104
|
return get_version_from_bumpversion_toml(obj=text.rstrip("\n"))
|
|
1173
1105
|
|
|
1174
1106
|
|
|
1175
1107
|
def get_version_from_git_tag() -> Version:
|
|
1176
|
-
text =
|
|
1108
|
+
text = logged_run("git", "tag", "--points-at", "origin/master", return_=True)
|
|
1177
1109
|
for line in text.splitlines():
|
|
1178
1110
|
with suppress(ParseVersionError):
|
|
1179
1111
|
return parse_version(line)
|
|
@@ -1208,27 +1140,16 @@ def run_bump_my_version(*, modifications: MutableSet[Path] | None = None) -> Non
|
|
|
1208
1140
|
##
|
|
1209
1141
|
|
|
1210
1142
|
|
|
1211
|
-
def
|
|
1212
|
-
|
|
1143
|
+
def _run_pre_commit_update(*, modifications: MutableSet[Path] | None = None) -> None:
|
|
1144
|
+
current = PRE_COMMIT_CONFIG_YAML.read_text()
|
|
1145
|
+
logged_run("pre-commit", "autoupdate", print=True)
|
|
1146
|
+
if (modifications is not None) and (PRE_COMMIT_CONFIG_YAML.read_text() != current):
|
|
1147
|
+
modifications.add(PRE_COMMIT_CONFIG_YAML)
|
|
1213
1148
|
|
|
1214
|
-
def run_autoupdate() -> None:
|
|
1215
|
-
current = PRE_COMMIT_CONFIG_YAML.read_text()
|
|
1216
|
-
run("pre-commit", "autoupdate", print=True)
|
|
1217
|
-
with writer(cache, overwrite=True) as temp:
|
|
1218
|
-
_ = temp.write_text(get_now().format_iso())
|
|
1219
|
-
if (modifications is not None) and (
|
|
1220
|
-
PRE_COMMIT_CONFIG_YAML.read_text() != current
|
|
1221
|
-
):
|
|
1222
|
-
modifications.add(PRE_COMMIT_CONFIG_YAML)
|
|
1223
1149
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
run_autoupdate()
|
|
1228
|
-
else:
|
|
1229
|
-
prev = ZonedDateTime.parse_iso(text.rstrip("\n"))
|
|
1230
|
-
if prev < (get_now() - 12 * HOUR):
|
|
1231
|
-
run_autoupdate()
|
|
1150
|
+
run_pre_commit_update = throttle(
|
|
1151
|
+
delta=12 * HOUR, path=PATH_THROTTLE_CACHE / _run_pre_commit_update.__name__
|
|
1152
|
+
)(_run_pre_commit_update)
|
|
1232
1153
|
|
|
1233
1154
|
|
|
1234
1155
|
##
|
|
@@ -1247,22 +1168,21 @@ def run_ripgrep_and_replace(
|
|
|
1247
1168
|
)
|
|
1248
1169
|
if result is None:
|
|
1249
1170
|
return
|
|
1250
|
-
for path in
|
|
1251
|
-
with yield_text_file(path, modifications=modifications) as
|
|
1252
|
-
|
|
1171
|
+
for path in result.splitlines():
|
|
1172
|
+
with yield_text_file(path, modifications=modifications) as context:
|
|
1173
|
+
context.output = sub(
|
|
1253
1174
|
r'# requires-python = ">=\d+\.\d+"',
|
|
1254
1175
|
rf'# requires-python = ">={version}"',
|
|
1255
|
-
|
|
1176
|
+
context.input,
|
|
1256
1177
|
flags=MULTILINE,
|
|
1257
1178
|
)
|
|
1258
|
-
_ = temp.write_text(text)
|
|
1259
1179
|
|
|
1260
1180
|
|
|
1261
1181
|
##
|
|
1262
1182
|
|
|
1263
1183
|
|
|
1264
1184
|
def set_version(version: Version, /) -> None:
|
|
1265
|
-
|
|
1185
|
+
logged_run(
|
|
1266
1186
|
"bump-my-version",
|
|
1267
1187
|
"replace",
|
|
1268
1188
|
"--new-version",
|
|
@@ -1318,35 +1238,6 @@ def update_action_versions(*, modifications: MutableSet[Path] | None = None) ->
|
|
|
1318
1238
|
##
|
|
1319
1239
|
|
|
1320
1240
|
|
|
1321
|
-
def write_text(
|
|
1322
|
-
verb: str,
|
|
1323
|
-
src: PathLike,
|
|
1324
|
-
dest: PathLike,
|
|
1325
|
-
/,
|
|
1326
|
-
*,
|
|
1327
|
-
modifications: MutableSet[Path] | None = None,
|
|
1328
|
-
) -> None:
|
|
1329
|
-
src, dest = map(Path, [src, dest])
|
|
1330
|
-
LOGGER.info("%s '%s'...", verb, dest)
|
|
1331
|
-
text = src.read_text().rstrip("\n") + "\n"
|
|
1332
|
-
with writer(dest, overwrite=True) as temp:
|
|
1333
|
-
_ = temp.write_text(text)
|
|
1334
|
-
if modifications is not None:
|
|
1335
|
-
modifications.add(dest)
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
##
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
def yaml_dump(obj: Any, /) -> str:
|
|
1342
|
-
stream = StringIO()
|
|
1343
|
-
YAML_INSTANCE.dump(obj, stream)
|
|
1344
|
-
return stream.getvalue()
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
##
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
1241
|
@contextmanager
|
|
1351
1242
|
def yield_bumpversion_toml(
|
|
1352
1243
|
*, modifications: MutableSet[Path] | None = None
|
|
@@ -1362,19 +1253,6 @@ def yield_bumpversion_toml(
|
|
|
1362
1253
|
##
|
|
1363
1254
|
|
|
1364
1255
|
|
|
1365
|
-
@contextmanager
|
|
1366
|
-
def yield_json_dict(
|
|
1367
|
-
path: PathLike, /, *, modifications: MutableSet[Path] | None = None
|
|
1368
|
-
) -> Iterator[StrDict]:
|
|
1369
|
-
with yield_write_context(
|
|
1370
|
-
path, json.loads, dict, json.dumps, modifications=modifications
|
|
1371
|
-
) as dict_:
|
|
1372
|
-
yield dict_
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
##
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
1256
|
def yield_python_versions(
|
|
1379
1257
|
version: str, /, *, max_: str = MAX_PYTHON_VERSION
|
|
1380
1258
|
) -> Iterator[str]:
|
|
@@ -1398,83 +1276,6 @@ def _yield_python_version_tuple(version: str, /) -> tuple[int, int]:
|
|
|
1398
1276
|
##
|
|
1399
1277
|
|
|
1400
1278
|
|
|
1401
|
-
@contextmanager
|
|
1402
|
-
def yield_text_file(
|
|
1403
|
-
path: PathLike, /, *, modifications: MutableSet[Path] | None = None
|
|
1404
|
-
) -> Iterator[Path]:
|
|
1405
|
-
path = Path(path)
|
|
1406
|
-
try:
|
|
1407
|
-
current = path.read_text()
|
|
1408
|
-
except FileNotFoundError:
|
|
1409
|
-
with TemporaryFile() as temp:
|
|
1410
|
-
yield temp
|
|
1411
|
-
write_text("Writing", temp, path, modifications=modifications)
|
|
1412
|
-
else:
|
|
1413
|
-
with TemporaryFile(text=current) as temp:
|
|
1414
|
-
yield temp
|
|
1415
|
-
if temp.read_text().rstrip("\n") != current.rstrip("\n"):
|
|
1416
|
-
write_text("Writing", temp, path, modifications=modifications)
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
##
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
@contextmanager
|
|
1423
|
-
def yield_toml_doc(
|
|
1424
|
-
path: PathLike, /, *, modifications: MutableSet[Path] | None = None
|
|
1425
|
-
) -> Iterator[TOMLDocument]:
|
|
1426
|
-
with yield_write_context(
|
|
1427
|
-
path, tomlkit.parse, document, tomlkit.dumps, modifications=modifications
|
|
1428
|
-
) as doc:
|
|
1429
|
-
yield doc
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
##
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
@contextmanager
|
|
1436
|
-
def yield_write_context[T](
|
|
1437
|
-
path: PathLike,
|
|
1438
|
-
loads: Callable[[str], T],
|
|
1439
|
-
get_default: Callable[[], T],
|
|
1440
|
-
dumps: Callable[[T], str],
|
|
1441
|
-
/,
|
|
1442
|
-
*,
|
|
1443
|
-
modifications: MutableSet[Path] | None = None,
|
|
1444
|
-
) -> Iterator[T]:
|
|
1445
|
-
path = Path(path)
|
|
1446
|
-
|
|
1447
|
-
def run_write(verb: str, data: T, /) -> None:
|
|
1448
|
-
with writer(path, overwrite=True) as temp:
|
|
1449
|
-
_ = temp.write_text(dumps(data))
|
|
1450
|
-
write_text(verb, temp, path, modifications=modifications)
|
|
1451
|
-
|
|
1452
|
-
try:
|
|
1453
|
-
current = path.read_text()
|
|
1454
|
-
except FileNotFoundError:
|
|
1455
|
-
yield (default := get_default())
|
|
1456
|
-
run_write("Writing", default)
|
|
1457
|
-
else:
|
|
1458
|
-
data = loads(current)
|
|
1459
|
-
yield data
|
|
1460
|
-
is_equal = data == loads(current) # tomlkit cannot handle !=
|
|
1461
|
-
if not is_equal:
|
|
1462
|
-
run_write("Modifying", data)
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
##
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
@contextmanager
|
|
1469
|
-
def yield_yaml_dict(
|
|
1470
|
-
path: PathLike, /, *, modifications: MutableSet[Path] | None = None
|
|
1471
|
-
) -> Iterator[StrDict]:
|
|
1472
|
-
with yield_write_context(
|
|
1473
|
-
path, YAML_INSTANCE.load, dict, yaml_dump, modifications=modifications
|
|
1474
|
-
) as dict_:
|
|
1475
|
-
yield dict_
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
1279
|
__all__ = [
|
|
1479
1280
|
"add_bumpversion_toml",
|
|
1480
1281
|
"add_coveragerc_toml",
|
|
@@ -1489,34 +1290,17 @@ __all__ = [
|
|
|
1489
1290
|
"add_readme_md",
|
|
1490
1291
|
"add_ruff_toml",
|
|
1491
1292
|
"check_versions",
|
|
1492
|
-
"
|
|
1493
|
-
"ensure_contains",
|
|
1494
|
-
"ensure_contains_partial",
|
|
1495
|
-
"ensure_not_contains",
|
|
1496
|
-
"get_aot",
|
|
1497
|
-
"get_array",
|
|
1498
|
-
"get_dict",
|
|
1499
|
-
"get_list",
|
|
1500
|
-
"get_partial_dict",
|
|
1293
|
+
"get_cron_job",
|
|
1501
1294
|
"get_python_package_name",
|
|
1502
|
-
"get_table",
|
|
1503
1295
|
"get_version_from_bumpversion_toml",
|
|
1504
1296
|
"get_version_from_git_show",
|
|
1505
1297
|
"get_version_from_git_tag",
|
|
1506
|
-
"is_partial_dict",
|
|
1507
1298
|
"run_bump_my_version",
|
|
1508
1299
|
"run_pre_commit_update",
|
|
1509
1300
|
"run_ripgrep_and_replace",
|
|
1510
1301
|
"set_version",
|
|
1511
1302
|
"update_action_file_extensions",
|
|
1512
1303
|
"update_action_versions",
|
|
1513
|
-
"write_text",
|
|
1514
|
-
"yaml_dump",
|
|
1515
1304
|
"yield_bumpversion_toml",
|
|
1516
|
-
"yield_json_dict",
|
|
1517
1305
|
"yield_python_versions",
|
|
1518
|
-
"yield_text_file",
|
|
1519
|
-
"yield_toml_doc",
|
|
1520
|
-
"yield_write_context",
|
|
1521
|
-
"yield_yaml_dict",
|
|
1522
1306
|
]
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typed_settings import load_settings, option, settings
|
|
4
4
|
|
|
5
|
-
from actions.conformalize_repo.constants import RUN_VERSION_BUMP
|
|
5
|
+
from actions.pre_commit.conformalize_repo.constants import RUN_VERSION_BUMP
|
|
6
6
|
from actions.utilities import LOADER
|
|
7
7
|
|
|
8
8
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from utilities.logging import basic_config
|
|
6
|
+
from utilities.os import is_pytest
|
|
7
|
+
|
|
8
|
+
from actions.logging import LOGGER
|
|
9
|
+
from actions.pre_commit.click import path_argument
|
|
10
|
+
from actions.pre_commit.format_requirements.lib import format_requirements
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@path_argument
|
|
17
|
+
def format_requirements_sub_cmd(*, paths: tuple[Path, ...]) -> None:
|
|
18
|
+
if is_pytest():
|
|
19
|
+
return
|
|
20
|
+
basic_config(obj=LOGGER)
|
|
21
|
+
format_requirements(*paths)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__all__ = ["format_requirements_sub_cmd"]
|