effectual 0.3.4__py3-none-any.whl → 0.4.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- effectual/build.py +16 -13
- effectual/config.py +14 -3
- effectual/developer.py +7 -7
- effectual/fileHash.py +9 -7
- effectual/minifier.py +2 -2
- {effectual-0.3.4.dist-info → effectual-0.4.0.dist-info}/METADATA +1 -1
- effectual-0.4.0.dist-info/RECORD +12 -0
- effectual-0.3.4.dist-info/RECORD +0 -12
- {effectual-0.3.4.dist-info → effectual-0.4.0.dist-info}/WHEEL +0 -0
- {effectual-0.3.4.dist-info → effectual-0.4.0.dist-info}/entry_points.txt +0 -0
- {effectual-0.3.4.dist-info → effectual-0.4.0.dist-info}/licenses/LICENSE +0 -0
effectual/build.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
import importlib
|
1
2
|
import os
|
2
3
|
import shutil
|
3
4
|
import zipfile
|
4
5
|
from pathlib import Path
|
5
6
|
from time import perf_counter
|
7
|
+
from typing import Any
|
6
8
|
|
7
9
|
import rtoml
|
8
10
|
|
@@ -19,14 +21,14 @@ def bundleFiles(
|
|
19
21
|
compressionLevel: int,
|
20
22
|
minification: bool,
|
21
23
|
) -> None:
|
22
|
-
"""Bundles dependencies and scripts into a single .
|
24
|
+
"""Bundles dependencies and scripts into a single .pyz archive
|
23
25
|
|
24
26
|
Args:
|
25
27
|
sourceDirectory (Path): Source directory which must contain a __main__.py script
|
26
28
|
outputDirectory (Path): Output directory for the bundle
|
27
29
|
outputFileName (str): Name of the output bundle
|
28
30
|
compressionLevel (int): Compression level for the bundle from 0-9
|
29
|
-
minification (bool): If the
|
31
|
+
minification (bool): If the scripts should be minified
|
30
32
|
"""
|
31
33
|
outputDirectory.mkdir(parents=True, exist_ok=True)
|
32
34
|
outputPath: Path = outputDirectory / outputFileName
|
@@ -65,7 +67,7 @@ def bundleFiles(
|
|
65
67
|
|
66
68
|
def dependencies(minify: bool) -> None:
|
67
69
|
with open("./pyproject.toml", "r", encoding="utf-8") as file:
|
68
|
-
packages: list[str] = dict(rtoml.load(file)).get("project").get("dependencies")
|
70
|
+
packages: list[str] = dict(rtoml.load(file)).get("project").get("dependencies") # type: ignore
|
69
71
|
|
70
72
|
arguments: list[str] = ["--no-compile", "--quiet", "--no-binary=none", "--no-cache"]
|
71
73
|
|
@@ -81,18 +83,19 @@ def dependencies(minify: bool) -> None:
|
|
81
83
|
|
82
84
|
print(f"{tagColor('optimizing')} || {', '.join(packages)}")
|
83
85
|
|
84
|
-
|
86
|
+
multiprocessing = importlib.import_module("multiprocessing")
|
85
87
|
|
86
88
|
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
87
89
|
pool.map(optimizeDependencies, Path(pathToInstallTo).rglob("*"))
|
88
90
|
|
89
91
|
|
90
92
|
def optimizeDependencies(file: Path) -> None:
|
93
|
+
stringFile: str = str(file)
|
91
94
|
if (
|
92
95
|
file.suffix in (".pyc", ".pyd", ".exe", ".typed")
|
93
|
-
or "__pycache__" in
|
94
|
-
or ".dist-info" in
|
95
|
-
or ".lock" in
|
96
|
+
or "__pycache__" in stringFile
|
97
|
+
or ".dist-info" in stringFile
|
98
|
+
or ".lock" in stringFile
|
96
99
|
):
|
97
100
|
try:
|
98
101
|
file.unlink()
|
@@ -109,7 +112,7 @@ def main() -> None:
|
|
109
112
|
RuntimeError: In the event there is no source directory
|
110
113
|
"""
|
111
114
|
|
112
|
-
configData: dict = loadConfig("./pyproject.toml")
|
115
|
+
configData: dict[Any, Any] = loadConfig("./pyproject.toml")
|
113
116
|
|
114
117
|
sourceDirectory: Path = Path(configData.get("sourceDirectory", "src/"))
|
115
118
|
outputDirectory: Path = Path(configData.get("outputDirectory", "out/"))
|
@@ -126,18 +129,18 @@ def main() -> None:
|
|
126
129
|
)
|
127
130
|
|
128
131
|
uvHashPath: Path = Path("./.effectual_cache/pyprojectHash.toml")
|
129
|
-
currentHash: dict[str] = dict()
|
132
|
+
currentHash: dict[str, dict[str, str]] = dict()
|
130
133
|
|
131
134
|
startTime = perf_counter()
|
132
135
|
|
133
136
|
Path("./.effectual_cache/").mkdir(parents=True, exist_ok=True)
|
134
|
-
currentHash["hashes"]
|
135
|
-
currentHash["hashes"]["pyproject"] = getFilehash("./pyproject.toml")
|
136
|
-
currentHash["hashes"]["lock"] = getFilehash("./uv.lock")
|
137
|
+
currentHash["hashes"] = dict()
|
138
|
+
currentHash["hashes"]["pyproject"] = getFilehash(Path("./pyproject.toml"))
|
139
|
+
currentHash["hashes"]["lock"] = getFilehash(Path("./uv.lock"))
|
137
140
|
|
138
141
|
if uvHashPath.exists():
|
139
142
|
with open(uvHashPath, "r") as file:
|
140
|
-
lastHash: dict = dict(rtoml.load(file)).get("hashes")
|
143
|
+
lastHash: dict[Any, Any] = dict(rtoml.load(file)).get("hashes")
|
141
144
|
if currentHash["hashes"] != lastHash:
|
142
145
|
with open(uvHashPath, "w") as file:
|
143
146
|
rtoml.dump(currentHash, file)
|
effectual/config.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
1
3
|
import rtoml
|
2
4
|
|
3
5
|
|
4
|
-
def loadConfig(configPath: str) -> dict:
|
6
|
+
def loadConfig(configPath: str) -> dict[Any, Any]:
|
5
7
|
"""Loads effectual config from a file
|
6
8
|
|
7
9
|
Args:
|
@@ -16,8 +18,17 @@ def loadConfig(configPath: str) -> dict:
|
|
16
18
|
"""
|
17
19
|
try:
|
18
20
|
with open(configPath, "r", encoding="utf-8") as file:
|
19
|
-
|
20
|
-
configData
|
21
|
+
configData: dict[Any, Any] = dict(rtoml.load(file))
|
22
|
+
if configData is None:
|
23
|
+
configData = {
|
24
|
+
"sourceDirectory": "./src/",
|
25
|
+
"outputDirectory": "./dist/",
|
26
|
+
"outputFileName": "bundle.pyz",
|
27
|
+
"minification": True,
|
28
|
+
"compressionLevel": 5,
|
29
|
+
}
|
30
|
+
else:
|
31
|
+
configData = configData.get("tool").get("effectual") # type: ignore
|
21
32
|
|
22
33
|
except ValueError as e:
|
23
34
|
raise RuntimeError(f"Invalid TOML in {configPath}: {e}")
|
effectual/developer.py
CHANGED
@@ -2,6 +2,7 @@ import subprocess
|
|
2
2
|
import time
|
3
3
|
import zipfile
|
4
4
|
from pathlib import Path
|
5
|
+
from typing import Any
|
5
6
|
|
6
7
|
from .colors import completeColor, fileColor, tagColor
|
7
8
|
from .config import loadConfig
|
@@ -27,10 +28,9 @@ def bundle(sourceDirectory: Path, outputFile: Path) -> None:
|
|
27
28
|
|
28
29
|
def main() -> None:
|
29
30
|
"""Super fast bundling for the 'task dev' command"""
|
30
|
-
|
31
|
-
configData: dict = loadConfig("./pyproject.toml")
|
31
|
+
configData: dict[Any, Any] = loadConfig("./pyproject.toml")
|
32
32
|
sourceDirectory: Path = Path(configData.get("sourceDirectory", "src/"))
|
33
|
-
outputFileName:
|
33
|
+
outputFileName: Path = Path(configData.get("outputFileName", "bundle.pyz"))
|
34
34
|
devBundlePath: Path = Path("./.effectual_cache/dev/")
|
35
35
|
devBundlePath.mkdir(parents=True, exist_ok=True)
|
36
36
|
|
@@ -40,12 +40,12 @@ def main() -> None:
|
|
40
40
|
|
41
41
|
runCommand = subprocess.Popen(["uv", "run", outputFile], shell=True)
|
42
42
|
|
43
|
-
|
43
|
+
lastHashSet: set[str] = getAllHashes(sourceDirectory, ".py")
|
44
44
|
|
45
45
|
while True:
|
46
|
-
|
47
|
-
if
|
48
|
-
|
46
|
+
currentHashSet: set[str] = getAllHashes(sourceDirectory, ".py")
|
47
|
+
if currentHashSet != lastHashSet:
|
48
|
+
lastHashSet = currentHashSet
|
49
49
|
runCommand.kill()
|
50
50
|
runCommand.wait()
|
51
51
|
outputFile.unlink()
|
effectual/fileHash.py
CHANGED
@@ -7,26 +7,28 @@ def getFilehash(filePath: Path) -> str:
|
|
7
7
|
"""Gets the file hash of a single python script
|
8
8
|
|
9
9
|
Args:
|
10
|
-
filePath (Path): Path to
|
10
|
+
filePath (Path): Path to a file
|
11
11
|
|
12
12
|
Returns:
|
13
|
-
str: Hash of the
|
13
|
+
str: Hash of the file
|
14
14
|
"""
|
15
15
|
with open(filePath, "rb") as file:
|
16
|
-
fileHash = hashlib.
|
16
|
+
fileHash = hashlib.sha1(file.read()).hexdigest()
|
17
17
|
return fileHash
|
18
18
|
|
19
19
|
|
20
|
-
def getAllHashes(sourceDirectory: Path) ->
|
20
|
+
def getAllHashes(sourceDirectory: Path, fileExtension: str) -> set[str]:
|
21
21
|
"""Gets all hashes in directory
|
22
22
|
|
23
23
|
Args:
|
24
|
-
sourceDirectory (Path): Path to
|
24
|
+
sourceDirectory (Path): Path to a folder containing files
|
25
25
|
|
26
26
|
Returns:
|
27
|
-
|
27
|
+
set[str]: Set containing paths and hashes
|
28
28
|
"""
|
29
29
|
|
30
30
|
with Pool() as pool:
|
31
|
-
hashList:
|
31
|
+
hashList: set[str] = set(
|
32
|
+
pool.map(getFilehash, sourceDirectory.glob(f"*.{fileExtension}"))
|
33
|
+
)
|
32
34
|
return hashList
|
effectual/minifier.py
CHANGED
@@ -38,7 +38,7 @@ def minifyToString(filePath: Path) -> str:
|
|
38
38
|
Returns:
|
39
39
|
str: Minified string
|
40
40
|
"""
|
41
|
-
with filePath.open("r"
|
41
|
+
with filePath.open("r") as fileR:
|
42
42
|
minifiedCode: str = str(
|
43
43
|
minify(
|
44
44
|
fileR.read(),
|
@@ -46,6 +46,6 @@ def minifyToString(filePath: Path) -> str:
|
|
46
46
|
remove_literal_statements=True,
|
47
47
|
remove_debug=True,
|
48
48
|
)
|
49
|
-
)
|
49
|
+
)
|
50
50
|
|
51
51
|
return minifiedCode
|
@@ -0,0 +1,12 @@
|
|
1
|
+
effectual/__init__.py,sha256=9hA5S-390BtY7m-NojGHioaBJJ8vEM3IXuMvmzWBv0E,407
|
2
|
+
effectual/build.py,sha256=LjPsTegLoxf2Ta3VwOV2LcMITf7ZEdPOuIcAJ0RXq7M,5669
|
3
|
+
effectual/colors.py,sha256=na7SEUSXM7aHvEKeIAn5shrZJtrBYq_ZUp121GRO_PQ,1411
|
4
|
+
effectual/config.py,sha256=otTF0HIBwECrHpXsB-e_rlxDZg5uRwIIoUPC37TZl8Q,1165
|
5
|
+
effectual/developer.py,sha256=-S55Vllozoi-WlJKjD2SXiuLuOuGEHnsmz1I3S5vIUo,2053
|
6
|
+
effectual/fileHash.py,sha256=ftFDY0RY1RF-IQxgbS9HfJp9mzgc3I6Acl69CIKUL2o,848
|
7
|
+
effectual/minifier.py,sha256=7GHgQWzin2J1W62yMReHXaYIChXc3f0rNJA-yY4LDEI,1313
|
8
|
+
effectual-0.4.0.dist-info/METADATA,sha256=heiu95UEveT9SrhVpai8S_fLEToTc56u55kjSqWQTxo,2527
|
9
|
+
effectual-0.4.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
10
|
+
effectual-0.4.0.dist-info/entry_points.txt,sha256=1W7EjlLZkw_Wz8V1SgdzzDis-CRE5IINyg74upsB0zU,40
|
11
|
+
effectual-0.4.0.dist-info/licenses/LICENSE,sha256=RrVXS_K_FctToNx9BLuZm9vbcpTi3PHNzWMaz7QyVeg,1082
|
12
|
+
effectual-0.4.0.dist-info/RECORD,,
|
effectual-0.3.4.dist-info/RECORD
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
effectual/__init__.py,sha256=9hA5S-390BtY7m-NojGHioaBJJ8vEM3IXuMvmzWBv0E,407
|
2
|
-
effectual/build.py,sha256=AfeQXckE2dhEpJAZg7T0dxYKudg7n7Ghy1BVc4f6L9A,5517
|
3
|
-
effectual/colors.py,sha256=na7SEUSXM7aHvEKeIAn5shrZJtrBYq_ZUp121GRO_PQ,1411
|
4
|
-
effectual/config.py,sha256=LzGT8e-zq7Rc-HOp3-r6g1XRiN9v0sCq5aeWL0bqFLY,754
|
5
|
-
effectual/developer.py,sha256=Ia6LPvDbO5kkF9dRIw3H23sulmWT8pLis55-PRQIInI,2014
|
6
|
-
effectual/fileHash.py,sha256=m2oPjhAcSH0Qc7J7aMkmjOlgDr5Lzilcfl1ppeoDxI8,810
|
7
|
-
effectual/minifier.py,sha256=RlUD0mUNDi7YZ1P-dDL6Y4FlCkfiiJP8G4TpX2y45iI,1347
|
8
|
-
effectual-0.3.4.dist-info/METADATA,sha256=E0sHvdgK8jKXY-B6pP5Cn8dWVDERD7h-kU3GfZ7eK8M,2527
|
9
|
-
effectual-0.3.4.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
10
|
-
effectual-0.3.4.dist-info/entry_points.txt,sha256=1W7EjlLZkw_Wz8V1SgdzzDis-CRE5IINyg74upsB0zU,40
|
11
|
-
effectual-0.3.4.dist-info/licenses/LICENSE,sha256=RrVXS_K_FctToNx9BLuZm9vbcpTi3PHNzWMaz7QyVeg,1082
|
12
|
-
effectual-0.3.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|