fastled 1.2.4__tar.gz → 1.2.6__tar.gz
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.
- {fastled-1.2.4 → fastled-1.2.6}/PKG-INFO +3 -1
- {fastled-1.2.4 → fastled-1.2.6}/README.md +2 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/__init__.py +130 -5
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/app.py +26 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/docker_manager.py +64 -1
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/live_client.py +17 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/parse_args.py +11 -1
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/project_init.py +53 -3
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/site/build.py +3 -3
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/PKG-INFO +3 -1
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/SOURCES.txt +1 -0
- fastled-1.2.6/tests/test_build.py +57 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_examples.py +1 -1
- {fastled-1.2.4 → fastled-1.2.6}/.aiderignore +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/build_multi_docker_image.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/build_webpage.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/lint.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/publish_release.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/test_build_exe.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/test_macos.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/test_ubuntu.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.github/workflows/test_win.yml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.gitignore +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.pylintrc +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.vscode/launch.json +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.vscode/settings.json +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/.vscode/tasks.json +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/LICENSE +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/MANIFEST.in +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/RELEASE.md +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/TODO.md +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/build_exe.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/build_site.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/clean +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/install +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/lint +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/pyproject.toml +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/requirements.testing.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/setup.cfg +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/setup.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/assets/example.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/cli.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/client_server.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/compile_server.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/compile_server_impl.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/filewatcher.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/keyboard.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/open_browser.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/paths.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/select_sketch_directory.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/settings.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/sketch.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/spinner.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/string_diff.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/test/can_run_local_docker_tests.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/test/examples.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/types.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/util.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled/web_compile.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/dependency_links.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/entry_points.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/requires.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/src/fastled.egg-info/top_level.txt +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/test +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_api.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_bad_ino.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_build_examples.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_cli.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_compile_server.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_docker_linux_on_windows.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_embedded_data.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_filechanger.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_ino/bad/bad.ino +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_ino/embedded/data/bigdata.dat +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_ino/embedded/wasm.ino +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_ino/wasm/wasm.ino +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_project_init.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_server_and_client_seperatly.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/tests/test_webcompile.py +0 -0
- {fastled-1.2.4 → fastled-1.2.6}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.6
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -266,6 +266,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
|
|
266
266
|
|
267
267
|
# Revisions
|
268
268
|
|
269
|
+
* 1.2.6 - Now builds image from the project root of FastLED.
|
270
|
+
* 1.1.25 - Fix up paths for `--init`
|
269
271
|
* 1.1.24 - Mac/Linux now properly responds to ctrl-c when waiting for a key event.
|
270
272
|
* 1.1.23 - Fixes missing `live-server` on platforms that don't have it already.
|
271
273
|
* 1.2.22 - Added `--purge` and added docker api at __init__.
|
@@ -243,6 +243,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
|
|
243
243
|
|
244
244
|
# Revisions
|
245
245
|
|
246
|
+
* 1.2.6 - Now builds image from the project root of FastLED.
|
247
|
+
* 1.1.25 - Fix up paths for `--init`
|
246
248
|
* 1.1.24 - Mac/Linux now properly responds to ctrl-c when waiting for a key event.
|
247
249
|
* 1.1.23 - Fixes missing `live-server` on platforms that don't have it already.
|
248
250
|
* 1.2.22 - Added `--purge` and added docker api at __init__.
|
@@ -13,7 +13,7 @@ from .types import BuildMode, CompileResult, CompileServerError
|
|
13
13
|
# IMPORTANT! There's a bug in github which will REJECT any version update
|
14
14
|
# that has any other change in the repo. Please bump the version as the
|
15
15
|
# ONLY change in a commit, or else the pypi update and the release will fail.
|
16
|
-
__version__ = "1.2.
|
16
|
+
__version__ = "1.2.6"
|
17
17
|
|
18
18
|
|
19
19
|
class Api:
|
@@ -131,17 +131,141 @@ class Docker:
|
|
131
131
|
from fastled.docker_manager import DockerManager
|
132
132
|
from fastled.settings import CONTAINER_NAME
|
133
133
|
|
134
|
-
|
134
|
+
docker_mgr = DockerManager()
|
135
135
|
container_name = container_name or CONTAINER_NAME
|
136
|
-
return
|
136
|
+
return docker_mgr.is_container_running(container_name)
|
137
137
|
|
138
138
|
@staticmethod
|
139
139
|
def purge() -> None:
|
140
140
|
from fastled.docker_manager import DockerManager
|
141
141
|
from fastled.settings import CONTAINER_NAME
|
142
142
|
|
143
|
-
|
144
|
-
|
143
|
+
docker_mgr = DockerManager()
|
144
|
+
docker_mgr.purge(CONTAINER_NAME)
|
145
|
+
|
146
|
+
@staticmethod
|
147
|
+
def build_from_github(
|
148
|
+
url: str = "https://github.com/fastled/fastled",
|
149
|
+
output_dir: Path | str = Path(".cache/fastled"),
|
150
|
+
) -> str:
|
151
|
+
"""Build the FastLED WASM compiler Docker image from a GitHub repository.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
url: GitHub repository URL (default: https://github.com/fastled/fastled)
|
155
|
+
output_dir: Directory to clone the repo into (default: .cache/fastled)
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
Container name.
|
159
|
+
"""
|
160
|
+
import subprocess
|
161
|
+
|
162
|
+
from fastled.docker_manager import DockerManager
|
163
|
+
from fastled.settings import CONTAINER_NAME, IMAGE_NAME
|
164
|
+
|
165
|
+
if isinstance(output_dir, str):
|
166
|
+
output_dir = Path(output_dir)
|
167
|
+
|
168
|
+
# Create output directory if it doesn't exist
|
169
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
170
|
+
|
171
|
+
# Clone or update the repository
|
172
|
+
if (output_dir / ".git").exists():
|
173
|
+
print(f"Updating existing repository in {output_dir}")
|
174
|
+
# Reset local changes and move HEAD back to handle force pushes
|
175
|
+
subprocess.run(
|
176
|
+
["git", "reset", "--hard", "HEAD~10"],
|
177
|
+
cwd=output_dir,
|
178
|
+
check=True,
|
179
|
+
capture_output=True, # Suppress output of reset
|
180
|
+
)
|
181
|
+
subprocess.run(
|
182
|
+
["git", "pull", "origin", "master"], cwd=output_dir, check=True
|
183
|
+
)
|
184
|
+
else:
|
185
|
+
print(f"Cloning {url} into {output_dir}")
|
186
|
+
subprocess.run(["git", "clone", url, str(output_dir)], check=True)
|
187
|
+
|
188
|
+
dockerfile_path = (
|
189
|
+
output_dir / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
|
190
|
+
)
|
191
|
+
|
192
|
+
if not dockerfile_path.exists():
|
193
|
+
raise FileNotFoundError(
|
194
|
+
f"Dockerfile not found at {dockerfile_path}. "
|
195
|
+
"This may not be a valid FastLED repository."
|
196
|
+
)
|
197
|
+
|
198
|
+
docker_mgr = DockerManager()
|
199
|
+
|
200
|
+
# Build the image
|
201
|
+
docker_mgr.build_image(
|
202
|
+
image_name=IMAGE_NAME,
|
203
|
+
tag="main",
|
204
|
+
dockerfile_path=dockerfile_path,
|
205
|
+
build_context=output_dir,
|
206
|
+
build_args={"NO_PREWARM": "1"},
|
207
|
+
)
|
208
|
+
|
209
|
+
# Run the container and return it
|
210
|
+
container = docker_mgr.run_container_detached(
|
211
|
+
image_name=IMAGE_NAME,
|
212
|
+
tag="main",
|
213
|
+
container_name=CONTAINER_NAME,
|
214
|
+
command=None, # Use default command from Dockerfile
|
215
|
+
volumes=None, # No volumes needed for build
|
216
|
+
ports=None, # No ports needed for build
|
217
|
+
remove_previous=True, # Remove any existing container
|
218
|
+
)
|
219
|
+
|
220
|
+
return container.name
|
221
|
+
|
222
|
+
@staticmethod
|
223
|
+
def build_from_fastled_repo(
|
224
|
+
project_root: Path | str = Path("."), platform_tag: str = ""
|
225
|
+
) -> str:
|
226
|
+
"""Build the FastLED WASM compiler Docker image, which will be tagged as "latest".
|
227
|
+
|
228
|
+
Args:
|
229
|
+
project_root: Path to the FastLED project root directory
|
230
|
+
platform_tag: Optional platform tag (e.g. "-arm64" for ARM builds)
|
231
|
+
|
232
|
+
Returns:
|
233
|
+
The string name of the docker container.
|
234
|
+
"""
|
235
|
+
from fastled.docker_manager import DockerManager
|
236
|
+
from fastled.settings import CONTAINER_NAME, IMAGE_NAME
|
237
|
+
|
238
|
+
if isinstance(project_root, str):
|
239
|
+
project_root = Path(project_root)
|
240
|
+
|
241
|
+
dockerfile_path = (
|
242
|
+
project_root / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
|
243
|
+
)
|
244
|
+
|
245
|
+
docker_mgr = DockerManager()
|
246
|
+
|
247
|
+
# Build the image
|
248
|
+
docker_mgr.build_image(
|
249
|
+
image_name=IMAGE_NAME,
|
250
|
+
tag="main",
|
251
|
+
dockerfile_path=dockerfile_path,
|
252
|
+
build_context=project_root,
|
253
|
+
build_args={"NO_PREWARM": "1"},
|
254
|
+
platform_tag=platform_tag,
|
255
|
+
)
|
256
|
+
|
257
|
+
# Run the container and return it
|
258
|
+
container = docker_mgr.run_container_detached(
|
259
|
+
image_name=IMAGE_NAME,
|
260
|
+
tag="main",
|
261
|
+
container_name=CONTAINER_NAME,
|
262
|
+
command=None, # Use default command from Dockerfile
|
263
|
+
volumes=None, # No volumes needed for build
|
264
|
+
ports=None, # No ports needed for build
|
265
|
+
remove_previous=True, # Remove any existing container
|
266
|
+
)
|
267
|
+
container_name = f"{container.name}"
|
268
|
+
return container_name
|
145
269
|
|
146
270
|
|
147
271
|
class Test:
|
@@ -173,6 +297,7 @@ class Test:
|
|
173
297
|
__all__ = [
|
174
298
|
"Api",
|
175
299
|
"Test",
|
300
|
+
"Build",
|
176
301
|
"CompileServer",
|
177
302
|
"CompileResult",
|
178
303
|
"CompileServerError",
|
@@ -51,6 +51,32 @@ def main() -> int:
|
|
51
51
|
print("Finished updating.")
|
52
52
|
return 0
|
53
53
|
|
54
|
+
if args.build:
|
55
|
+
try:
|
56
|
+
project_root = Path(".").absolute()
|
57
|
+
print(f"Building Docker image at {project_root}")
|
58
|
+
from fastled import Api, Docker
|
59
|
+
|
60
|
+
docker_image_name = Docker.build_from_fastled_repo(
|
61
|
+
project_root=project_root
|
62
|
+
)
|
63
|
+
print(f"Built Docker image: {docker_image_name}")
|
64
|
+
print("Running server")
|
65
|
+
with Api.server(
|
66
|
+
auto_updates=False, container_name=docker_image_name
|
67
|
+
) as server:
|
68
|
+
print(f"Server started at {server.url()}")
|
69
|
+
sketch_dir = Path("examples/wasm")
|
70
|
+
with Api.live_client(
|
71
|
+
sketch_directory=sketch_dir, host=server
|
72
|
+
) as client:
|
73
|
+
print(f"Client started at {client.url()}")
|
74
|
+
while True:
|
75
|
+
time.sleep(0.1)
|
76
|
+
except KeyboardInterrupt:
|
77
|
+
print("\nExiting from client...")
|
78
|
+
return 1
|
79
|
+
|
54
80
|
if args.server:
|
55
81
|
print("Running in server only mode.")
|
56
82
|
return run_server(args)
|
@@ -97,10 +97,12 @@ class RunningContainer:
|
|
97
97
|
|
98
98
|
class DockerManager:
|
99
99
|
def __init__(self) -> None:
|
100
|
+
from docker.errors import DockerException
|
101
|
+
|
100
102
|
try:
|
101
103
|
self._client: DockerClient | None = None
|
102
104
|
self.first_run = False
|
103
|
-
except
|
105
|
+
except DockerException as e:
|
104
106
|
stack = traceback.format_exc()
|
105
107
|
warnings.warn(f"Error initializing Docker client: {e}\n{stack}")
|
106
108
|
raise
|
@@ -610,6 +612,67 @@ class DockerManager:
|
|
610
612
|
print(f"Container {container_name} not found.")
|
611
613
|
return False
|
612
614
|
|
615
|
+
def build_image(
|
616
|
+
self,
|
617
|
+
image_name: str,
|
618
|
+
tag: str,
|
619
|
+
dockerfile_path: Path,
|
620
|
+
build_context: Path,
|
621
|
+
build_args: dict[str, str] | None = None,
|
622
|
+
platform_tag: str = "",
|
623
|
+
) -> None:
|
624
|
+
"""
|
625
|
+
Build a Docker image from a Dockerfile.
|
626
|
+
|
627
|
+
Args:
|
628
|
+
image_name: Name for the image
|
629
|
+
tag: Tag for the image
|
630
|
+
dockerfile_path: Path to the Dockerfile
|
631
|
+
build_context: Path to the build context directory
|
632
|
+
build_args: Optional dictionary of build arguments
|
633
|
+
platform_tag: Optional platform tag (e.g. "-arm64")
|
634
|
+
"""
|
635
|
+
if not dockerfile_path.exists():
|
636
|
+
raise FileNotFoundError(f"Dockerfile not found at {dockerfile_path}")
|
637
|
+
|
638
|
+
if not build_context.exists():
|
639
|
+
raise FileNotFoundError(
|
640
|
+
f"Build context directory not found at {build_context}"
|
641
|
+
)
|
642
|
+
|
643
|
+
print(f"Building Docker image {image_name}:{tag} from {dockerfile_path}")
|
644
|
+
|
645
|
+
# Prepare build arguments
|
646
|
+
buildargs = build_args or {}
|
647
|
+
if platform_tag:
|
648
|
+
buildargs["PLATFORM_TAG"] = platform_tag
|
649
|
+
|
650
|
+
try:
|
651
|
+
cmd_list = [
|
652
|
+
"docker",
|
653
|
+
"build",
|
654
|
+
"-t",
|
655
|
+
f"{image_name}:{tag}",
|
656
|
+
]
|
657
|
+
|
658
|
+
# Add build args
|
659
|
+
for arg_name, arg_value in buildargs.items():
|
660
|
+
cmd_list.extend(["--build-arg", f"{arg_name}={arg_value}"])
|
661
|
+
|
662
|
+
# Add dockerfile and context paths
|
663
|
+
cmd_list.extend(["-f", str(dockerfile_path), str(build_context)])
|
664
|
+
|
665
|
+
cmd_str = subprocess.list2cmdline(cmd_list)
|
666
|
+
print(f"Running command: {cmd_str}")
|
667
|
+
|
668
|
+
# Run the build command
|
669
|
+
subprocess.run(cmd_list, check=True)
|
670
|
+
print(f"Successfully built image {image_name}:{tag}")
|
671
|
+
|
672
|
+
except subprocess.CalledProcessError as e:
|
673
|
+
print(f"Error building Docker image: {e}")
|
674
|
+
raise
|
675
|
+
|
613
676
|
def purge(self, image_name: str) -> None:
|
614
677
|
"""
|
615
678
|
Remove all containers and images associated with the given image name.
|
@@ -45,6 +45,17 @@ class LiveClient:
|
|
45
45
|
)
|
46
46
|
return rtn
|
47
47
|
|
48
|
+
def url(self) -> str:
|
49
|
+
"""Get the URL of the server."""
|
50
|
+
if isinstance(self.host, CompileServer):
|
51
|
+
return self.host.url()
|
52
|
+
if self.host is None:
|
53
|
+
import warnings
|
54
|
+
|
55
|
+
warnings.warn("TODO: use the actual host.")
|
56
|
+
return "http://localhost:9021"
|
57
|
+
return self.host
|
58
|
+
|
48
59
|
@property
|
49
60
|
def running(self) -> bool:
|
50
61
|
return self.thread is not None and self.thread.is_alive()
|
@@ -67,3 +78,9 @@ class LiveClient:
|
|
67
78
|
"""Finalize the client."""
|
68
79
|
self.stop()
|
69
80
|
self.thread = None
|
81
|
+
|
82
|
+
def __enter__(self) -> "LiveClient":
|
83
|
+
return self
|
84
|
+
|
85
|
+
def __exit__(self, exc_type, exc_value, traceback) -> None:
|
86
|
+
self.finalize()
|
@@ -79,6 +79,12 @@ def parse_args() -> argparse.Namespace:
|
|
79
79
|
action="store_true",
|
80
80
|
help="Use localhost for web compilation from an instance of fastled --server, creating it if necessary",
|
81
81
|
)
|
82
|
+
parser.add_argument(
|
83
|
+
"--build",
|
84
|
+
"-b",
|
85
|
+
action="store_true",
|
86
|
+
help="Build the wasm compiler image from the FastLED repo",
|
87
|
+
)
|
82
88
|
parser.add_argument(
|
83
89
|
"--server",
|
84
90
|
"-s",
|
@@ -116,7 +122,11 @@ def parse_args() -> argparse.Namespace:
|
|
116
122
|
|
117
123
|
if args.init:
|
118
124
|
example = args.init if args.init is not True else None
|
119
|
-
|
125
|
+
try:
|
126
|
+
args.directory = project_init(example, args.directory)
|
127
|
+
except Exception as e:
|
128
|
+
print(f"Failed to initialize project: {e}")
|
129
|
+
sys.exit(1)
|
120
130
|
print("\nInitialized FastLED project in", args.directory)
|
121
131
|
print(f"Use 'fastled {args.directory}' to compile the project.")
|
122
132
|
sys.exit(0)
|
@@ -1,9 +1,13 @@
|
|
1
|
+
import _thread
|
2
|
+
import threading
|
3
|
+
import time
|
1
4
|
import zipfile
|
2
5
|
from pathlib import Path
|
3
6
|
|
4
7
|
import httpx
|
5
8
|
|
6
9
|
from fastled.settings import DEFAULT_URL
|
10
|
+
from fastled.spinner import Spinner
|
7
11
|
|
8
12
|
DEFAULT_EXAMPLE = "wasm"
|
9
13
|
|
@@ -34,6 +38,35 @@ def _prompt_for_example() -> str:
|
|
34
38
|
return answer
|
35
39
|
|
36
40
|
|
41
|
+
class DownloadThread(threading.Thread):
|
42
|
+
def __init__(self, url: str, json: str):
|
43
|
+
super().__init__(daemon=True)
|
44
|
+
self.url = url
|
45
|
+
self.json = json
|
46
|
+
self.bytes_downloaded = 0
|
47
|
+
self.content: bytes | None = None
|
48
|
+
self.error: Exception | None = None
|
49
|
+
self.success = False
|
50
|
+
|
51
|
+
def run(self) -> None:
|
52
|
+
timeout = httpx.Timeout(5.0, connect=5.0, read=120.0, write=30.0)
|
53
|
+
try:
|
54
|
+
with httpx.Client(timeout=timeout) as client:
|
55
|
+
with client.stream("POST", self.url, json=self.json) as response:
|
56
|
+
response.raise_for_status()
|
57
|
+
content = b""
|
58
|
+
for chunk in response.iter_bytes():
|
59
|
+
content += chunk
|
60
|
+
self.bytes_downloaded += len(chunk)
|
61
|
+
self.content = content
|
62
|
+
self.success = True
|
63
|
+
except KeyboardInterrupt:
|
64
|
+
self.error = RuntimeError("Download cancelled")
|
65
|
+
_thread.interrupt_main()
|
66
|
+
except Exception as e:
|
67
|
+
self.error = e
|
68
|
+
|
69
|
+
|
37
70
|
def project_init(
|
38
71
|
example: str | None = "PROMPT", # prompt for example
|
39
72
|
outputdir: Path | None = None,
|
@@ -56,9 +89,26 @@ def project_init(
|
|
56
89
|
assert example is not None
|
57
90
|
endpoint_url = f"{host}/project/init"
|
58
91
|
json = example
|
59
|
-
|
60
|
-
|
61
|
-
|
92
|
+
print(f"Initializing project with example '{example}', url={endpoint_url}")
|
93
|
+
|
94
|
+
# Start download thread
|
95
|
+
download_thread = DownloadThread(endpoint_url, json)
|
96
|
+
# spinner = Spinner("Downloading project...")
|
97
|
+
with Spinner(f"Downloading project {example}..."):
|
98
|
+
download_thread.start()
|
99
|
+
while download_thread.is_alive():
|
100
|
+
time.sleep(0.1)
|
101
|
+
|
102
|
+
print() # New line after progress
|
103
|
+
download_thread.join()
|
104
|
+
|
105
|
+
# Check for errors
|
106
|
+
if not download_thread.success:
|
107
|
+
assert download_thread.error is not None
|
108
|
+
raise download_thread.error
|
109
|
+
|
110
|
+
content = download_thread.content
|
111
|
+
assert content is not None
|
62
112
|
tmpzip = outputdir / "fastled.zip"
|
63
113
|
outputdir.mkdir(exist_ok=True)
|
64
114
|
tmpzip.write_bytes(content)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.6
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -266,6 +266,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
|
|
266
266
|
|
267
267
|
# Revisions
|
268
268
|
|
269
|
+
* 1.2.6 - Now builds image from the project root of FastLED.
|
270
|
+
* 1.1.25 - Fix up paths for `--init`
|
269
271
|
* 1.1.24 - Mac/Linux now properly responds to ctrl-c when waiting for a key event.
|
270
272
|
* 1.1.23 - Fixes missing `live-server` on platforms that don't have it already.
|
271
273
|
* 1.2.22 - Added `--purge` and added docker api at __init__.
|
@@ -0,0 +1,57 @@
|
|
1
|
+
"""
|
2
|
+
Unit test file.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import unittest
|
6
|
+
from pathlib import Path
|
7
|
+
|
8
|
+
from fastled import Api, CompileServer, Docker, Test # type: ignore
|
9
|
+
|
10
|
+
HERE = Path(__file__).parent
|
11
|
+
PROJECT_ROOT = HERE.parent
|
12
|
+
FASTLED_SISTER_REPO = PROJECT_ROOT / ".." / "FastLED"
|
13
|
+
|
14
|
+
DEFAULT_GITHUB_URL = "https://github.com/fastled/fastled"
|
15
|
+
OUTPUT_DIR = Path(".cache/fastled")
|
16
|
+
|
17
|
+
|
18
|
+
def _enabled() -> bool:
|
19
|
+
"""Check if this system can run the tests."""
|
20
|
+
sister_repo_does_not_exist = not FASTLED_SISTER_REPO.exists()
|
21
|
+
|
22
|
+
if sister_repo_does_not_exist:
|
23
|
+
print(
|
24
|
+
f"This test is only enable when FastLED is a repo in the same directly as the project root folder: {FASTLED_SISTER_REPO} does not exist"
|
25
|
+
)
|
26
|
+
return False
|
27
|
+
|
28
|
+
return Test.can_run_local_docker_tests()
|
29
|
+
|
30
|
+
|
31
|
+
class BuildDockerFromRepoTester(unittest.TestCase):
|
32
|
+
"""Main tester class."""
|
33
|
+
|
34
|
+
@unittest.skipUnless(_enabled(), "Skipping test on non-Linux system on github")
|
35
|
+
def test_build_docker(self) -> None:
|
36
|
+
"""Builds the docker file from the fastled repo."""
|
37
|
+
|
38
|
+
docker_image_name = Docker.build_from_fastled_repo(FASTLED_SISTER_REPO)
|
39
|
+
self.assertTrue(docker_image_name, "Failed to build docker image")
|
40
|
+
server: CompileServer
|
41
|
+
with Api.server(auto_updates=True, container_name=docker_image_name) as server:
|
42
|
+
self.assertTrue(server.ping())
|
43
|
+
|
44
|
+
@unittest.skipUnless(_enabled(), "Skipping test on non-Linux system on github")
|
45
|
+
def test_build_docker_from_github(self) -> None:
|
46
|
+
"""Builds the docker file from the fastled repo."""
|
47
|
+
url = DEFAULT_GITHUB_URL
|
48
|
+
print("Building from github")
|
49
|
+
docker_image_name = Docker.build_from_github(url=url, output_dir=OUTPUT_DIR)
|
50
|
+
self.assertTrue(docker_image_name, "Failed to build docker image")
|
51
|
+
server: CompileServer
|
52
|
+
with Api.server(auto_updates=True, container_name=docker_image_name) as server:
|
53
|
+
self.assertTrue(server.ping())
|
54
|
+
|
55
|
+
|
56
|
+
if __name__ == "__main__":
|
57
|
+
unittest.main()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|