dycw-actions 0.11.3__py3-none-any.whl → 0.14.0__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/.DS_Store +0 -0
- actions/__init__.py +1 -1
- actions/cli.py +5 -0
- actions/pre_commit/conformalize_repo/cli.py +1 -1
- actions/pre_commit/conformalize_repo/lib.py +128 -109
- actions/pre_commit/conformalize_repo/settings.py +3 -3
- actions/pre_commit/constants.py +3 -3
- actions/pre_commit/touch_empty_py/lib.py +2 -2
- actions/pre_commit/touch_py_typed/lib.py +4 -3
- actions/pre_commit/update_requirements/cli.py +10 -2
- actions/pre_commit/update_requirements/lib.py +74 -14
- actions/pre_commit/update_requirements/settings.py +23 -0
- actions/pre_commit/utilities.py +131 -39
- actions/publish_package/lib.py +17 -11
- actions/random_sleep/lib.py +3 -3
- actions/re_encrypt/__init__.py +1 -0
- actions/re_encrypt/cli.py +36 -0
- actions/re_encrypt/constants.py +7 -0
- actions/re_encrypt/lib.py +115 -0
- actions/re_encrypt/settings.py +26 -0
- actions/run_hooks/lib.py +13 -11
- actions/types.py +5 -9
- {dycw_actions-0.11.3.dist-info → dycw_actions-0.14.0.dist-info}/METADATA +4 -2
- {dycw_actions-0.11.3.dist-info → dycw_actions-0.14.0.dist-info}/RECORD +26 -19
- {dycw_actions-0.11.3.dist-info → dycw_actions-0.14.0.dist-info}/WHEEL +1 -1
- {dycw_actions-0.11.3.dist-info → dycw_actions-0.14.0.dist-info}/entry_points.txt +0 -0
actions/pre_commit/constants.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from utilities.
|
|
3
|
+
from utilities.constants import HOUR
|
|
4
4
|
|
|
5
5
|
from actions.constants import PATH_ACTIONS
|
|
6
6
|
|
|
7
7
|
PATH_PRE_COMMIT = PATH_ACTIONS / "pre_commit"
|
|
8
|
-
|
|
8
|
+
THROTTLE_DURATION = 12 * HOUR
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
__all__ = ["PATH_PRE_COMMIT", "
|
|
11
|
+
__all__ = ["PATH_PRE_COMMIT", "THROTTLE_DURATION"]
|
|
@@ -11,7 +11,7 @@ from utilities.throttle import throttle
|
|
|
11
11
|
|
|
12
12
|
from actions import __version__
|
|
13
13
|
from actions.logging import LOGGER
|
|
14
|
-
from actions.pre_commit.constants import
|
|
14
|
+
from actions.pre_commit.constants import THROTTLE_DURATION
|
|
15
15
|
from actions.pre_commit.utilities import path_throttle_cache, yield_python_file
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
@@ -36,7 +36,7 @@ def _touch_empty_py(*paths: PathLike) -> None:
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
touch_empty_py = throttle(
|
|
39
|
-
|
|
39
|
+
duration=THROTTLE_DURATION, path=path_throttle_cache(_touch_empty_py)
|
|
40
40
|
)(_touch_empty_py)
|
|
41
41
|
|
|
42
42
|
|
|
@@ -11,8 +11,9 @@ from utilities.text import repr_str
|
|
|
11
11
|
from utilities.throttle import throttle
|
|
12
12
|
|
|
13
13
|
from actions import __version__
|
|
14
|
+
from actions.constants import PYPROJECT_TOML
|
|
14
15
|
from actions.logging import LOGGER
|
|
15
|
-
from actions.pre_commit.constants import
|
|
16
|
+
from actions.pre_commit.constants import THROTTLE_DURATION
|
|
16
17
|
from actions.pre_commit.utilities import path_throttle_cache
|
|
17
18
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
@@ -36,7 +37,7 @@ def _touch_py_typed(*paths: PathLike) -> None:
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
touch_py_typed = throttle(
|
|
39
|
-
|
|
40
|
+
duration=THROTTLE_DURATION, path=path_throttle_cache(_touch_py_typed)
|
|
40
41
|
)(_touch_py_typed)
|
|
41
42
|
|
|
42
43
|
|
|
@@ -47,7 +48,7 @@ def _format_path(
|
|
|
47
48
|
if not path.is_file():
|
|
48
49
|
msg = f"Expected a file; {str(path)!r} is not"
|
|
49
50
|
raise FileNotFoundError(msg)
|
|
50
|
-
if path.name !=
|
|
51
|
+
if path.name != PYPROJECT_TOML.name:
|
|
51
52
|
msg = f"Expected 'pyproject.toml'; got {str(path)!r}"
|
|
52
53
|
raise TypeError(msg)
|
|
53
54
|
src = path.parent / "src"
|
|
@@ -2,23 +2,31 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from typed_settings import click_options
|
|
5
6
|
from utilities.logging import basic_config
|
|
6
7
|
from utilities.os import is_pytest
|
|
7
8
|
|
|
8
9
|
from actions.logging import LOGGER
|
|
9
10
|
from actions.pre_commit.click import path_argument
|
|
10
11
|
from actions.pre_commit.update_requirements.lib import update_requirements
|
|
12
|
+
from actions.pre_commit.update_requirements.settings import Settings
|
|
13
|
+
from actions.utilities import LOADER
|
|
11
14
|
|
|
12
15
|
if TYPE_CHECKING:
|
|
13
16
|
from pathlib import Path
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
@path_argument
|
|
17
|
-
|
|
20
|
+
@click_options(Settings, [LOADER], show_envvars_in_help=True)
|
|
21
|
+
def update_requirements_sub_cmd(
|
|
22
|
+
settings: Settings, /, *, paths: tuple[Path, ...]
|
|
23
|
+
) -> None:
|
|
18
24
|
if is_pytest():
|
|
19
25
|
return
|
|
20
26
|
basic_config(obj=LOGGER)
|
|
21
|
-
update_requirements(
|
|
27
|
+
update_requirements(
|
|
28
|
+
*paths, indexes=settings.indexes, native_tls=settings.native_tls
|
|
29
|
+
)
|
|
22
30
|
|
|
23
31
|
|
|
24
32
|
__all__ = ["update_requirements_sub_cmd"]
|
|
@@ -4,8 +4,9 @@ import sys
|
|
|
4
4
|
from functools import partial
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
+
from ordered_set import OrderedSet
|
|
7
8
|
from pydantic import TypeAdapter
|
|
8
|
-
from utilities.functions import get_func_name, max_nullable
|
|
9
|
+
from utilities.functions import ensure_str, get_func_name, max_nullable
|
|
9
10
|
from utilities.tabulate import func_param_desc
|
|
10
11
|
from utilities.text import repr_str
|
|
11
12
|
|
|
@@ -20,11 +21,18 @@ from actions.pre_commit.update_requirements.classes import (
|
|
|
20
21
|
parse_version1_or_2,
|
|
21
22
|
parse_version2_or_3,
|
|
22
23
|
)
|
|
23
|
-
from actions.pre_commit.
|
|
24
|
+
from actions.pre_commit.update_requirements.settings import SETTINGS
|
|
25
|
+
from actions.pre_commit.utilities import (
|
|
26
|
+
get_aot,
|
|
27
|
+
get_pyproject_dependencies,
|
|
28
|
+
get_table,
|
|
29
|
+
yield_pyproject_toml,
|
|
30
|
+
yield_toml_doc,
|
|
31
|
+
)
|
|
24
32
|
from actions.utilities import logged_run
|
|
25
33
|
|
|
26
34
|
if TYPE_CHECKING:
|
|
27
|
-
from collections.abc import MutableSet
|
|
35
|
+
from collections.abc import Iterator, MutableSet
|
|
28
36
|
from pathlib import Path
|
|
29
37
|
|
|
30
38
|
from utilities.packaging import Requirement
|
|
@@ -33,11 +41,25 @@ if TYPE_CHECKING:
|
|
|
33
41
|
from actions.pre_commit.update_requirements.classes import Version2or3, VersionSet
|
|
34
42
|
|
|
35
43
|
|
|
36
|
-
def update_requirements(
|
|
37
|
-
|
|
44
|
+
def update_requirements(
|
|
45
|
+
*paths: PathLike,
|
|
46
|
+
indexes: list[str] | None = SETTINGS.indexes,
|
|
47
|
+
native_tls: bool = SETTINGS.native_tls,
|
|
48
|
+
) -> None:
|
|
49
|
+
LOGGER.info(
|
|
50
|
+
func_param_desc(
|
|
51
|
+
update_requirements,
|
|
52
|
+
__version__,
|
|
53
|
+
f"{paths=}",
|
|
54
|
+
f"{indexes=}",
|
|
55
|
+
f"{native_tls=}",
|
|
56
|
+
)
|
|
57
|
+
)
|
|
38
58
|
modifications: set[Path] = set()
|
|
39
59
|
for path in paths:
|
|
40
|
-
_format_path(
|
|
60
|
+
_format_path(
|
|
61
|
+
path, indexes=indexes, native_tls=native_tls, modifications=modifications
|
|
62
|
+
)
|
|
41
63
|
if len(modifications) >= 1:
|
|
42
64
|
LOGGER.info(
|
|
43
65
|
"Exiting due to modifications: %s",
|
|
@@ -52,24 +74,40 @@ def _format_path(
|
|
|
52
74
|
/,
|
|
53
75
|
*,
|
|
54
76
|
versions: VersionSet | None = None,
|
|
77
|
+
indexes: list[str] | None = SETTINGS.indexes,
|
|
78
|
+
native_tls: bool = SETTINGS.native_tls,
|
|
55
79
|
modifications: MutableSet[Path] | None = None,
|
|
56
80
|
) -> None:
|
|
57
|
-
versions_use =
|
|
81
|
+
versions_use = (
|
|
82
|
+
_get_versions(indexes=indexes, native_tls=native_tls)
|
|
83
|
+
if versions is None
|
|
84
|
+
else versions
|
|
85
|
+
)
|
|
58
86
|
with yield_toml_doc(path, modifications=modifications) as doc:
|
|
59
87
|
get_pyproject_dependencies(doc).apply(
|
|
60
88
|
partial(_format_req, versions=versions_use)
|
|
61
89
|
)
|
|
62
90
|
|
|
63
91
|
|
|
64
|
-
def _get_versions(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
92
|
+
def _get_versions(
|
|
93
|
+
*,
|
|
94
|
+
indexes: list[str] | None = SETTINGS.indexes,
|
|
95
|
+
native_tls: bool = SETTINGS.native_tls,
|
|
96
|
+
) -> VersionSet:
|
|
97
|
+
index_args: OrderedSet[str] = OrderedSet([])
|
|
98
|
+
_ = index_args.update(list(_yield_indexes()))
|
|
99
|
+
if indexes is not None:
|
|
100
|
+
_ = index_args.update(indexes)
|
|
101
|
+
head: list[str] = ["uv", "pip", "list", "--format", "json"]
|
|
102
|
+
tail: list[str] = ["--strict"]
|
|
103
|
+
if len(index_args) >= 1:
|
|
104
|
+
tail.extend(["--index", ",".join(index_args)])
|
|
105
|
+
if native_tls:
|
|
106
|
+
tail.append("--native-tls")
|
|
107
|
+
json1 = logged_run(*head, *tail, return_=True)
|
|
68
108
|
models1 = TypeAdapter(list[PipListOutput]).validate_json(json1)
|
|
69
109
|
versions1 = {p.name: parse_version2_or_3(p.version) for p in models1}
|
|
70
|
-
json2 = logged_run(
|
|
71
|
-
"uv", "pip", "list", "--format", "json", "--outdated", "--strict", return_=True
|
|
72
|
-
)
|
|
110
|
+
json2 = logged_run(*head, "--outdated", *tail, return_=True)
|
|
73
111
|
models2 = TypeAdapter(list[PipListOutdatedOutput]).validate_json(json2)
|
|
74
112
|
versions2 = {p.name: parse_version2_or_3(p.latest_version) for p in models2}
|
|
75
113
|
out: StrDict = {}
|
|
@@ -78,6 +116,28 @@ def _get_versions() -> VersionSet:
|
|
|
78
116
|
return out
|
|
79
117
|
|
|
80
118
|
|
|
119
|
+
def _yield_indexes() -> Iterator[str]:
|
|
120
|
+
try:
|
|
121
|
+
with yield_pyproject_toml() as doc:
|
|
122
|
+
try:
|
|
123
|
+
tool = get_table(doc, "tool")
|
|
124
|
+
except KeyError:
|
|
125
|
+
return
|
|
126
|
+
try:
|
|
127
|
+
uv = get_table(tool, "uv")
|
|
128
|
+
except KeyError:
|
|
129
|
+
return
|
|
130
|
+
try:
|
|
131
|
+
indexes = get_aot(uv, "index")
|
|
132
|
+
except KeyError:
|
|
133
|
+
return
|
|
134
|
+
else:
|
|
135
|
+
for index in indexes:
|
|
136
|
+
yield ensure_str(index["url"])
|
|
137
|
+
except FileNotFoundError:
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
|
|
81
141
|
def _format_req(requirement: Requirement, /, *, versions: VersionSet) -> Requirement:
|
|
82
142
|
try:
|
|
83
143
|
lower = parse_version2_or_3(requirement[">="])
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typed_settings import load_settings, option, settings
|
|
4
|
+
|
|
5
|
+
from actions.utilities import LOADER
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@settings
|
|
9
|
+
class Settings:
|
|
10
|
+
indexes: list[str] | None = option(
|
|
11
|
+
factory=list,
|
|
12
|
+
help="List of URLs as additional indexes when searching for packages",
|
|
13
|
+
)
|
|
14
|
+
native_tls: bool = option(
|
|
15
|
+
default=False,
|
|
16
|
+
help="Whether to load TLS certificates from the platform's native certificate store",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
SETTINGS = load_settings(Settings, [LOADER])
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = ["SETTINGS", "Settings"]
|
actions/pre_commit/utilities.py
CHANGED
|
@@ -5,7 +5,7 @@ from collections.abc import Iterator, MutableSet
|
|
|
5
5
|
from contextlib import contextmanager
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import TYPE_CHECKING, Any, assert_never
|
|
8
|
+
from typing import TYPE_CHECKING, Any, assert_never, overload
|
|
9
9
|
|
|
10
10
|
import tomlkit
|
|
11
11
|
from libcst import Module, parse_module
|
|
@@ -16,8 +16,9 @@ from utilities.functions import ensure_class, ensure_str, get_func_name
|
|
|
16
16
|
from utilities.iterables import OneEmptyError, OneNonUniqueError, one
|
|
17
17
|
from utilities.packaging import Requirement
|
|
18
18
|
from utilities.types import PathLike, StrDict
|
|
19
|
+
from utilities.typing import is_str_dict
|
|
19
20
|
|
|
20
|
-
from actions.constants import PATH_CACHE, YAML_INSTANCE
|
|
21
|
+
from actions.constants import PATH_CACHE, PYPROJECT_TOML, YAML_INSTANCE
|
|
21
22
|
from actions.logging import LOGGER
|
|
22
23
|
from actions.utilities import are_equal_modulo_new_line, write_text, yaml_dump
|
|
23
24
|
|
|
@@ -26,26 +27,26 @@ if TYPE_CHECKING:
|
|
|
26
27
|
|
|
27
28
|
from utilities.types import PathLike, StrDict
|
|
28
29
|
|
|
29
|
-
from actions.types import
|
|
30
|
+
from actions.types import ArrayLike, ContainerLike, FuncRequirement
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
for table_ in tables:
|
|
34
|
-
if table_ not in array:
|
|
35
|
-
array.append(table_)
|
|
33
|
+
##
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
@overload
|
|
37
|
+
def ensure_contains(container: AoT, /, *objs: Table) -> None: ...
|
|
38
|
+
@overload
|
|
39
|
+
def ensure_contains(container: list[str], /, *objs: str) -> None: ...
|
|
40
|
+
@overload
|
|
41
|
+
def ensure_contains(container: list[StrDict], /, *objs: StrDict) -> None: ...
|
|
42
|
+
def ensure_contains(container: ArrayLike, /, *objs: Any) -> None:
|
|
42
43
|
for obj in objs:
|
|
43
|
-
if obj not in
|
|
44
|
-
|
|
44
|
+
if obj not in container:
|
|
45
|
+
container.append(obj)
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
def ensure_contains_partial_dict(
|
|
48
|
-
container:
|
|
49
|
+
container: list[StrDict], partial: StrDict, /, *, extra: StrDict | None = None
|
|
49
50
|
) -> StrDict:
|
|
50
51
|
try:
|
|
51
52
|
return get_partial_dict(container, partial, skip_log=True)
|
|
@@ -55,52 +56,123 @@ def ensure_contains_partial_dict(
|
|
|
55
56
|
return dict_
|
|
56
57
|
|
|
57
58
|
|
|
58
|
-
def ensure_contains_partial_str(
|
|
59
|
+
def ensure_contains_partial_str(list_: Array | list[str], text: str, /) -> str:
|
|
59
60
|
try:
|
|
60
|
-
return get_partial_str(
|
|
61
|
+
return get_partial_str(list_, text, skip_log=True)
|
|
61
62
|
except OneEmptyError:
|
|
62
|
-
|
|
63
|
+
list_.append(text)
|
|
63
64
|
return text
|
|
64
65
|
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
@overload
|
|
68
|
+
def ensure_not_contains(container: AoT, /, *objs: Table) -> None: ...
|
|
69
|
+
@overload
|
|
70
|
+
def ensure_not_contains(container: list[str], /, *objs: str) -> None: ...
|
|
71
|
+
@overload
|
|
72
|
+
def ensure_not_contains(container: list[StrDict], /, *objs: StrDict) -> None: ...
|
|
73
|
+
def ensure_not_contains(container: ArrayLike, /, *objs: Any) -> None:
|
|
67
74
|
for obj in objs:
|
|
68
75
|
try:
|
|
69
|
-
index = next(i for i, o in enumerate(
|
|
76
|
+
index = next(i for i, o in enumerate(container) if o == obj)
|
|
70
77
|
except StopIteration:
|
|
71
78
|
pass
|
|
72
79
|
else:
|
|
73
|
-
del
|
|
80
|
+
del container[index]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_aot(container: ContainerLike, key: str, /) -> AoT:
|
|
87
|
+
return ensure_class(container[key], AoT)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def get_array(container: ContainerLike, key: str, /) -> Array:
|
|
91
|
+
return ensure_class(container[key], Array)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_dict(dict_: StrDict, key: str, /) -> StrDict:
|
|
95
|
+
if is_str_dict(value := dict_[key]):
|
|
96
|
+
return value
|
|
97
|
+
raise TypeError(value)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_list_dicts(dict_: StrDict, key: str, /) -> list[StrDict]:
|
|
101
|
+
list_ = ensure_class(dict_[key], list)
|
|
102
|
+
for i in list_:
|
|
103
|
+
if not is_str_dict(i):
|
|
104
|
+
raise TypeError(i)
|
|
105
|
+
return list_
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_list_strs(dict_: StrDict, key: str, /) -> list[str]:
|
|
109
|
+
list_ = ensure_class(dict_[key], list)
|
|
110
|
+
for i in list_:
|
|
111
|
+
if not isinstance(i, str):
|
|
112
|
+
raise TypeError(i)
|
|
113
|
+
return list_
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_table(container: ContainerLike, key: str, /) -> Table:
|
|
117
|
+
return ensure_class(container[key], Table)
|
|
74
118
|
|
|
75
119
|
|
|
76
120
|
##
|
|
77
121
|
|
|
78
122
|
|
|
79
|
-
def
|
|
80
|
-
|
|
123
|
+
def get_set_aot(container: ContainerLike, key: str, /) -> AoT:
|
|
124
|
+
try:
|
|
125
|
+
return get_aot(container, key)
|
|
126
|
+
except KeyError:
|
|
127
|
+
value = container[key] = aot()
|
|
128
|
+
return value
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_set_array(container: ContainerLike, key: str, /) -> Array:
|
|
132
|
+
try:
|
|
133
|
+
return get_array(container, key)
|
|
134
|
+
except KeyError:
|
|
135
|
+
value = container[key] = array()
|
|
136
|
+
return value
|
|
81
137
|
|
|
82
138
|
|
|
83
|
-
def
|
|
84
|
-
|
|
139
|
+
def get_set_dict(dict_: StrDict, key: str, /) -> StrDict:
|
|
140
|
+
try:
|
|
141
|
+
return get_dict(dict_, key)
|
|
142
|
+
except KeyError:
|
|
143
|
+
value = dict_[key] = {}
|
|
144
|
+
return value
|
|
85
145
|
|
|
86
146
|
|
|
87
|
-
def
|
|
88
|
-
|
|
147
|
+
def get_set_list_dicts(dict_: StrDict, key: str, /) -> list[StrDict]:
|
|
148
|
+
try:
|
|
149
|
+
return get_list_dicts(dict_, key)
|
|
150
|
+
except KeyError:
|
|
151
|
+
value = dict_[key] = []
|
|
152
|
+
return value
|
|
89
153
|
|
|
90
154
|
|
|
91
|
-
def
|
|
92
|
-
|
|
155
|
+
def get_set_list_strs(dict_: StrDict, key: str, /) -> list[str]:
|
|
156
|
+
try:
|
|
157
|
+
return get_list_strs(dict_, key)
|
|
158
|
+
except KeyError:
|
|
159
|
+
value = dict_[key] = []
|
|
160
|
+
return value
|
|
93
161
|
|
|
94
162
|
|
|
95
|
-
def
|
|
96
|
-
|
|
163
|
+
def get_set_table(container: ContainerLike, key: str, /) -> Table:
|
|
164
|
+
try:
|
|
165
|
+
return get_table(container, key)
|
|
166
|
+
except KeyError:
|
|
167
|
+
value = container[key] = table()
|
|
168
|
+
return value
|
|
97
169
|
|
|
98
170
|
|
|
99
171
|
##
|
|
100
172
|
|
|
101
173
|
|
|
102
174
|
def get_partial_dict(
|
|
103
|
-
iterable: Iterable[
|
|
175
|
+
iterable: Iterable[StrDict], dict_: StrDict, /, *, skip_log: bool = False
|
|
104
176
|
) -> StrDict:
|
|
105
177
|
try:
|
|
106
178
|
return one(i for i in iterable if is_partial_dict(dict_, i))
|
|
@@ -177,19 +249,21 @@ def is_partial_str(obj: Any, text: str, /) -> bool:
|
|
|
177
249
|
def get_pyproject_dependencies(doc: TOMLDocument, /) -> PyProjectDependencies:
|
|
178
250
|
out = PyProjectDependencies()
|
|
179
251
|
if (project_key := "project") in doc:
|
|
180
|
-
project =
|
|
252
|
+
project = get_set_table(doc, project_key)
|
|
181
253
|
if (dep_key := "dependencies") in project:
|
|
182
|
-
out.dependencies =
|
|
254
|
+
out.dependencies = get_set_array(project, dep_key)
|
|
183
255
|
if (opt_dep_key := "optional-dependencies") in project:
|
|
184
|
-
opt_dependencies =
|
|
256
|
+
opt_dependencies = get_set_table(project, opt_dep_key)
|
|
185
257
|
out.opt_dependencies = {}
|
|
186
258
|
for key in opt_dependencies:
|
|
187
|
-
out.opt_dependencies[ensure_str(key)] =
|
|
259
|
+
out.opt_dependencies[ensure_str(key)] = get_set_array(
|
|
260
|
+
opt_dependencies, key
|
|
261
|
+
)
|
|
188
262
|
if (dep_grps_key := "dependency-groups") in doc:
|
|
189
|
-
dep_grps =
|
|
263
|
+
dep_grps = get_set_table(doc, dep_grps_key)
|
|
190
264
|
out.dep_groups = {}
|
|
191
265
|
for key in dep_grps:
|
|
192
|
-
out.dep_groups[ensure_str(key)] =
|
|
266
|
+
out.dep_groups[ensure_str(key)] = get_set_array(dep_grps, key)
|
|
193
267
|
return out
|
|
194
268
|
|
|
195
269
|
|
|
@@ -295,6 +369,17 @@ def yield_json_dict(
|
|
|
295
369
|
##
|
|
296
370
|
|
|
297
371
|
|
|
372
|
+
@contextmanager
|
|
373
|
+
def yield_pyproject_toml(
|
|
374
|
+
*, modifications: MutableSet[Path] | None = None
|
|
375
|
+
) -> Iterator[TOMLDocument]:
|
|
376
|
+
with yield_toml_doc(PYPROJECT_TOML, modifications=modifications) as doc:
|
|
377
|
+
yield doc
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
##
|
|
381
|
+
|
|
382
|
+
|
|
298
383
|
@contextmanager
|
|
299
384
|
def yield_mutable_write_context[T](
|
|
300
385
|
path: PathLike,
|
|
@@ -370,7 +455,6 @@ def yield_yaml_dict(
|
|
|
370
455
|
__all__ = [
|
|
371
456
|
"PyProjectDependencies",
|
|
372
457
|
"WriteContext",
|
|
373
|
-
"ensure_aot_contains",
|
|
374
458
|
"ensure_contains",
|
|
375
459
|
"ensure_contains_partial_dict",
|
|
376
460
|
"ensure_contains_partial_str",
|
|
@@ -378,10 +462,17 @@ __all__ = [
|
|
|
378
462
|
"get_aot",
|
|
379
463
|
"get_array",
|
|
380
464
|
"get_dict",
|
|
381
|
-
"
|
|
465
|
+
"get_list_dicts",
|
|
466
|
+
"get_list_strs",
|
|
382
467
|
"get_partial_dict",
|
|
383
468
|
"get_partial_str",
|
|
384
469
|
"get_pyproject_dependencies",
|
|
470
|
+
"get_set_aot",
|
|
471
|
+
"get_set_array",
|
|
472
|
+
"get_set_dict",
|
|
473
|
+
"get_set_list_dicts",
|
|
474
|
+
"get_set_list_strs",
|
|
475
|
+
"get_set_table",
|
|
385
476
|
"get_table",
|
|
386
477
|
"is_partial_dict",
|
|
387
478
|
"is_partial_str",
|
|
@@ -389,6 +480,7 @@ __all__ = [
|
|
|
389
480
|
"yield_immutable_write_context",
|
|
390
481
|
"yield_json_dict",
|
|
391
482
|
"yield_mutable_write_context",
|
|
483
|
+
"yield_pyproject_toml",
|
|
392
484
|
"yield_python_file",
|
|
393
485
|
"yield_text_file",
|
|
394
486
|
"yield_toml_doc",
|
actions/publish_package/lib.py
CHANGED
|
@@ -14,6 +14,8 @@ from actions.utilities import logged_run
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from typed_settings import Secret
|
|
16
16
|
|
|
17
|
+
from actions.types import SecretLike
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
def publish_package(
|
|
19
21
|
*,
|
|
@@ -34,18 +36,22 @@ def publish_package(
|
|
|
34
36
|
f"{native_tls=}",
|
|
35
37
|
)
|
|
36
38
|
)
|
|
39
|
+
build_head: list[str] = ["uv", "build", "--out-dir"]
|
|
40
|
+
build_tail: list[str] = ["--wheel", "--clear"]
|
|
41
|
+
publish: list[SecretLike] = ["uv", "publish"]
|
|
42
|
+
if username is not None:
|
|
43
|
+
publish.extend(["--username", username])
|
|
44
|
+
if password is not None:
|
|
45
|
+
publish.extend(["--password", password])
|
|
46
|
+
if publish_url is not None:
|
|
47
|
+
publish.extend(["--publish-url", publish_url])
|
|
48
|
+
if trusted_publishing:
|
|
49
|
+
publish.extend(["--trusted-publishing", "always"])
|
|
50
|
+
if native_tls:
|
|
51
|
+
publish.append("--native-tls")
|
|
37
52
|
with TemporaryDirectory() as temp:
|
|
38
|
-
logged_run(
|
|
39
|
-
logged_run(
|
|
40
|
-
"uv",
|
|
41
|
-
"publish",
|
|
42
|
-
*([] if username is None else ["--username", username]),
|
|
43
|
-
*([] if password is None else ["--password", password]),
|
|
44
|
-
*([] if publish_url is None else ["--publish-url", publish_url]),
|
|
45
|
-
*(["--trusted-publishing", "always"] if trusted_publishing else []),
|
|
46
|
-
*(["--native-tls"] if native_tls else []),
|
|
47
|
-
f"{temp}/*",
|
|
48
|
-
)
|
|
53
|
+
logged_run(*build_head, str(temp), *build_tail)
|
|
54
|
+
logged_run(*publish, f"{temp}/*")
|
|
49
55
|
LOGGER.info("Finished running %r", get_func_name(publish_package))
|
|
50
56
|
|
|
51
57
|
|
actions/random_sleep/lib.py
CHANGED
|
@@ -27,9 +27,9 @@ def random_sleep(
|
|
|
27
27
|
)
|
|
28
28
|
)
|
|
29
29
|
start = get_now()
|
|
30
|
-
|
|
31
|
-
LOGGER.info("Sleeping for %s...",
|
|
32
|
-
end = (start +
|
|
30
|
+
duration = TimeDelta(seconds=choice(range(min, max, step)))
|
|
31
|
+
LOGGER.info("Sleeping for %s...", duration)
|
|
32
|
+
end = (start + duration).round(mode="ceil")
|
|
33
33
|
while (now := get_now()) < end:
|
|
34
34
|
_intermediate(start, now, end, log_freq=log_freq)
|
|
35
35
|
LOGGER.info("Finished running %r", get_func_name(random_sleep))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from click import argument
|
|
8
|
+
from typed_settings import click_options
|
|
9
|
+
from utilities.logging import basic_config
|
|
10
|
+
from utilities.os import is_pytest
|
|
11
|
+
|
|
12
|
+
from actions.logging import LOGGER
|
|
13
|
+
from actions.re_encrypt.lib import re_encrypt
|
|
14
|
+
from actions.re_encrypt.settings import Settings
|
|
15
|
+
from actions.utilities import LOADER
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from utilities.types import PathLike
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@argument("path", type=click.Path(exists=True, dir_okay=False, path_type=Path))
|
|
22
|
+
@click_options(Settings, [LOADER], show_envvars_in_help=True)
|
|
23
|
+
def re_encrypt_sub_cmd(settings: Settings, /, *, path: PathLike) -> None:
|
|
24
|
+
if is_pytest():
|
|
25
|
+
return
|
|
26
|
+
basic_config(obj=LOGGER)
|
|
27
|
+
re_encrypt(
|
|
28
|
+
path,
|
|
29
|
+
key_file=settings.key_file,
|
|
30
|
+
key=settings.key,
|
|
31
|
+
new_key_file=settings.new_key_file,
|
|
32
|
+
new_key=settings.new_key,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = ["re_encrypt_sub_cmd"]
|