effectual 0.5.4__py3-none-any.whl → 0.5.6__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- effectual/__init__.py +8 -2
- effectual/build.py +37 -47
- effectual/config.py +5 -4
- effectual/developer.py +1 -1
- effectual/treeshake.py +19 -0
- {effectual-0.5.4.dist-info → effectual-0.5.6.dist-info}/METADATA +3 -2
- effectual-0.5.6.dist-info/RECORD +12 -0
- effectual-0.5.4.dist-info/RECORD +0 -11
- /effectual/{minifier.py → transformations.py} +0 -0
- {effectual-0.5.4.dist-info → effectual-0.5.6.dist-info}/WHEEL +0 -0
- {effectual-0.5.4.dist-info → effectual-0.5.6.dist-info}/entry_points.txt +0 -0
- {effectual-0.5.4.dist-info → effectual-0.5.6.dist-info}/licenses/LICENSE +0 -0
effectual/__init__.py
CHANGED
@@ -8,7 +8,10 @@ def main() -> None:
|
|
8
8
|
|
9
9
|
@click.command("dist")
|
10
10
|
def dist() -> None:
|
11
|
-
"""
|
11
|
+
"""
|
12
|
+
Bundles your source directory
|
13
|
+
into a production bundle
|
14
|
+
"""
|
12
15
|
from . import build
|
13
16
|
|
14
17
|
build.main()
|
@@ -16,7 +19,10 @@ def dist() -> None:
|
|
16
19
|
|
17
20
|
@click.command("dev")
|
18
21
|
def dev() -> None:
|
19
|
-
"""
|
22
|
+
"""
|
23
|
+
Bundles your source directory
|
24
|
+
into a developer bundle
|
25
|
+
"""
|
20
26
|
from . import developer
|
21
27
|
|
22
28
|
developer.main()
|
effectual/build.py
CHANGED
@@ -10,15 +10,16 @@ from watch_lite import getHash
|
|
10
10
|
|
11
11
|
from .colors import completeColor, fileColor, folderColor, tagColor
|
12
12
|
from .config import dumpHashes, loadConfig, loadToml
|
13
|
-
from .
|
13
|
+
from .transformations import minifyToString
|
14
|
+
from .treeshake import cleanPackages
|
14
15
|
|
15
16
|
|
16
17
|
def bundleFiles(
|
17
|
-
sourceDirectory: Path,
|
18
|
-
outputDirectory: Path,
|
19
|
-
outputFileName: str,
|
20
|
-
compressionLevel: int,
|
21
|
-
minification: bool,
|
18
|
+
sourceDirectory: Path = Path("./src/"),
|
19
|
+
outputDirectory: Path = Path("./out"),
|
20
|
+
outputFileName: str = "bundle.pyz",
|
21
|
+
compressionLevel: int = 5,
|
22
|
+
minification: bool = True,
|
22
23
|
) -> None:
|
23
24
|
"""Bundles dependencies and scripts into a single .pyz archive
|
24
25
|
|
@@ -42,16 +43,19 @@ def bundleFiles(
|
|
42
43
|
compression=zipfile.ZIP_DEFLATED,
|
43
44
|
) as bundler:
|
44
45
|
cachePath: Path = Path("./.effectual_cache/cachedPackages")
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
if cachePath.exists():
|
47
|
+
if os.listdir(cachePath):
|
48
|
+
totalSize: int = int(0)
|
49
|
+
for cachedFile in cachePath.rglob("*"):
|
50
|
+
if cachedFile.is_dir() and not any(cachedFile.iterdir()):
|
51
|
+
continue
|
52
|
+
totalSize += cachedFile.stat().st_size
|
53
|
+
arcName = cachedFile.relative_to(cachePath)
|
54
|
+
bundler.write(cachedFile, arcname=arcName)
|
55
|
+
|
56
|
+
print(
|
57
|
+
f"{tagColor('bundling')} || uv dependencies {folderColor(totalSize)}" # noqa: E501
|
58
|
+
)
|
55
59
|
|
56
60
|
for pyFile in sourceDirectory.rglob("*.py"):
|
57
61
|
print(f"{tagColor('bundling')} || {pyFile.name} {fileColor(pyFile)}")
|
@@ -67,42 +71,29 @@ def bundleFiles(
|
|
67
71
|
def dependencies(minify: bool) -> None:
|
68
72
|
packages: list[str] = (
|
69
73
|
loadToml("./pyproject.toml").get("project").get("dependencies")
|
70
|
-
)
|
71
|
-
|
72
|
-
arguments: list[str] = ["--no-compile", "--quiet", "--no-binary=none", "--no-cache"]
|
73
|
-
|
74
|
-
pathToInstallTo: str = "./.effectual_cache/cachedPackages"
|
75
|
-
argumentString: str = " ".join(arguments)
|
74
|
+
)
|
76
75
|
|
77
|
-
if
|
78
|
-
|
76
|
+
if len(packages) != 0:
|
77
|
+
arguments: list[str] = ["--no-compile", "--quiet", "--no-binary=none"]
|
79
78
|
|
80
|
-
|
81
|
-
|
82
|
-
os.system(f'uv pip install "{key}" {argumentString} --target {pathToInstallTo}')
|
79
|
+
pathToInstallTo: str = "./.effectual_cache/cachedPackages"
|
80
|
+
argumentString: str = " ".join(arguments)
|
83
81
|
|
84
|
-
|
82
|
+
if Path(pathToInstallTo).exists():
|
83
|
+
shutil.rmtree(pathToInstallTo)
|
85
84
|
|
86
|
-
|
85
|
+
for key in packages:
|
86
|
+
print(f"{tagColor('installing')} || {key}")
|
87
|
+
os.system(
|
88
|
+
f'uv pip install "{key}" {argumentString} --target {pathToInstallTo}'
|
89
|
+
)
|
87
90
|
|
88
|
-
|
89
|
-
pool.map(optimizeDependencies, Path(pathToInstallTo).rglob("*"))
|
91
|
+
print(f"{tagColor('optimizing')} || {', '.join(packages)}")
|
90
92
|
|
93
|
+
multiprocessing = importlib.import_module("multiprocessing")
|
91
94
|
|
92
|
-
|
93
|
-
|
94
|
-
if (
|
95
|
-
file.suffix in (".pyc", ".pyd", ".exe", ".typed")
|
96
|
-
or "__pycache__" in stringFile
|
97
|
-
or ".dist-info" in stringFile
|
98
|
-
or ".lock" in stringFile
|
99
|
-
):
|
100
|
-
try:
|
101
|
-
file.unlink()
|
102
|
-
except PermissionError:
|
103
|
-
pass
|
104
|
-
elif file.suffix == ".py":
|
105
|
-
minifyFile(file)
|
95
|
+
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
96
|
+
pool.map(cleanPackages, Path(pathToInstallTo).rglob("*"))
|
106
97
|
|
107
98
|
|
108
99
|
def main() -> None:
|
@@ -120,8 +111,7 @@ def main() -> None:
|
|
120
111
|
compressionLevel: int = max(
|
121
112
|
0, min(9, configData.get("compressionLevel", 5))
|
122
113
|
) # Default level if not set
|
123
|
-
|
124
|
-
minification = configData.get("minification", True)
|
114
|
+
minification: bool = configData.get("minification", True)
|
125
115
|
|
126
116
|
if not sourceDirectory.is_dir():
|
127
117
|
raise RuntimeError(
|
effectual/config.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
import io
|
2
|
+
from pathlib import Path
|
2
3
|
from typing import Any
|
3
4
|
|
4
5
|
import rtoml
|
5
6
|
|
6
7
|
|
7
|
-
def loadToml(tomlFile: str) -> dict[str, Any]:
|
8
|
+
def loadToml(tomlFile: str | Path) -> dict[str, Any]:
|
8
9
|
"""Loads a toml file from a specific path to a dictionary
|
9
10
|
|
10
11
|
Args:
|
@@ -19,14 +20,14 @@ def loadToml(tomlFile: str) -> dict[str, Any]:
|
|
19
20
|
"""
|
20
21
|
try:
|
21
22
|
with open(tomlFile, "r", encoding="utf-8") as file:
|
22
|
-
return dict(rtoml.load(file))
|
23
|
+
return dict(rtoml.load(file))
|
23
24
|
except ValueError as e:
|
24
25
|
raise RuntimeError(f"Invalid TOML in {tomlFile}: {e}")
|
25
26
|
except FileNotFoundError:
|
26
27
|
raise RuntimeError(f"TOML file {tomlFile} not found.")
|
27
28
|
|
28
29
|
|
29
|
-
def loadConfig(configPath: str) -> dict[Any, Any]:
|
30
|
+
def loadConfig(configPath: str = "./pyproject.toml") -> dict[Any, Any]:
|
30
31
|
"""Loads effectual config from a file
|
31
32
|
|
32
33
|
Args:
|
@@ -57,4 +58,4 @@ def dumpHashes(hashesToDump: dict[str, dict[str, str]], file: io.TextIOWrapper)
|
|
57
58
|
hashesToDump (dict[str, dict[str, str]]): Dictionary of hashes to dump as toml
|
58
59
|
file (_type_): File object
|
59
60
|
"""
|
60
|
-
|
61
|
+
rtoml.dump(hashesToDump, file, pretty=False)
|
effectual/developer.py
CHANGED
@@ -46,10 +46,10 @@ def main() -> None:
|
|
46
46
|
while True:
|
47
47
|
currentHashSet: set[str] = getAllHashes(str(sourceDirectory))
|
48
48
|
if currentHashSet != lastHashSet:
|
49
|
-
lastHashSet = currentHashSet
|
50
49
|
runCommand.kill()
|
51
50
|
runCommand.wait()
|
52
51
|
outputFile.unlink()
|
52
|
+
lastHashSet = currentHashSet
|
53
53
|
print(f"{tagColor('reloaded')} || file change detected")
|
54
54
|
bundle(sourceDirectory, outputFile)
|
55
55
|
runCommand = subprocess.Popen(["uv", "run", outputFile], shell=True)
|
effectual/treeshake.py
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
from transformations import minifyFile
|
4
|
+
|
5
|
+
|
6
|
+
def cleanPackages(file: Path) -> None:
|
7
|
+
stringFile: str = str(file)
|
8
|
+
if (
|
9
|
+
file.suffix in (".pyc", ".pyd", ".exe", ".typed")
|
10
|
+
or "__pycache__" in stringFile
|
11
|
+
or ".dist-info" in stringFile
|
12
|
+
or ".lock" in stringFile
|
13
|
+
):
|
14
|
+
try:
|
15
|
+
file.unlink()
|
16
|
+
except PermissionError:
|
17
|
+
pass
|
18
|
+
elif file.suffix == ".py":
|
19
|
+
minifyFile(file)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: effectual
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.6
|
4
4
|
Summary: A python package/script bundler
|
5
5
|
Project-URL: Homepage, https://github.com/effectualpy/effectual
|
6
6
|
Author-email: jake <jakewdr@proton.me>
|
@@ -79,7 +79,8 @@ This is like what what [Rollup](https://rollupjs.org/) does for vite
|
|
79
79
|
# To be added
|
80
80
|
|
81
81
|
- [Treeshaking](https://webpack.js.org/guides/tree-shaking/)
|
82
|
-
-
|
82
|
+
- Rewriting some time critical parts in Rust 🚀🦀
|
83
|
+
- Cross platform compatibility
|
83
84
|
- Plugin and loader system
|
84
85
|
|
85
86
|
# Contributions
|
@@ -0,0 +1,12 @@
|
|
1
|
+
effectual/__init__.py,sha256=Hg_RSVgpLZvaeBUqt5uL_r5YIDsVdKPcFE2L5WJVYbM,482
|
2
|
+
effectual/build.py,sha256=c1GyLhIqybBhED8eou8B7GOXwpmeSWvxpv4PBkYgLtQ,5463
|
3
|
+
effectual/colors.py,sha256=na7SEUSXM7aHvEKeIAn5shrZJtrBYq_ZUp121GRO_PQ,1411
|
4
|
+
effectual/config.py,sha256=Z99V7AnJpSWuo-aEz10TDj5BAaT7tboGJUjggj-HQh4,1798
|
5
|
+
effectual/developer.py,sha256=D_KX6YYWgHF5b6ri-48ai1RqxqiIqZ0Rw-dVHG9NLHE,2052
|
6
|
+
effectual/transformations.py,sha256=7GHgQWzin2J1W62yMReHXaYIChXc3f0rNJA-yY4LDEI,1313
|
7
|
+
effectual/treeshake.py,sha256=VQCFFbS9DF7824Qwl8oIBTcRMJoyYi5LOdXlAA9vo2g,485
|
8
|
+
effectual-0.5.6.dist-info/METADATA,sha256=Q-DezI6eEDCfqYpjMFsth5F00JFXHw-u3FkOXpzpcqM,2587
|
9
|
+
effectual-0.5.6.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
10
|
+
effectual-0.5.6.dist-info/entry_points.txt,sha256=1W7EjlLZkw_Wz8V1SgdzzDis-CRE5IINyg74upsB0zU,40
|
11
|
+
effectual-0.5.6.dist-info/licenses/LICENSE,sha256=RrVXS_K_FctToNx9BLuZm9vbcpTi3PHNzWMaz7QyVeg,1082
|
12
|
+
effectual-0.5.6.dist-info/RECORD,,
|
effectual-0.5.4.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
effectual/__init__.py,sha256=9hA5S-390BtY7m-NojGHioaBJJ8vEM3IXuMvmzWBv0E,407
|
2
|
-
effectual/build.py,sha256=Ub_EL71GcclEoG0zJz20aomm-8iwOFxh6wS01W5PlK8,5556
|
3
|
-
effectual/colors.py,sha256=na7SEUSXM7aHvEKeIAn5shrZJtrBYq_ZUp121GRO_PQ,1411
|
4
|
-
effectual/config.py,sha256=3vMO_r9jf3GX7VMnZBbedk-g9rgUkfwa57bpq7yLQiQ,1767
|
5
|
-
effectual/developer.py,sha256=ERbmZuaUzSVzKgWNUWMa1H7K39xfBNeHolUEdUKcOWc,2052
|
6
|
-
effectual/minifier.py,sha256=7GHgQWzin2J1W62yMReHXaYIChXc3f0rNJA-yY4LDEI,1313
|
7
|
-
effectual-0.5.4.dist-info/METADATA,sha256=S46Zge-cvbJWjq5mcxt_CW5P953iEnDf1pYROylBqIE,2560
|
8
|
-
effectual-0.5.4.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
9
|
-
effectual-0.5.4.dist-info/entry_points.txt,sha256=1W7EjlLZkw_Wz8V1SgdzzDis-CRE5IINyg74upsB0zU,40
|
10
|
-
effectual-0.5.4.dist-info/licenses/LICENSE,sha256=RrVXS_K_FctToNx9BLuZm9vbcpTi3PHNzWMaz7QyVeg,1082
|
11
|
-
effectual-0.5.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|