dycw-utilities 0.175.18__py3-none-any.whl → 0.175.20__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.
- {dycw_utilities-0.175.18.dist-info → dycw_utilities-0.175.20.dist-info}/METADATA +1 -1
- {dycw_utilities-0.175.18.dist-info → dycw_utilities-0.175.20.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/subprocess.py +76 -5
- {dycw_utilities-0.175.18.dist-info → dycw_utilities-0.175.20.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.175.18.dist-info → dycw_utilities-0.175.20.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
utilities/__init__.py,sha256=
|
|
1
|
+
utilities/__init__.py,sha256=0iNHFjfunbBFef4oYY7Vp7CHutwqqxx7liLuA-yDLJQ,61
|
|
2
2
|
utilities/altair.py,sha256=TLfRFbG9HwG7SLXoJ-v0r-t49ZaGgTQZD82cpjVi4vs,9085
|
|
3
3
|
utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
|
|
4
4
|
utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
|
|
@@ -80,7 +80,7 @@ utilities/sqlalchemy.py,sha256=HQYpd7LFxdTF5WYVWYtCJeEBI71EJm7ytvCGyAH9B-U,37163
|
|
|
80
80
|
utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
|
|
81
81
|
utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
|
|
82
82
|
utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
|
|
83
|
-
utilities/subprocess.py,sha256=
|
|
83
|
+
utilities/subprocess.py,sha256=1nM6Fb-aD4xO673bqWt79rReS2gAhUGmxiA00ZPHYcU,45578
|
|
84
84
|
utilities/tempfile.py,sha256=a3_M1QyxGZql_VcGkBOQBeWbbkItjgkfIpVyzU1UAic,3843
|
|
85
85
|
utilities/testbook.py,sha256=j1KmaVbrX9VrbeMgtPh5gk55myAsn3dyRUn7jGbPbRk,1294
|
|
86
86
|
utilities/text.py,sha256=7SvwcSR2l_5cOrm1samGnR4C-ZI6qyFLHLzSpO1zeHQ,13958
|
|
@@ -97,7 +97,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
|
97
97
|
utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
|
|
98
98
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
|
99
99
|
utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
|
|
100
|
-
dycw_utilities-0.175.
|
|
101
|
-
dycw_utilities-0.175.
|
|
102
|
-
dycw_utilities-0.175.
|
|
103
|
-
dycw_utilities-0.175.
|
|
100
|
+
dycw_utilities-0.175.20.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
|
|
101
|
+
dycw_utilities-0.175.20.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
|
|
102
|
+
dycw_utilities-0.175.20.dist-info/METADATA,sha256=vhmsFDQysT0e5L5jasWdhZPF6zNePjTpq0iLx5LQ_uw,1443
|
|
103
|
+
dycw_utilities-0.175.20.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/subprocess.py
CHANGED
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
from contextlib import contextmanager
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from io import StringIO
|
|
8
|
+
from itertools import repeat
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from re import search
|
|
10
11
|
from shlex import join
|
|
@@ -54,11 +55,36 @@ UPDATE_CA_CERTIFICATES: str = "update-ca-certificates"
|
|
|
54
55
|
##
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
def append_text(
|
|
59
|
+
path: PathLike,
|
|
60
|
+
text: str,
|
|
61
|
+
/,
|
|
62
|
+
*,
|
|
63
|
+
sudo: bool = False,
|
|
64
|
+
skip_if_present: bool = False,
|
|
65
|
+
flags: int = 0,
|
|
66
|
+
blank_lines: int = 1,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Append text to a file."""
|
|
69
|
+
try:
|
|
70
|
+
existing = cat(path, sudo=sudo)
|
|
71
|
+
except (CalledProcessError, FileNotFoundError):
|
|
72
|
+
tee(path, text, sudo=sudo, append=True)
|
|
73
|
+
return
|
|
74
|
+
if skip_if_present and (search(text, existing, flags=flags) is not None):
|
|
75
|
+
return
|
|
76
|
+
full = "".join([*repeat("\n", times=blank_lines), text])
|
|
77
|
+
tee(path, full, sudo=sudo, append=True)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
|
|
82
|
+
|
|
57
83
|
def apt_install(package: str, /, *, update: bool = False, sudo: bool = False) -> None:
|
|
58
84
|
"""Install a package."""
|
|
59
85
|
if update: # pragma: no cover
|
|
60
86
|
run(*maybe_sudo_cmd(*APT_UPDATE, sudo=sudo))
|
|
61
|
-
run(*maybe_sudo_cmd(*apt_install_cmd(package), sudo=sudo))
|
|
87
|
+
run(*maybe_sudo_cmd(*apt_install_cmd(package), sudo=sudo)) # pragma: no cover
|
|
62
88
|
|
|
63
89
|
|
|
64
90
|
def apt_install_cmd(package: str, /) -> list[str]:
|
|
@@ -69,9 +95,17 @@ def apt_install_cmd(package: str, /) -> list[str]:
|
|
|
69
95
|
##
|
|
70
96
|
|
|
71
97
|
|
|
72
|
-
def
|
|
98
|
+
def cat(path: PathLike, /, *paths: PathLike, sudo: bool = False) -> str:
|
|
99
|
+
"""Concatenate and print files."""
|
|
100
|
+
if sudo: # pragma: no cover
|
|
101
|
+
return run(*sudo_cmd(*cat_cmd(path, *paths)), return_=True)
|
|
102
|
+
all_paths = list(map(Path, [path, *paths]))
|
|
103
|
+
return "\n".join(p.read_text() for p in all_paths)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def cat_cmd(path: PathLike, /, *paths: PathLike) -> list[str]:
|
|
73
107
|
"""Command to use 'cat' to concatenate and print files."""
|
|
74
|
-
return ["cat", str(path)]
|
|
108
|
+
return ["cat", str(path), *map(str, paths)]
|
|
75
109
|
|
|
76
110
|
|
|
77
111
|
##
|
|
@@ -170,6 +204,24 @@ def chpasswd(user_name: str, password: str, /, *, sudo: bool = False) -> None:
|
|
|
170
204
|
##
|
|
171
205
|
|
|
172
206
|
|
|
207
|
+
def copy_text(
|
|
208
|
+
src: PathLike,
|
|
209
|
+
dest: PathLike,
|
|
210
|
+
/,
|
|
211
|
+
*,
|
|
212
|
+
sudo: bool = False,
|
|
213
|
+
substitutions: StrMapping | None = None,
|
|
214
|
+
) -> None:
|
|
215
|
+
"""Copy the text contents of a file."""
|
|
216
|
+
text = cat(src, sudo=sudo)
|
|
217
|
+
if substitutions is not None:
|
|
218
|
+
text = Template(text).substitute(**substitutions)
|
|
219
|
+
tee(dest, text, sudo=sudo)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
##
|
|
223
|
+
|
|
224
|
+
|
|
173
225
|
def cp(
|
|
174
226
|
src: PathLike,
|
|
175
227
|
dest: PathLike,
|
|
@@ -356,6 +408,20 @@ def mv_cmd(src: PathLike, dest: PathLike, /) -> list[str]:
|
|
|
356
408
|
##
|
|
357
409
|
|
|
358
410
|
|
|
411
|
+
def replace_text(
|
|
412
|
+
path: PathLike, /, *replacements: tuple[str, str], sudo: bool = False
|
|
413
|
+
) -> None:
|
|
414
|
+
"""Replace the text in a file."""
|
|
415
|
+
path = Path(path)
|
|
416
|
+
text = cat(path, sudo=sudo)
|
|
417
|
+
for old, new in replacements:
|
|
418
|
+
text = text.replace(old, new)
|
|
419
|
+
tee(path, text, sudo=sudo)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
##
|
|
423
|
+
|
|
424
|
+
|
|
359
425
|
def ripgrep(*args: str, path: PathLike = PWD) -> str | None:
|
|
360
426
|
"""Search for lines."""
|
|
361
427
|
try: # skipif-ci
|
|
@@ -379,7 +445,8 @@ def rm(path: PathLike, /, *paths: PathLike, sudo: bool = False) -> None:
|
|
|
379
445
|
if sudo: # pragma: no cover
|
|
380
446
|
run(*sudo_cmd(*rm_cmd(path, *paths)))
|
|
381
447
|
else:
|
|
382
|
-
|
|
448
|
+
all_paths = list(map(Path, [path, *paths]))
|
|
449
|
+
for p in all_paths:
|
|
383
450
|
if p.is_file():
|
|
384
451
|
p.unlink(missing_ok=True)
|
|
385
452
|
elif p.is_dir():
|
|
@@ -1260,7 +1327,7 @@ def symlink_cmd(target: PathLike, link: PathLike, /) -> list[str]:
|
|
|
1260
1327
|
def tee(
|
|
1261
1328
|
path: PathLike, text: str, /, *, sudo: bool = False, append: bool = False
|
|
1262
1329
|
) -> None:
|
|
1263
|
-
"""
|
|
1330
|
+
"""Duplicate standard input."""
|
|
1264
1331
|
mkdir(path, sudo=sudo, parent=True)
|
|
1265
1332
|
if sudo: # pragma: no cover
|
|
1266
1333
|
run(*sudo_cmd(*tee_cmd(path, append=append)), input=text)
|
|
@@ -1516,14 +1583,17 @@ __all__ = [
|
|
|
1516
1583
|
"RsyncCmdError",
|
|
1517
1584
|
"RsyncCmdNoSourcesError",
|
|
1518
1585
|
"RsyncCmdSourcesNotFoundError",
|
|
1586
|
+
"append_text",
|
|
1519
1587
|
"apt_install",
|
|
1520
1588
|
"apt_install_cmd",
|
|
1589
|
+
"cat",
|
|
1521
1590
|
"cd_cmd",
|
|
1522
1591
|
"chmod",
|
|
1523
1592
|
"chmod_cmd",
|
|
1524
1593
|
"chown",
|
|
1525
1594
|
"chown_cmd",
|
|
1526
1595
|
"chpasswd",
|
|
1596
|
+
"copy_text",
|
|
1527
1597
|
"cp",
|
|
1528
1598
|
"cp_cmd",
|
|
1529
1599
|
"echo_cmd",
|
|
@@ -1540,6 +1610,7 @@ __all__ = [
|
|
|
1540
1610
|
"mkdir_cmd",
|
|
1541
1611
|
"mv",
|
|
1542
1612
|
"mv_cmd",
|
|
1613
|
+
"replace_text",
|
|
1543
1614
|
"ripgrep",
|
|
1544
1615
|
"ripgrep_cmd",
|
|
1545
1616
|
"rm",
|
|
File without changes
|
|
File without changes
|