dycw-utilities 0.174.7__tar.gz → 0.174.8__tar.gz
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.
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/PKG-INFO +1 -1
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/pyproject.toml +3 -3
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/subprocess.py +109 -14
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/README.md +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/aeventkit.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/click.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/docker.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/git.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/grp.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/http.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/jinja2.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/json.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/math.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/os.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pwd.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pydantic_settings.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pydantic_settings_sops.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/random.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/re.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/shutil.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/string.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/testbook.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/text.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/types.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/version.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/zoneinfo.py +0 -0
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"pytest-cov >=7.0.0, <7.1",
|
|
29
29
|
"pytest-timeout >=2.4.0, <2.5",
|
|
30
30
|
]
|
|
31
|
-
fastapi = ["fastapi >=0.127.
|
|
31
|
+
fastapi = ["fastapi >=0.127.1, <0.128"]
|
|
32
32
|
fastapi-test = ["httpx", "uvicorn"]
|
|
33
33
|
fpdf2 = ["fpdf2 >=2.8.5, <2.9"]
|
|
34
34
|
gitpython = ["gitpython >=3.1.45, <3.2"]
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
name = "dycw-utilities"
|
|
102
102
|
readme = "README.md"
|
|
103
103
|
requires-python = ">= 3.12"
|
|
104
|
-
version = "0.174.
|
|
104
|
+
version = "0.174.8"
|
|
105
105
|
|
|
106
106
|
[project.entry-points.pytest11]
|
|
107
107
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
# bump-my-version
|
|
136
136
|
[tool.bumpversion]
|
|
137
137
|
allow_dirty = true
|
|
138
|
-
current_version = "0.174.
|
|
138
|
+
current_version = "0.174.8"
|
|
139
139
|
|
|
140
140
|
[[tool.bumpversion.files]]
|
|
141
141
|
filename = "src/utilities/__init__.py"
|
|
@@ -5,7 +5,7 @@ from contextlib import contextmanager
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from io import StringIO
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from shlex import join
|
|
8
|
+
from shlex import join
|
|
9
9
|
from string import Template
|
|
10
10
|
from subprocess import PIPE, CalledProcessError, Popen
|
|
11
11
|
from threading import Thread
|
|
@@ -40,22 +40,37 @@ RESTART_SSHD = ["systemctl", "restart", "sshd"]
|
|
|
40
40
|
UPDATE_CA_CERTIFICATES: str = "update-ca-certificates"
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
##
|
|
44
|
+
|
|
45
|
+
|
|
43
46
|
def apt_install_cmd(package: str, /) -> list[str]:
|
|
44
47
|
return ["apt", "install", "-y", package]
|
|
45
48
|
|
|
46
49
|
|
|
50
|
+
##
|
|
51
|
+
|
|
52
|
+
|
|
47
53
|
def cat_cmd(path: PathLike, /) -> list[str]:
|
|
48
54
|
return ["cat", str(path)]
|
|
49
55
|
|
|
50
56
|
|
|
57
|
+
##
|
|
58
|
+
|
|
59
|
+
|
|
51
60
|
def cd_cmd(path: PathLike, /) -> list[str]:
|
|
52
61
|
return ["cd", str(path)]
|
|
53
62
|
|
|
54
63
|
|
|
64
|
+
##
|
|
65
|
+
|
|
66
|
+
|
|
55
67
|
def chmod_cmd(path: PathLike, mode: str, /) -> list[str]:
|
|
56
68
|
return ["chmod", mode, str(path)]
|
|
57
69
|
|
|
58
70
|
|
|
71
|
+
##
|
|
72
|
+
|
|
73
|
+
|
|
59
74
|
def chown_cmd(
|
|
60
75
|
path: PathLike, /, *, user: str | None = None, group: str | None = None
|
|
61
76
|
) -> list[str]:
|
|
@@ -80,14 +95,23 @@ class ChownCmdError(Exception):
|
|
|
80
95
|
return "At least one of 'user' and/or 'group' must be given; got None"
|
|
81
96
|
|
|
82
97
|
|
|
98
|
+
##
|
|
99
|
+
|
|
100
|
+
|
|
83
101
|
def cp_cmd(src: PathLike, dest: PathLike, /) -> list[str]:
|
|
84
102
|
return ["cp", "-r", str(src), str(dest)]
|
|
85
103
|
|
|
86
104
|
|
|
105
|
+
##
|
|
106
|
+
|
|
107
|
+
|
|
87
108
|
def echo_cmd(text: str, /) -> list[str]:
|
|
88
109
|
return ["echo", text]
|
|
89
110
|
|
|
90
111
|
|
|
112
|
+
##
|
|
113
|
+
|
|
114
|
+
|
|
91
115
|
def expand_path(
|
|
92
116
|
path: PathLike, /, *, subs: StrMapping | None = None, sudo: bool = False
|
|
93
117
|
) -> Path:
|
|
@@ -98,47 +122,71 @@ def expand_path(
|
|
|
98
122
|
return Path(path).expanduser()
|
|
99
123
|
|
|
100
124
|
|
|
125
|
+
##
|
|
126
|
+
|
|
127
|
+
|
|
101
128
|
def git_clone_cmd(url: str, path: PathLike, /) -> list[str]:
|
|
102
129
|
return ["git", "clone", "--recurse-submodules", url, str(path)]
|
|
103
130
|
|
|
104
131
|
|
|
132
|
+
##
|
|
133
|
+
|
|
134
|
+
|
|
105
135
|
def git_hard_reset_cmd(*, branch: str | None = None) -> list[str]:
|
|
106
136
|
branch_use = "master" if branch is None else branch
|
|
107
137
|
return ["git", "hard-reset", branch_use]
|
|
108
138
|
|
|
109
139
|
|
|
140
|
+
##
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def maybe_parent(path: PathLike, /, *, parent: bool = False) -> Path:
|
|
144
|
+
path = Path(path)
|
|
145
|
+
return path.parent if parent else path
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
##
|
|
149
|
+
|
|
150
|
+
|
|
110
151
|
def maybe_sudo_cmd(cmd: str, /, *args: str, sudo: bool = False) -> list[str]:
|
|
111
152
|
parts: list[str] = [cmd, *args]
|
|
112
153
|
return sudo_cmd(*parts) if sudo else parts
|
|
113
154
|
|
|
114
155
|
|
|
156
|
+
##
|
|
157
|
+
|
|
158
|
+
|
|
115
159
|
def mkdir(path: PathLike, /, *, sudo: bool = False, parent: bool = False) -> None:
|
|
116
160
|
if sudo: # pragma: no cover
|
|
117
161
|
run(*sudo_cmd(*mkdir_cmd(path, parent=parent)))
|
|
118
162
|
else:
|
|
119
|
-
path =
|
|
120
|
-
|
|
121
|
-
|
|
163
|
+
maybe_parent(path, parent=parent).mkdir(parents=True, exist_ok=True)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
##
|
|
122
167
|
|
|
123
168
|
|
|
124
169
|
def mkdir_cmd(path: PathLike, /, *, parent: bool = False) -> list[str]:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
else:
|
|
130
|
-
args.append(quoted)
|
|
131
|
-
return args
|
|
170
|
+
return ["mkdir", "-p", str(maybe_parent(path, parent=parent))]
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
##
|
|
132
174
|
|
|
133
175
|
|
|
134
176
|
def mv_cmd(src: PathLike, dest: PathLike, /) -> list[str]:
|
|
135
177
|
return ["mv", str(src), str(dest)]
|
|
136
178
|
|
|
137
179
|
|
|
180
|
+
##
|
|
181
|
+
|
|
182
|
+
|
|
138
183
|
def rm_cmd(path: PathLike, /) -> list[str]:
|
|
139
184
|
return ["rm", "-rf", str(path)]
|
|
140
185
|
|
|
141
186
|
|
|
187
|
+
##
|
|
188
|
+
|
|
189
|
+
|
|
142
190
|
def rsync(
|
|
143
191
|
src_or_srcs: MaybeIterable[PathLike],
|
|
144
192
|
user: str,
|
|
@@ -153,7 +201,6 @@ def rsync(
|
|
|
153
201
|
print: bool = False, # noqa: A002
|
|
154
202
|
retry: Retry | None = None,
|
|
155
203
|
logger: LoggerLike | None = None,
|
|
156
|
-
archive: bool = False,
|
|
157
204
|
chown_user: str | None = None,
|
|
158
205
|
chown_group: str | None = None,
|
|
159
206
|
exclude: MaybeIterable[str] | None = None,
|
|
@@ -171,12 +218,13 @@ def rsync(
|
|
|
171
218
|
retry=retry,
|
|
172
219
|
logger=logger,
|
|
173
220
|
)
|
|
221
|
+
is_dir = any(Path(s).is_dir() for s in always_iterable(src_or_srcs)) # skipif-ci
|
|
174
222
|
rsync_args = rsync_cmd( # skipif-ci
|
|
175
223
|
src_or_srcs,
|
|
176
224
|
user,
|
|
177
225
|
hostname,
|
|
178
226
|
dest,
|
|
179
|
-
archive=
|
|
227
|
+
archive=is_dir,
|
|
180
228
|
chown_user=chown_user,
|
|
181
229
|
chown_group=chown_group,
|
|
182
230
|
exclude=exclude,
|
|
@@ -184,6 +232,7 @@ def rsync(
|
|
|
184
232
|
host_key_algorithms=host_key_algorithms,
|
|
185
233
|
strict_host_key_checking=strict_host_key_checking,
|
|
186
234
|
sudo=sudo,
|
|
235
|
+
parent=is_dir,
|
|
187
236
|
)
|
|
188
237
|
run(*rsync_args, print=print, retry=retry, logger=logger) # skipif-ci
|
|
189
238
|
if chmod is not None: # skipif-ci
|
|
@@ -201,6 +250,9 @@ def rsync(
|
|
|
201
250
|
)
|
|
202
251
|
|
|
203
252
|
|
|
253
|
+
##
|
|
254
|
+
|
|
255
|
+
|
|
204
256
|
def rsync_cmd(
|
|
205
257
|
src_or_srcs: MaybeIterable[PathLike],
|
|
206
258
|
user: str,
|
|
@@ -216,6 +268,7 @@ def rsync_cmd(
|
|
|
216
268
|
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
217
269
|
strict_host_key_checking: bool = True,
|
|
218
270
|
sudo: bool = False,
|
|
271
|
+
parent: bool = False,
|
|
219
272
|
) -> list[str]:
|
|
220
273
|
args: list[str] = ["rsync"]
|
|
221
274
|
if archive:
|
|
@@ -244,7 +297,15 @@ def rsync_cmd(
|
|
|
244
297
|
args.extend(["--rsh", join(rsh_args)])
|
|
245
298
|
if sudo:
|
|
246
299
|
args.extend(["--rsync-path", join(sudo_cmd("rsync"))])
|
|
247
|
-
|
|
300
|
+
dest_use = maybe_parent(dest, parent=parent)
|
|
301
|
+
return [
|
|
302
|
+
*args,
|
|
303
|
+
*map(str, always_iterable(src_or_srcs)),
|
|
304
|
+
f"{user}@{hostname}:{dest_use}",
|
|
305
|
+
]
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
##
|
|
248
309
|
|
|
249
310
|
|
|
250
311
|
@overload
|
|
@@ -502,10 +563,16 @@ def _run_write_to_streams(text: str, /, *outputs: IO[str]) -> None:
|
|
|
502
563
|
_ = output.write(text)
|
|
503
564
|
|
|
504
565
|
|
|
566
|
+
##
|
|
567
|
+
|
|
568
|
+
|
|
505
569
|
def set_hostname_cmd(hostname: str, /) -> list[str]:
|
|
506
570
|
return ["hostnamectl", "set-hostname", hostname]
|
|
507
571
|
|
|
508
572
|
|
|
573
|
+
##
|
|
574
|
+
|
|
575
|
+
|
|
509
576
|
@overload
|
|
510
577
|
def ssh(
|
|
511
578
|
user: str,
|
|
@@ -641,6 +708,9 @@ def ssh(
|
|
|
641
708
|
)
|
|
642
709
|
|
|
643
710
|
|
|
711
|
+
##
|
|
712
|
+
|
|
713
|
+
|
|
644
714
|
def ssh_cmd(
|
|
645
715
|
user: str,
|
|
646
716
|
hostname: str,
|
|
@@ -658,6 +728,9 @@ def ssh_cmd(
|
|
|
658
728
|
return [*args, f"{user}@{hostname}", *cmd_and_cmds_or_args]
|
|
659
729
|
|
|
660
730
|
|
|
731
|
+
##
|
|
732
|
+
|
|
733
|
+
|
|
661
734
|
def ssh_opts_cmd(
|
|
662
735
|
*,
|
|
663
736
|
batch_mode: bool = True,
|
|
@@ -673,26 +746,44 @@ def ssh_opts_cmd(
|
|
|
673
746
|
return [*args, "-T"]
|
|
674
747
|
|
|
675
748
|
|
|
749
|
+
##
|
|
750
|
+
|
|
751
|
+
|
|
676
752
|
def ssh_keygen_cmd(hostname: str, /) -> list[str]:
|
|
677
753
|
return ["ssh-keygen", "-f", "~/.ssh/known_hosts", "-R", hostname]
|
|
678
754
|
|
|
679
755
|
|
|
756
|
+
##
|
|
757
|
+
|
|
758
|
+
|
|
680
759
|
def sudo_cmd(cmd: str, /, *args: str) -> list[str]:
|
|
681
760
|
return ["sudo", cmd, *args]
|
|
682
761
|
|
|
683
762
|
|
|
763
|
+
##
|
|
764
|
+
|
|
765
|
+
|
|
684
766
|
def sudo_nopasswd_cmd(user: str, /) -> str:
|
|
685
767
|
return f"{user} ALL=(ALL) NOPASSWD: ALL"
|
|
686
768
|
|
|
687
769
|
|
|
770
|
+
##
|
|
771
|
+
|
|
772
|
+
|
|
688
773
|
def symlink_cmd(src: PathLike, dest: PathLike, /) -> list[str]:
|
|
689
774
|
return ["ln", "-s", str(src), str(dest)]
|
|
690
775
|
|
|
691
776
|
|
|
777
|
+
##
|
|
778
|
+
|
|
779
|
+
|
|
692
780
|
def touch_cmd(path: PathLike, /) -> list[str]:
|
|
693
781
|
return ["touch", str(path)]
|
|
694
782
|
|
|
695
783
|
|
|
784
|
+
##
|
|
785
|
+
|
|
786
|
+
|
|
696
787
|
def uv_run_cmd(module: str, /, *args: str) -> list[str]:
|
|
697
788
|
return [
|
|
698
789
|
"uv",
|
|
@@ -708,6 +799,9 @@ def uv_run_cmd(module: str, /, *args: str) -> list[str]:
|
|
|
708
799
|
]
|
|
709
800
|
|
|
710
801
|
|
|
802
|
+
##
|
|
803
|
+
|
|
804
|
+
|
|
711
805
|
@contextmanager
|
|
712
806
|
def yield_ssh_temp_dir(
|
|
713
807
|
user: str,
|
|
@@ -748,6 +842,7 @@ __all__ = [
|
|
|
748
842
|
"expand_path",
|
|
749
843
|
"git_clone_cmd",
|
|
750
844
|
"git_hard_reset_cmd",
|
|
845
|
+
"maybe_parent",
|
|
751
846
|
"maybe_sudo_cmd",
|
|
752
847
|
"mkdir",
|
|
753
848
|
"mkdir_cmd",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_plugins/pytest_randomly.py
RENAMED
|
File without changes
|
{dycw_utilities-0.174.7 → dycw_utilities-0.174.8}/src/utilities/pytest_plugins/pytest_regressions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|