effectual 0.5.4__py3-none-any.whl → 0.5.6__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.
- 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
|