pysfi 0.1.13__py3-none-any.whl → 0.1.15__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.
- {pysfi-0.1.13.dist-info → pysfi-0.1.15.dist-info}/METADATA +1 -1
- {pysfi-0.1.13.dist-info → pysfi-0.1.15.dist-info}/RECORD +35 -35
- {pysfi-0.1.13.dist-info → pysfi-0.1.15.dist-info}/entry_points.txt +2 -0
- sfi/__init__.py +20 -5
- sfi/alarmclock/__init__.py +3 -3
- sfi/bumpversion/__init__.py +5 -5
- sfi/bumpversion/bumpversion.py +64 -15
- sfi/cleanbuild/__init__.py +3 -3
- sfi/cleanbuild/cleanbuild.py +5 -1
- sfi/cli.py +13 -2
- sfi/condasetup/__init__.py +1 -1
- sfi/condasetup/condasetup.py +91 -76
- sfi/docdiff/__init__.py +1 -1
- sfi/docdiff/docdiff.py +3 -2
- sfi/docscan/__init__.py +3 -3
- sfi/docscan/docscan.py +78 -23
- sfi/docscan/docscan_gui.py +5 -5
- sfi/filedate/filedate.py +12 -5
- sfi/img2pdf/img2pdf.py +5 -5
- sfi/llmquantize/llmquantize.py +44 -33
- sfi/llmserver/__init__.py +1 -1
- sfi/makepython/makepython.py +880 -319
- sfi/pdfcrypt/__init__.py +30 -0
- sfi/pdfcrypt/pdfcrypt.py +435 -0
- sfi/pdfsplit/pdfsplit.py +45 -12
- sfi/pyarchive/__init__.py +1 -1
- sfi/pyarchive/pyarchive.py +1 -1
- sfi/pyembedinstall/pyembedinstall.py +1 -1
- sfi/pylibpack/pylibpack.py +5 -13
- sfi/pyloadergen/pyloadergen.py +6 -3
- sfi/pypack/pypack.py +131 -105
- sfi/pyprojectparse/pyprojectparse.py +19 -44
- sfi/pysourcepack/__init__.py +1 -1
- sfi/pysourcepack/pysourcepack.py +11 -14
- sfi/workflowengine/__init__.py +0 -0
- sfi/workflowengine/workflowengine.py +0 -547
- {pysfi-0.1.13.dist-info → pysfi-0.1.15.dist-info}/WHEEL +0 -0
|
@@ -1,43 +1,45 @@
|
|
|
1
|
-
sfi/__init__.py,sha256=
|
|
2
|
-
sfi/cli.py,sha256=
|
|
3
|
-
sfi/alarmclock/__init__.py,sha256=
|
|
1
|
+
sfi/__init__.py,sha256=TVJQhNdT9_xTAmwbMdf5rw-JogSq0EdM2iR-igNIHLk,685
|
|
2
|
+
sfi/cli.py,sha256=o-sFO6I3X3DMO2I_Gzc9LziWBdm2ruHXpjbraXGzZi0,933
|
|
3
|
+
sfi/alarmclock/__init__.py,sha256=AUnUxITgFPYgSjn9ug2DEejrz5HDP56zZKYu-6JW1vY,72
|
|
4
4
|
sfi/alarmclock/alarmclock.py,sha256=ixVkbg548smUivRsqyI3YSZ81BWIrKawnuezAp3BzyE,11635
|
|
5
|
-
sfi/bumpversion/__init__.py,sha256=
|
|
6
|
-
sfi/bumpversion/bumpversion.py,sha256=
|
|
7
|
-
sfi/cleanbuild/__init__.py,sha256=
|
|
8
|
-
sfi/cleanbuild/cleanbuild.py,sha256=
|
|
9
|
-
sfi/condasetup/__init__.py,sha256=
|
|
10
|
-
sfi/condasetup/condasetup.py,sha256=
|
|
11
|
-
sfi/docdiff/__init__.py,sha256=
|
|
12
|
-
sfi/docdiff/docdiff.py,sha256=
|
|
13
|
-
sfi/docscan/__init__.py,sha256=
|
|
14
|
-
sfi/docscan/docscan.py,sha256=
|
|
15
|
-
sfi/docscan/docscan_gui.py,sha256=
|
|
5
|
+
sfi/bumpversion/__init__.py,sha256=yAaQaGUKnwPERhTaS4XXANQc9AT31nseY2dKomRPRmU,122
|
|
6
|
+
sfi/bumpversion/bumpversion.py,sha256=Uxj0S8ZGmIRhfCx2ziWkVe5gHv74r68UPkiYzZcAwxo,21288
|
|
7
|
+
sfi/cleanbuild/__init__.py,sha256=_bXrBcQkHQTE2484-UMWAWz8kq-2Yjn9hleLcjF-pJg,98
|
|
8
|
+
sfi/cleanbuild/cleanbuild.py,sha256=Ilk4zBE48y6tUC3C5qp1pXdQ6CF0NZlra4ZbdiU5s2k,5270
|
|
9
|
+
sfi/condasetup/__init__.py,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
10
|
+
sfi/condasetup/condasetup.py,sha256=tuRzRi4NKmIfqN4Gq5w-VmY7BnleizPhAbYta8AzH4c,4976
|
|
11
|
+
sfi/docdiff/__init__.py,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
12
|
+
sfi/docdiff/docdiff.py,sha256=YR8e-gkbvjH0Bjt5fVVW0-8b7lbinQs6TRo4B5XgEjE,7783
|
|
13
|
+
sfi/docscan/__init__.py,sha256=v7sLqtKfRfuxZ4bAKVvR5FBc_SX44W9MOBL_vmmAuss,121
|
|
14
|
+
sfi/docscan/docscan.py,sha256=hXSOrfMikyg-Zsi_mpZvn31ea1J0un90ftwpRoXxNdA,42765
|
|
15
|
+
sfi/docscan/docscan_gui.py,sha256=KoXVHOQjUwtkxh5tI4V6mLBMl9PAP3Hp7zydJ_lppoQ,52345
|
|
16
16
|
sfi/docscan/lang/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
sfi/docscan/lang/eng.py,sha256=GcOcT9FLcPZRdJ-MbLRYyf6vDweZTQBu_zUnEFzRY84,8529
|
|
18
18
|
sfi/docscan/lang/zhcn.py,sha256=1SZwQjZF3oi9FsnzuZB-9v7P64sGm5oNmVjuL-rhcEQ,8885
|
|
19
19
|
sfi/filedate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
sfi/filedate/filedate.py,sha256=
|
|
20
|
+
sfi/filedate/filedate.py,sha256=eOR6LCwYosO6qyThPNeSCNImiU19UTQaqNWTkFKHAfs,6227
|
|
21
21
|
sfi/gittool/__init__.py,sha256=Xqxw7UUX-TKkWOCB1QHq8AdIKTkU7x87Xr-E0yVmObA,24
|
|
22
22
|
sfi/gittool/gittool.py,sha256=BBE6gm9qP1fAWLqKprmsf7bOFgDvBvia8_bMaXc7dR4,11960
|
|
23
23
|
sfi/img2pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
-
sfi/img2pdf/img2pdf.py,sha256=
|
|
24
|
+
sfi/img2pdf/img2pdf.py,sha256=Rx8N9ZG2MrbzfiGAaZGEFlNGuOpP_gwNY5MmOSGTv3w,15198
|
|
25
25
|
sfi/llmclient/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
26
|
sfi/llmclient/llmclient.py,sha256=zvaT-HEiL3CM3uEpvzuseLPEqFQe6RO4_fhnA2djHo0,22681
|
|
27
27
|
sfi/llmquantize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
sfi/llmquantize/llmquantize.py,sha256=
|
|
29
|
-
sfi/llmserver/__init__.py,sha256=
|
|
28
|
+
sfi/llmquantize/llmquantize.py,sha256=crbZ4qnq6BAAkba_dBVYVhI9hhd9yBQ7XlNsWIrAes8,18888
|
|
29
|
+
sfi/llmserver/__init__.py,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
30
30
|
sfi/llmserver/llmserver.py,sha256=Fm4Go7wif4xMGomMFDsyJnYMafXsWemGkr-VfaeYa6w,13530
|
|
31
31
|
sfi/makepython/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
sfi/makepython/makepython.py,sha256=
|
|
32
|
+
sfi/makepython/makepython.py,sha256=GrzQTJyyB2PXugJK3yLxP1V5I_bSymW0qfkeqZvxRPA,43154
|
|
33
|
+
sfi/pdfcrypt/__init__.py,sha256=cKY_rosu4Qo0QvJF5d_vFgvMMcH14JH6uElOMRXo654,565
|
|
34
|
+
sfi/pdfcrypt/pdfcrypt.py,sha256=s7LMABQt4gW8UabuwdKdy_hgmSa8ZDePFrtab3tEkEA,13236
|
|
33
35
|
sfi/pdfsplit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
-
sfi/pdfsplit/pdfsplit.py,sha256=
|
|
35
|
-
sfi/pyarchive/__init__.py,sha256=
|
|
36
|
-
sfi/pyarchive/pyarchive.py,sha256=
|
|
36
|
+
sfi/pdfsplit/pdfsplit.py,sha256=LOz7PuLlLBiXlFTjJej9G0UvJ03GZ9H-Gghy8ErvJzE,6576
|
|
37
|
+
sfi/pyarchive/__init__.py,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
38
|
+
sfi/pyarchive/pyarchive.py,sha256=ne8FZh79_0ZtIWCG6Ddg9uUF6JxTvFsvfilOLl4wYmI,38280
|
|
37
39
|
sfi/pyembedinstall/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
sfi/pyembedinstall/pyembedinstall.py,sha256=
|
|
40
|
+
sfi/pyembedinstall/pyembedinstall.py,sha256=1XOTR6Mg2YtP_-t9jRjiNGSSTw5TklDO60XPc3I9TL0,24158
|
|
39
41
|
sfi/pylibpack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
-
sfi/pylibpack/pylibpack.py,sha256=
|
|
42
|
+
sfi/pylibpack/pylibpack.py,sha256=AJbMY4aHJq0YhyUXryBargNqCUTeSwaUuc3SiCcjcko,57685
|
|
41
43
|
sfi/pylibpack/rules/numpy.json,sha256=ee4gA5NBudFi3MaJA-QlBKQwiQAUb-eluF8HNVkl7Vk,384
|
|
42
44
|
sfi/pylibpack/rules/pymupdf.json,sha256=Hkzh8dvXKCzKx4aeHbu5E0qwgfbwQxZH2VLtQZzlMO4,153
|
|
43
45
|
sfi/pylibpack/rules/pyqt5.json,sha256=JKGnVSUMfXGR5XK1sbL1F6cAsEhl7hK12QkrulAB00M,374
|
|
@@ -45,13 +47,13 @@ sfi/pylibpack/rules/pyside2.json,sha256=uSSteT-3wDohWwQ36Z5mSOaSbxrR4565In4uZj_e
|
|
|
45
47
|
sfi/pylibpack/rules/scipy.json,sha256=vTSi3W5BGWcwMkaDnyD6Yg7ijZdicPEUMw4fnRTnNf4,468
|
|
46
48
|
sfi/pylibpack/rules/shiboken2.json,sha256=9Pl3eslvergyjlyHNknkyN0oZlcH3049WULe5WjsmKM,515
|
|
47
49
|
sfi/pyloadergen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
-
sfi/pyloadergen/pyloadergen.py,sha256=
|
|
50
|
+
sfi/pyloadergen/pyloadergen.py,sha256=NiQGk4I5LMNvEaMc9aasXKHGNSg127AcUR5hmDPm6sQ,45801
|
|
49
51
|
sfi/pypack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
-
sfi/pypack/pypack.py,sha256=
|
|
52
|
+
sfi/pypack/pypack.py,sha256=v2qdSGL4cANO28mbaJSGbThiyJG33djsTcVy9RlwDgc,23031
|
|
51
53
|
sfi/pyprojectparse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
-
sfi/pyprojectparse/pyprojectparse.py,sha256=
|
|
53
|
-
sfi/pysourcepack/__init__.py,sha256=
|
|
54
|
-
sfi/pysourcepack/pysourcepack.py,sha256=
|
|
54
|
+
sfi/pyprojectparse/pyprojectparse.py,sha256=XPY1E3mW6qkvuAlGBK8fpTfPQJYkWpQFcYZTZ4IlROk,29784
|
|
55
|
+
sfi/pysourcepack/__init__.py,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
56
|
+
sfi/pysourcepack/pysourcepack.py,sha256=HNhO0Ry3kAzZJ5-bXlxn81jrh_GdjKzWFOyz7SQhN1Q,12158
|
|
55
57
|
sfi/quizbase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
58
|
sfi/quizbase/quizbase.py,sha256=3tPUuYexZ9TVsNPPO_Itmr5OvyHSgY5OSUZwPoQt9zg,30605
|
|
57
59
|
sfi/quizbase/quizbase_gui.py,sha256=m_Lj3au1a8gEv5x7KOTjomiP1NpXHUgHSPE4lLv63hY,34733
|
|
@@ -62,9 +64,7 @@ sfi/taskkill/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
62
64
|
sfi/taskkill/taskkill.py,sha256=wM9g8sWJVTy4GxXe26rKdax2lIBI-uH9wP5wRenriH4,11606
|
|
63
65
|
sfi/which/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
66
|
sfi/which/which.py,sha256=2YbGgSiT1ySapKVV1ESoPf4P-JU8vvzmsZY39NiVr6k,2596
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
pysfi-0.1.
|
|
68
|
-
pysfi-0.1.
|
|
69
|
-
pysfi-0.1.13.dist-info/entry_points.txt,sha256=ju_Bwp3L8-5Bpcj0PSCCDL8vGsGb4ZYpjfzprSdFrfA,1215
|
|
70
|
-
pysfi-0.1.13.dist-info/RECORD,,
|
|
67
|
+
pysfi-0.1.15.dist-info/METADATA,sha256=LyUkSywzxLXVtmVvhzMuSKMxEo5EApdoyHk6q3eFcA0,4198
|
|
68
|
+
pysfi-0.1.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
69
|
+
pysfi-0.1.15.dist-info/entry_points.txt,sha256=j0zUSQnJ1YpYEKTK0oEICBjIyOAVZOd5Ss2_k0id530,1297
|
|
70
|
+
pysfi-0.1.15.dist-info/RECORD,,
|
|
@@ -12,7 +12,9 @@ img2pdf = sfi.img2pdf.img2pdf:main
|
|
|
12
12
|
llmcli = sfi.llmclient.llmclient:main
|
|
13
13
|
llmqnt = sfi.llmquantize.llmquantize:main
|
|
14
14
|
llmsvr = sfi.llmserver.llmserver:main
|
|
15
|
+
makepython = sfi.makepython.makepython:main
|
|
15
16
|
mkp = sfi.makepython.makepython:main
|
|
17
|
+
pdfcrypt = sfi.pdfcrypt.pdfcrypt:main
|
|
16
18
|
pdfsplit = sfi.pdfsplit.pdfsplit:main
|
|
17
19
|
pyarchive = sfi.pyarchive.pyarchive:main
|
|
18
20
|
pyembedinstall = sfi.pyembedinstall.pyembedinstall:main
|
sfi/__init__.py
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
"""Single File commands for Interactive python.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"""Single File commands for Interactive python.
|
|
2
|
+
|
|
3
|
+
pysfi (Python Single File Interactive) is a collection of Python utility
|
|
4
|
+
tools designed to streamline development workflows and enhance productivity.
|
|
5
|
+
|
|
6
|
+
This package provides:
|
|
7
|
+
- Document processing utilities (docscan, docdiff, pdfsplit, img2pdf)
|
|
8
|
+
- Development tools (makepython, bumpversion, cleanbuild)
|
|
9
|
+
- System management utilities (filedate, taskkill, gittool)
|
|
10
|
+
- AI/LLM tools (llmclient, llmserver, llmquantize)
|
|
11
|
+
- And many more specialized utilities
|
|
12
|
+
|
|
13
|
+
Each module can be used independently as a command-line tool
|
|
14
|
+
or imported as a Python library.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
__version__ = "0.1.15"
|
|
20
|
+
__all__ = ["__version__"]
|
sfi/alarmclock/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""Alarm clock module for pysfi."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
1
|
+
"""Alarm clock module for pysfi."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
sfi/bumpversion/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""Bumpversion - Automated version number management tool."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
__version__ = "0.1.
|
|
1
|
+
"""Bumpversion - Automated version number management tool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__version__ = "0.1.15"
|
sfi/bumpversion/bumpversion.py
CHANGED
|
@@ -11,6 +11,7 @@ import sys
|
|
|
11
11
|
from dataclasses import dataclass
|
|
12
12
|
from enum import Enum
|
|
13
13
|
from pathlib import Path
|
|
14
|
+
from re import Pattern
|
|
14
15
|
from typing import Final
|
|
15
16
|
|
|
16
17
|
try:
|
|
@@ -21,7 +22,8 @@ except ImportError:
|
|
|
21
22
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
22
23
|
logger = logging.getLogger(__name__)
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
# Semantic versioning regex pattern
|
|
26
|
+
VERSION_PATTERN: Final[Pattern[str]] = re.compile(
|
|
25
27
|
r"(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"
|
|
26
28
|
)
|
|
27
29
|
|
|
@@ -69,7 +71,12 @@ class Version:
|
|
|
69
71
|
buildmetadata=match.group("buildmetadata"),
|
|
70
72
|
)
|
|
71
73
|
|
|
72
|
-
def bump(
|
|
74
|
+
def bump(
|
|
75
|
+
self,
|
|
76
|
+
part: VersionPart,
|
|
77
|
+
reset_prerelease: bool = True,
|
|
78
|
+
prerelease: str | None = None,
|
|
79
|
+
) -> Version:
|
|
73
80
|
"""Return a new version with specified part bumped."""
|
|
74
81
|
# Determine the new prerelease value
|
|
75
82
|
new_prerelease = None
|
|
@@ -121,7 +128,9 @@ class FileParser:
|
|
|
121
128
|
"""Parser for different file formats to extract and update version numbers."""
|
|
122
129
|
|
|
123
130
|
@staticmethod
|
|
124
|
-
def _write_with_original_line_ending(
|
|
131
|
+
def _write_with_original_line_ending(
|
|
132
|
+
file_path: Path, content: str, original_content: str
|
|
133
|
+
) -> None:
|
|
125
134
|
"""Write content to file while preserving original line ending style.
|
|
126
135
|
|
|
127
136
|
Args:
|
|
@@ -167,7 +176,9 @@ class FileParser:
|
|
|
167
176
|
new_content = re.sub(pattern, new_version_str, content)
|
|
168
177
|
|
|
169
178
|
# Write back preserving original line endings
|
|
170
|
-
FileParser._write_with_original_line_ending(
|
|
179
|
+
FileParser._write_with_original_line_ending(
|
|
180
|
+
file_path, new_content, original_bytes.decode("utf-8")
|
|
181
|
+
)
|
|
171
182
|
|
|
172
183
|
@staticmethod
|
|
173
184
|
def parse_init_py(file_path: Path) -> tuple[Version, list[str]]:
|
|
@@ -285,7 +296,9 @@ class BumpversionManager:
|
|
|
285
296
|
if projects_file.exists():
|
|
286
297
|
with projects_file.open("r", encoding="utf-8") as f:
|
|
287
298
|
projects_data = json.load(f)
|
|
288
|
-
self.subproject_paths = {
|
|
299
|
+
self.subproject_paths = {
|
|
300
|
+
self.root_path / p for p in projects_data.get("subprojects", [])
|
|
301
|
+
}
|
|
289
302
|
except Exception:
|
|
290
303
|
pass
|
|
291
304
|
|
|
@@ -313,10 +326,17 @@ class BumpversionManager:
|
|
|
313
326
|
# Filter out unwanted directories
|
|
314
327
|
excluded_dirs = {"__pycache__", ".venv", "venv", "env", ".git", "dist", "build"}
|
|
315
328
|
init_files = [
|
|
316
|
-
f
|
|
329
|
+
f
|
|
330
|
+
for f in init_files
|
|
331
|
+
if not any(part in excluded_dirs for part in f.parts)
|
|
332
|
+
and "tests" not in f.parts
|
|
317
333
|
]
|
|
318
334
|
# Exclude files inside subprojects defined in projects.json
|
|
319
|
-
init_files = [
|
|
335
|
+
init_files = [
|
|
336
|
+
f
|
|
337
|
+
for f in init_files
|
|
338
|
+
if not any(str(f).startswith(str(sp)) for sp in self.subproject_paths)
|
|
339
|
+
]
|
|
320
340
|
detected_files.extend(init_files)
|
|
321
341
|
for f in init_files:
|
|
322
342
|
logger.info(f"Found: {f}")
|
|
@@ -442,7 +462,9 @@ class BumpversionManager:
|
|
|
442
462
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
443
463
|
return False
|
|
444
464
|
|
|
445
|
-
def _git_commit(
|
|
465
|
+
def _git_commit(
|
|
466
|
+
self, version: Version, message: str | None, files: list[Path]
|
|
467
|
+
) -> None:
|
|
446
468
|
"""Commit version changes to git."""
|
|
447
469
|
commit_message = message or f"chore: bump version to {version}"
|
|
448
470
|
|
|
@@ -458,7 +480,9 @@ class BumpversionManager:
|
|
|
458
480
|
tag_name = f"v{version}"
|
|
459
481
|
|
|
460
482
|
try:
|
|
461
|
-
subprocess.run(
|
|
483
|
+
subprocess.run(
|
|
484
|
+
["git", "tag", "-a", tag_name, "-m", f"Version {version}"], check=True
|
|
485
|
+
)
|
|
462
486
|
logger.info(f"Git tag created: {tag_name}")
|
|
463
487
|
except subprocess.CalledProcessError as e:
|
|
464
488
|
logger.error(f"Git tag failed: {e}")
|
|
@@ -466,14 +490,39 @@ class BumpversionManager:
|
|
|
466
490
|
|
|
467
491
|
def main() -> None:
|
|
468
492
|
"""Main entry point for bumpversion command."""
|
|
469
|
-
parser = argparse.ArgumentParser(
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
parser.add_argument(
|
|
473
|
-
|
|
493
|
+
parser = argparse.ArgumentParser(
|
|
494
|
+
prog="bumpversion", description="Automated version number management tool"
|
|
495
|
+
)
|
|
496
|
+
parser.add_argument(
|
|
497
|
+
"part",
|
|
498
|
+
type=str,
|
|
499
|
+
choices=["major", "minor", "patch"],
|
|
500
|
+
help="Version part to bump",
|
|
501
|
+
)
|
|
502
|
+
parser.add_argument(
|
|
503
|
+
"--files",
|
|
504
|
+
"-f",
|
|
505
|
+
type=str,
|
|
506
|
+
nargs="*",
|
|
507
|
+
help="Specific files to update (default: auto-detect)",
|
|
508
|
+
)
|
|
509
|
+
parser.add_argument(
|
|
510
|
+
"--prerelease",
|
|
511
|
+
"-p",
|
|
512
|
+
type=str,
|
|
513
|
+
help="Set prerelease tag (e.g., alpha, beta, rc1)",
|
|
514
|
+
)
|
|
515
|
+
parser.add_argument(
|
|
516
|
+
"--commit", "-c", action="store_true", help="Commit changes to git"
|
|
517
|
+
)
|
|
474
518
|
parser.add_argument("--tag", "-t", action="store_true", help="Create git tag")
|
|
475
519
|
parser.add_argument("--message", "-m", type=str, help="Custom commit message")
|
|
476
|
-
parser.add_argument(
|
|
520
|
+
parser.add_argument(
|
|
521
|
+
"--dry-run",
|
|
522
|
+
"-n",
|
|
523
|
+
action="store_true",
|
|
524
|
+
help="Show what would be done without making changes",
|
|
525
|
+
)
|
|
477
526
|
parser.add_argument("--debug", "-d", action="store_true", help="Enable debug mode")
|
|
478
527
|
args = parser.parse_args()
|
|
479
528
|
|
sfi/cleanbuild/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""Cleanbuild - Clean build artifacts and temporary files."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
1
|
+
"""Cleanbuild - Clean build artifacts and temporary files."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
sfi/cleanbuild/cleanbuild.py
CHANGED
|
@@ -13,6 +13,10 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
13
13
|
from dataclasses import dataclass, field
|
|
14
14
|
from functools import cached_property
|
|
15
15
|
from pathlib import Path
|
|
16
|
+
from typing import Final
|
|
17
|
+
|
|
18
|
+
# Folders to clean
|
|
19
|
+
_BUILD_FOLDERS: Final[tuple[str, ...]] = ("build", "dist", ".venv", "node_modules")
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
|
|
@@ -20,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|
|
20
24
|
|
|
21
25
|
CWD = Path.cwd()
|
|
22
26
|
PROJECT_ROOT = Path(__file__).parent.parent.parent
|
|
23
|
-
|
|
27
|
+
|
|
24
28
|
|
|
25
29
|
@dataclass(frozen=True)
|
|
26
30
|
class SearchResult:
|
sfi/cli.py
CHANGED
|
@@ -2,15 +2,26 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
|
|
5
|
-
from sfi import __version__ as VERSION
|
|
5
|
+
from sfi import __version__ as VERSION
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def main() -> None:
|
|
9
9
|
"""Main entry point for the pysfi CLI tool.
|
|
10
10
|
|
|
11
11
|
Parses command line arguments and handles version printing.
|
|
12
|
+
|
|
13
|
+
This is the central entry point for all pysfi subcommands.
|
|
14
|
+
Currently supports:
|
|
15
|
+
- Version information display
|
|
16
|
+
|
|
17
|
+
Future enhancements will include routing to specific
|
|
18
|
+
module commands based on subcommands.
|
|
12
19
|
"""
|
|
13
|
-
parser = argparse.ArgumentParser(
|
|
20
|
+
parser = argparse.ArgumentParser(
|
|
21
|
+
prog="pysfi",
|
|
22
|
+
description="Python Single File Interactive - A collection of Python utility tools",
|
|
23
|
+
epilog="Use 'pysfi <command> --help' for more information on a specific command",
|
|
24
|
+
)
|
|
14
25
|
parser.add_argument(
|
|
15
26
|
"-v",
|
|
16
27
|
"--version",
|
sfi/condasetup/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|
sfi/condasetup/condasetup.py
CHANGED
|
@@ -3,92 +3,106 @@ from __future__ import annotations
|
|
|
3
3
|
import argparse
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
+
import subprocess
|
|
6
7
|
from pathlib import Path
|
|
8
|
+
from typing import Final
|
|
7
9
|
|
|
8
10
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
9
11
|
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
_CONDA_MIRROR_URLS: dict[str, frozenset[str]] = {
|
|
13
|
-
"tsinghua": frozenset(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"https://mirrors.aliyun.com/anaconda/pkgs/pro/",
|
|
61
|
-
"https://mirrors.aliyun.com/anaconda/pkgs/dev/",
|
|
62
|
-
"https://mirrors.aliyun.com/anaconda/cloud/conda-forge/",
|
|
63
|
-
"https://mirrors.aliyun.com/anaconda/cloud/bioconda/",
|
|
64
|
-
"https://mirrors.aliyun.com/anaconda/cloud/menpo/",
|
|
65
|
-
"https://mirrors.aliyun.com/anaconda/cloud/pytorch/",
|
|
66
|
-
]
|
|
67
|
-
),
|
|
12
|
+
|
|
13
|
+
# Conda mirror URLs
|
|
14
|
+
_CONDA_MIRROR_URLS: Final[dict[str, frozenset[str]]] = {
|
|
15
|
+
"tsinghua": frozenset([
|
|
16
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/",
|
|
17
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/",
|
|
18
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/",
|
|
19
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/",
|
|
20
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro/",
|
|
21
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/",
|
|
22
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/",
|
|
23
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/",
|
|
24
|
+
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/",
|
|
25
|
+
]),
|
|
26
|
+
"ustc": frozenset([
|
|
27
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/main/",
|
|
28
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/free/",
|
|
29
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/r/",
|
|
30
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/msys2/",
|
|
31
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/pro/",
|
|
32
|
+
"https://mirrors.ustc.edu.cn/anaconda/pkgs/dev/",
|
|
33
|
+
"https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/",
|
|
34
|
+
"https://mirrors.ustc.edu.cn/anaconda/cloud/bioconda/",
|
|
35
|
+
"https://mirrors.ustc.edu.cn/anaconda/cloud/menpo/",
|
|
36
|
+
"https://mirrors.ustc.edu.cn/anaconda/cloud/pytorch/",
|
|
37
|
+
]),
|
|
38
|
+
"bsfu": frozenset([
|
|
39
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/main/",
|
|
40
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/free/",
|
|
41
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/r/",
|
|
42
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/msys2/",
|
|
43
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/pro/",
|
|
44
|
+
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/dev/",
|
|
45
|
+
"https://mirrors.bsfu.edu.cn/anaconda/cloud/conda-forge/",
|
|
46
|
+
"https://mirrors.bsfu.edu.cn/anaconda/cloud/bioconda/",
|
|
47
|
+
"https://mirrors.bsfu.edu.cn/anaconda/cloud/menpo/",
|
|
48
|
+
"https://mirrors.bsfu.edu.cn/anaconda/cloud/pytorch/",
|
|
49
|
+
]),
|
|
50
|
+
"aliyun": frozenset([
|
|
51
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/main/",
|
|
52
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/free/",
|
|
53
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/r/",
|
|
54
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/msys2/",
|
|
55
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/pro/",
|
|
56
|
+
"https://mirrors.aliyun.com/anaconda/pkgs/dev/",
|
|
57
|
+
"https://mirrors.aliyun.com/anaconda/cloud/conda-forge/",
|
|
58
|
+
"https://mirrors.aliyun.com/anaconda/cloud/bioconda/",
|
|
59
|
+
"https://mirrors.aliyun.com/anaconda/cloud/menpo/",
|
|
60
|
+
"https://mirrors.aliyun.com/anaconda/cloud/pytorch/",
|
|
61
|
+
]),
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
|
|
71
65
|
def set_conda_mirror(mirror: str = "tsinghua") -> None:
|
|
72
|
-
"""Set the Conda mirror for the given channel.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
else:
|
|
79
|
-
logger.debug("No existing .condarc file found")
|
|
80
|
-
|
|
81
|
-
mirror_urls = _CONDA_MIRROR_URLS[mirror]
|
|
82
|
-
for url in mirror_urls:
|
|
83
|
-
logger.debug(f"Adding mirror: {url}")
|
|
84
|
-
os.system(f"conda config --add channels {url}")
|
|
85
|
-
os.system("conda config --set show_channel_urls yes")
|
|
86
|
-
logger.info("Conda mirror set successfully")
|
|
87
|
-
else:
|
|
66
|
+
"""Set the Conda mirror for the given channel.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
mirror: Mirror name (tsinghua, ustc, bsfu, or aliyun)
|
|
70
|
+
"""
|
|
71
|
+
if mirror not in _CONDA_MIRROR_URLS:
|
|
88
72
|
logger.error(f"Invalid mirror: {mirror}")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
old_config = Path.home() / ".condarc"
|
|
76
|
+
if old_config.exists():
|
|
77
|
+
logger.info("Found existing .condarc file, backing it up")
|
|
78
|
+
os.rename(old_config, Path.home() / ".condarc.bak")
|
|
79
|
+
else:
|
|
80
|
+
logger.debug("No existing .condarc file found")
|
|
81
|
+
|
|
82
|
+
mirror_urls = _CONDA_MIRROR_URLS[mirror]
|
|
83
|
+
for url in mirror_urls:
|
|
84
|
+
logger.debug(f"Adding mirror: {url}")
|
|
85
|
+
try:
|
|
86
|
+
subprocess.run(["conda", "config", "--add", "channels", url], check=True)
|
|
87
|
+
except subprocess.CalledProcessError as e:
|
|
88
|
+
logger.error(f"Failed to add mirror {url}: {e}")
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
subprocess.run(
|
|
93
|
+
["conda", "config", "--set", "show_channel_urls", "yes"], check=True
|
|
94
|
+
)
|
|
95
|
+
logger.info("Conda mirror set successfully")
|
|
96
|
+
except subprocess.CalledProcessError as e:
|
|
97
|
+
logger.error(f"Failed to set show_channel_urls: {e}")
|
|
98
|
+
|
|
89
99
|
|
|
100
|
+
def parse_args() -> argparse.Namespace:
|
|
101
|
+
"""Parse command line arguments.
|
|
90
102
|
|
|
91
|
-
|
|
103
|
+
Returns:
|
|
104
|
+
Parsed arguments
|
|
105
|
+
"""
|
|
92
106
|
parser = argparse.ArgumentParser(description="Setup Conda environment for SFI")
|
|
93
107
|
parser.add_argument(
|
|
94
108
|
"mirror",
|
|
@@ -103,7 +117,8 @@ def parse_args():
|
|
|
103
117
|
return parser.parse_args()
|
|
104
118
|
|
|
105
119
|
|
|
106
|
-
def main():
|
|
120
|
+
def main() -> None:
|
|
121
|
+
"""Main entry point for condasetup CLI."""
|
|
107
122
|
args = parse_args()
|
|
108
123
|
|
|
109
124
|
if args.debug:
|
sfi/docdiff/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|
sfi/docdiff/docdiff.py
CHANGED
|
@@ -10,9 +10,10 @@ import time
|
|
|
10
10
|
from dataclasses import dataclass
|
|
11
11
|
from functools import cached_property
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import Any
|
|
13
|
+
from typing import Any, Final
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# Configuration file path
|
|
16
|
+
CONFIG_FILE: Final[Path] = Path.home() / ".pysfi" / "docdiff.json"
|
|
16
17
|
|
|
17
18
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
18
19
|
logger = logging.getLogger(__name__)
|
sfi/docscan/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""Document scanner module for scanning and extracting content from various document formats."""
|
|
2
|
-
|
|
3
|
-
__version__ = "0.1.
|
|
1
|
+
"""Document scanner module for scanning and extracting content from various document formats."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.15"
|