fastled 1.1.37__py2.py3-none-any.whl → 1.1.39__py2.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.
- fastled/__init__.py +44 -7
- fastled/client_server.py +114 -75
- fastled/compile_server.py +8 -3
- fastled/compile_server_impl.py +29 -22
- fastled/live_client.py +69 -0
- fastled/types.py +46 -10
- fastled/web_compile.py +7 -8
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/METADATA +114 -19
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/RECORD +13 -13
- fastled/build_mode.py +0 -25
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/LICENSE +0 -0
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/WHEEL +0 -0
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/entry_points.txt +0 -0
- {fastled-1.1.37.dist-info → fastled-1.1.39.dist-info}/top_level.txt +0 -0
fastled/__init__.py
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
# context
|
4
4
|
from contextlib import contextmanager
|
5
5
|
from pathlib import Path
|
6
|
+
from typing import Generator
|
6
7
|
|
7
8
|
from .compile_server import CompileServer
|
8
|
-
from .
|
9
|
+
from .live_client import LiveClient
|
10
|
+
from .types import BuildMode, CompileResult, CompileServerError
|
9
11
|
|
10
|
-
__version__ = "1.1.
|
12
|
+
__version__ = "1.1.39"
|
11
13
|
|
12
14
|
|
13
15
|
class Api:
|
@@ -29,17 +31,42 @@ class Api:
|
|
29
31
|
|
30
32
|
@staticmethod
|
31
33
|
def web_compile(
|
32
|
-
directory: Path | str,
|
33
|
-
|
34
|
+
directory: Path | str,
|
35
|
+
host: str | CompileServer | None = None,
|
36
|
+
build_mode: BuildMode = BuildMode.QUICK,
|
37
|
+
profile: bool = False, # When true then profile information will be enabled and included in the zip.
|
38
|
+
) -> CompileResult:
|
34
39
|
from fastled.web_compile import web_compile
|
35
40
|
|
36
41
|
if isinstance(host, CompileServer):
|
37
42
|
host = host.url()
|
38
43
|
if isinstance(directory, str):
|
39
44
|
directory = Path(directory)
|
40
|
-
out:
|
45
|
+
out: CompileResult = web_compile(
|
46
|
+
directory, host, build_mode=build_mode, profile=profile
|
47
|
+
)
|
41
48
|
return out
|
42
49
|
|
50
|
+
@staticmethod
|
51
|
+
def live_client(
|
52
|
+
sketch_directory: Path,
|
53
|
+
host: str | CompileServer | None = None,
|
54
|
+
auto_start=True,
|
55
|
+
open_web_browser=True,
|
56
|
+
keep_running=True,
|
57
|
+
build_mode=BuildMode.QUICK,
|
58
|
+
profile=False,
|
59
|
+
) -> LiveClient:
|
60
|
+
return LiveClient(
|
61
|
+
sketch_directory=sketch_directory,
|
62
|
+
host=host,
|
63
|
+
auto_start=auto_start,
|
64
|
+
open_web_browser=open_web_browser,
|
65
|
+
keep_running=keep_running,
|
66
|
+
build_mode=build_mode,
|
67
|
+
profile=profile,
|
68
|
+
)
|
69
|
+
|
43
70
|
@staticmethod
|
44
71
|
def spawn_server(
|
45
72
|
sketch_directory: Path | None = None,
|
@@ -47,7 +74,7 @@ class Api:
|
|
47
74
|
auto_updates=None,
|
48
75
|
auto_start=True,
|
49
76
|
container_name: str | None = None,
|
50
|
-
):
|
77
|
+
) -> CompileServer:
|
51
78
|
from fastled.compile_server import CompileServer
|
52
79
|
|
53
80
|
out = CompileServer(
|
@@ -67,7 +94,7 @@ class Api:
|
|
67
94
|
auto_updates=None,
|
68
95
|
auto_start=True,
|
69
96
|
container_name: str | None = None,
|
70
|
-
):
|
97
|
+
) -> Generator[CompileServer, None, None]:
|
71
98
|
server = Api.spawn_server(
|
72
99
|
sketch_directory=sketch_directory,
|
73
100
|
interactive=interactive,
|
@@ -92,3 +119,13 @@ class Test:
|
|
92
119
|
host = host.url()
|
93
120
|
|
94
121
|
return test_examples(examples=examples, host=host)
|
122
|
+
|
123
|
+
|
124
|
+
__all__ = [
|
125
|
+
"Api",
|
126
|
+
"Test",
|
127
|
+
"CompileServer",
|
128
|
+
"CompileResult",
|
129
|
+
"CompileServerError",
|
130
|
+
"BuildMode",
|
131
|
+
]
|
fastled/client_server.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
import argparse
|
2
2
|
import shutil
|
3
3
|
import tempfile
|
4
|
+
import threading
|
4
5
|
import time
|
5
6
|
from multiprocessing import Process
|
6
7
|
from pathlib import Path
|
7
8
|
|
8
|
-
from fastled.build_mode import BuildMode, get_build_mode
|
9
9
|
from fastled.compile_server import CompileServer
|
10
10
|
from fastled.docker_manager import DockerManager
|
11
11
|
from fastled.filewatcher import FileWatcherProcess
|
@@ -13,9 +13,7 @@ from fastled.keyboard import SpaceBarWatcher
|
|
13
13
|
from fastled.open_browser import open_browser_process
|
14
14
|
from fastled.settings import DEFAULT_URL
|
15
15
|
from fastled.sketch import looks_like_sketch_directory
|
16
|
-
|
17
|
-
# CompiledResult
|
18
|
-
from fastled.types import CompiledResult
|
16
|
+
from fastled.types import BuildMode, CompileResult, CompileServerError
|
19
17
|
from fastled.web_compile import (
|
20
18
|
SERVER_PORT,
|
21
19
|
ConnectionResult,
|
@@ -30,7 +28,7 @@ def _run_web_compiler(
|
|
30
28
|
build_mode: BuildMode,
|
31
29
|
profile: bool,
|
32
30
|
last_hash_value: str | None,
|
33
|
-
) ->
|
31
|
+
) -> CompileResult:
|
34
32
|
input_dir = Path(directory)
|
35
33
|
output_dir = input_dir / "fastled_js"
|
36
34
|
start = time.time()
|
@@ -42,7 +40,7 @@ def _run_web_compiler(
|
|
42
40
|
print("\nWeb compilation failed:")
|
43
41
|
print(f"Time taken: {diff:.2f} seconds")
|
44
42
|
print(web_result.stdout)
|
45
|
-
return
|
43
|
+
return web_result
|
46
44
|
|
47
45
|
def print_results() -> None:
|
48
46
|
hash_value = (
|
@@ -58,9 +56,7 @@ def _run_web_compiler(
|
|
58
56
|
if last_hash_value is not None and last_hash_value == web_result.hash_value:
|
59
57
|
print("\nSkipping redeploy: No significant changes found.")
|
60
58
|
print_results()
|
61
|
-
return
|
62
|
-
success=True, fastled_js=str(output_dir), hash_value=web_result.hash_value
|
63
|
-
)
|
59
|
+
return web_result
|
64
60
|
|
65
61
|
# Extract zip contents to fastled_js directory
|
66
62
|
output_dir.mkdir(exist_ok=True)
|
@@ -78,18 +74,20 @@ def _run_web_compiler(
|
|
78
74
|
|
79
75
|
print(web_result.stdout)
|
80
76
|
print_results()
|
81
|
-
return
|
82
|
-
success=True, fastled_js=str(output_dir), hash_value=web_result.hash_value
|
83
|
-
)
|
77
|
+
return web_result
|
84
78
|
|
85
79
|
|
86
|
-
def _try_start_server_or_get_url(
|
87
|
-
auto_update
|
88
|
-
|
80
|
+
def _try_start_server_or_get_url(
|
81
|
+
auto_update: bool, args_web: str | bool, localhost: bool
|
82
|
+
) -> tuple[str, CompileServer | None]:
|
83
|
+
is_local_host = localhost or (
|
84
|
+
isinstance(args_web, str)
|
85
|
+
and ("localhost" in args_web or "127.0.0.1" in args_web)
|
86
|
+
)
|
89
87
|
# test to see if there is already a local host server
|
90
88
|
local_host_needs_server = False
|
91
89
|
if is_local_host:
|
92
|
-
addr = "localhost" if
|
90
|
+
addr = "localhost" if localhost or not isinstance(args_web, str) else args_web
|
93
91
|
urls = [addr]
|
94
92
|
if ":" not in addr:
|
95
93
|
urls.append(f"{addr}:{SERVER_PORT}")
|
@@ -97,16 +95,16 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
|
|
97
95
|
result: ConnectionResult | None = find_good_connection(urls)
|
98
96
|
if result is not None:
|
99
97
|
print(f"Found local server at {result.host}")
|
100
|
-
return result.host
|
98
|
+
return (result.host, None)
|
101
99
|
else:
|
102
100
|
local_host_needs_server = True
|
103
101
|
|
104
|
-
if not local_host_needs_server and
|
105
|
-
if isinstance(
|
106
|
-
return
|
107
|
-
if isinstance(
|
108
|
-
return DEFAULT_URL
|
109
|
-
return
|
102
|
+
if not local_host_needs_server and args_web:
|
103
|
+
if isinstance(args_web, str):
|
104
|
+
return (args_web, None)
|
105
|
+
if isinstance(args_web, bool):
|
106
|
+
return (DEFAULT_URL, None)
|
107
|
+
return (args_web, None)
|
110
108
|
else:
|
111
109
|
try:
|
112
110
|
print("No local server found, starting one...")
|
@@ -114,76 +112,64 @@ def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServe
|
|
114
112
|
print("Waiting for the local compiler to start...")
|
115
113
|
if not compile_server.ping():
|
116
114
|
print("Failed to start local compiler.")
|
117
|
-
raise
|
118
|
-
return compile_server
|
115
|
+
raise CompileServerError("Failed to start local compiler.")
|
116
|
+
return (compile_server.url(), compile_server)
|
119
117
|
except KeyboardInterrupt:
|
120
118
|
raise
|
121
119
|
except RuntimeError:
|
122
120
|
print("Failed to start local compile server, using web compiler instead.")
|
123
|
-
return DEFAULT_URL
|
121
|
+
return (DEFAULT_URL, None)
|
124
122
|
|
125
123
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
if
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
124
|
+
def run_client(
|
125
|
+
directory: Path,
|
126
|
+
host: str | CompileServer | None,
|
127
|
+
open_web_browser: bool = True,
|
128
|
+
keep_running: bool = True, # if false, only one compilation will be done.
|
129
|
+
build_mode: BuildMode = BuildMode.QUICK,
|
130
|
+
profile: bool = False,
|
131
|
+
shutdown: threading.Event | None = None,
|
132
|
+
) -> int:
|
133
|
+
|
134
|
+
compile_server: CompileServer | None = (
|
135
|
+
host if isinstance(host, CompileServer) else None
|
136
|
+
)
|
137
|
+
shutdown = shutdown or threading.Event()
|
135
138
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
def get_url() -> str:
|
140
|
+
if compile_server is not None:
|
141
|
+
return compile_server.url()
|
142
|
+
if isinstance(host, str):
|
143
|
+
return host
|
144
|
+
return DEFAULT_URL
|
145
|
+
|
146
|
+
url = get_url()
|
142
147
|
|
143
|
-
url: str
|
144
148
|
try:
|
145
|
-
try:
|
146
|
-
url_or_server: str | CompileServer = _try_start_server_or_get_url(args)
|
147
|
-
if isinstance(url_or_server, str):
|
148
|
-
print(f"Found URL: {url_or_server}")
|
149
|
-
url = url_or_server
|
150
|
-
else:
|
151
|
-
compile_server = url_or_server
|
152
|
-
print(f"Server started at {compile_server.url()}")
|
153
|
-
url = compile_server.url()
|
154
|
-
except KeyboardInterrupt:
|
155
|
-
print("\nExiting from first try...")
|
156
|
-
if compile_server:
|
157
|
-
compile_server.stop()
|
158
|
-
return 1
|
159
|
-
except Exception as e:
|
160
|
-
print(f"Error: {e}")
|
161
|
-
return 1
|
162
|
-
build_mode: BuildMode = get_build_mode(args)
|
163
149
|
|
164
150
|
def compile_function(
|
165
151
|
url: str = url,
|
166
152
|
build_mode: BuildMode = build_mode,
|
167
153
|
profile: bool = profile,
|
168
154
|
last_hash_value: str | None = None,
|
169
|
-
) ->
|
155
|
+
) -> CompileResult:
|
170
156
|
return _run_web_compiler(
|
171
|
-
|
157
|
+
directory,
|
172
158
|
host=url,
|
173
159
|
build_mode=build_mode,
|
174
160
|
profile=profile,
|
175
161
|
last_hash_value=last_hash_value,
|
176
162
|
)
|
177
163
|
|
178
|
-
result:
|
179
|
-
last_compiled_result:
|
164
|
+
result: CompileResult = compile_function(last_hash_value=None)
|
165
|
+
last_compiled_result: CompileResult = result
|
180
166
|
|
181
167
|
if not result.success:
|
182
168
|
print("\nCompilation failed.")
|
183
169
|
|
184
170
|
browser_proc: Process | None = None
|
185
171
|
if open_web_browser:
|
186
|
-
browser_proc = open_browser_process(
|
172
|
+
browser_proc = open_browser_process(directory / "fastled_js")
|
187
173
|
else:
|
188
174
|
print("\nCompilation successful.")
|
189
175
|
if compile_server:
|
@@ -191,21 +177,15 @@ def run_client_server(args: argparse.Namespace) -> int:
|
|
191
177
|
compile_server.stop()
|
192
178
|
return 0
|
193
179
|
|
194
|
-
if
|
195
|
-
if compile_server:
|
196
|
-
compile_server.stop()
|
180
|
+
if not keep_running or shutdown.is_set():
|
197
181
|
if browser_proc:
|
198
182
|
browser_proc.kill()
|
199
183
|
return 0 if result.success else 1
|
200
184
|
except KeyboardInterrupt:
|
201
185
|
print("\nExiting from main")
|
202
|
-
if compile_server:
|
203
|
-
compile_server.stop()
|
204
186
|
return 1
|
205
187
|
|
206
|
-
sketch_filewatcher = FileWatcherProcess(
|
207
|
-
args.directory, excluded_patterns=["fastled_js"]
|
208
|
-
)
|
188
|
+
sketch_filewatcher = FileWatcherProcess(directory, excluded_patterns=["fastled_js"])
|
209
189
|
|
210
190
|
source_code_watcher: FileWatcherProcess | None = None
|
211
191
|
if compile_server and compile_server.using_fastled_src_dir_volume():
|
@@ -215,8 +195,8 @@ def run_client_server(args: argparse.Namespace) -> int:
|
|
215
195
|
)
|
216
196
|
|
217
197
|
def trigger_rebuild_if_sketch_changed(
|
218
|
-
last_compiled_result:
|
219
|
-
) -> tuple[bool,
|
198
|
+
last_compiled_result: CompileResult,
|
199
|
+
) -> tuple[bool, CompileResult]:
|
220
200
|
changed_files = sketch_filewatcher.get_all_changes()
|
221
201
|
if changed_files:
|
222
202
|
print(f"\nChanges detected in {changed_files}")
|
@@ -237,6 +217,9 @@ def run_client_server(args: argparse.Namespace) -> int:
|
|
237
217
|
|
238
218
|
try:
|
239
219
|
while True:
|
220
|
+
if shutdown.is_set():
|
221
|
+
print("\nStopping watch mode...")
|
222
|
+
return 0
|
240
223
|
if SpaceBarWatcher.watch_space_bar_pressed(timeout=1.0):
|
241
224
|
print("Compiling...")
|
242
225
|
last_compiled_result = compile_function(last_hash_value=None)
|
@@ -304,3 +287,59 @@ def run_client_server(args: argparse.Namespace) -> int:
|
|
304
287
|
compile_server.stop()
|
305
288
|
if browser_proc:
|
306
289
|
browser_proc.kill()
|
290
|
+
|
291
|
+
|
292
|
+
def run_client_server(args: argparse.Namespace) -> int:
|
293
|
+
profile = bool(args.profile)
|
294
|
+
web: str | bool = args.web if isinstance(args.web, str) else bool(args.web)
|
295
|
+
auto_update = bool(args.auto_update)
|
296
|
+
localhost = bool(args.localhost)
|
297
|
+
directory = Path(args.directory)
|
298
|
+
just_compile = bool(args.just_compile)
|
299
|
+
interactive = bool(args.interactive)
|
300
|
+
force_compile = bool(args.force_compile)
|
301
|
+
open_web_browser = not just_compile and not interactive
|
302
|
+
build_mode: BuildMode = BuildMode.from_args(args)
|
303
|
+
|
304
|
+
if not force_compile and not looks_like_sketch_directory(directory):
|
305
|
+
print(
|
306
|
+
"Error: Not a valid FastLED sketch directory, if you are sure it is, use --force-compile"
|
307
|
+
)
|
308
|
+
return 1
|
309
|
+
|
310
|
+
# If not explicitly using web compiler, check Docker installation
|
311
|
+
if not web and not DockerManager.is_docker_installed():
|
312
|
+
print(
|
313
|
+
"\nDocker is not installed on this system - switching to web compiler instead."
|
314
|
+
)
|
315
|
+
web = True
|
316
|
+
|
317
|
+
url: str
|
318
|
+
compile_server: CompileServer | None = None
|
319
|
+
try:
|
320
|
+
url, compile_server = _try_start_server_or_get_url(auto_update, web, localhost)
|
321
|
+
except KeyboardInterrupt:
|
322
|
+
print("\nExiting from first try...")
|
323
|
+
if compile_server:
|
324
|
+
compile_server.stop()
|
325
|
+
return 1
|
326
|
+
except Exception as e:
|
327
|
+
print(f"Error: {e}")
|
328
|
+
if compile_server:
|
329
|
+
compile_server.stop()
|
330
|
+
return 1
|
331
|
+
|
332
|
+
try:
|
333
|
+
return run_client(
|
334
|
+
directory=directory,
|
335
|
+
host=compile_server if compile_server else url,
|
336
|
+
open_web_browser=open_web_browser,
|
337
|
+
keep_running=not just_compile,
|
338
|
+
build_mode=build_mode,
|
339
|
+
profile=profile,
|
340
|
+
)
|
341
|
+
except KeyboardInterrupt:
|
342
|
+
return 1
|
343
|
+
finally:
|
344
|
+
if compile_server:
|
345
|
+
compile_server.stop()
|
fastled/compile_server.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
from pathlib import Path
|
2
2
|
|
3
|
-
from fastled.
|
4
|
-
from fastled.types import WebCompileResult
|
3
|
+
from fastled.types import BuildMode, CompileResult, Platform
|
5
4
|
|
6
5
|
|
7
6
|
class CompileServer:
|
7
|
+
|
8
|
+
# May throw CompileServerError if auto_start is True.
|
8
9
|
def __init__(
|
9
10
|
self,
|
10
11
|
interactive: bool = False,
|
@@ -12,11 +13,14 @@ class CompileServer:
|
|
12
13
|
mapped_dir: Path | None = None,
|
13
14
|
auto_start: bool = True,
|
14
15
|
container_name: str | None = None,
|
16
|
+
platform: Platform = Platform.WASM,
|
15
17
|
) -> None:
|
16
18
|
from fastled.compile_server_impl import ( # avoid circular import
|
17
19
|
CompileServerImpl,
|
18
20
|
)
|
19
21
|
|
22
|
+
assert platform == Platform.WASM, "Only WASM platform is supported right now."
|
23
|
+
|
20
24
|
self.impl = CompileServerImpl(
|
21
25
|
container_name=container_name,
|
22
26
|
interactive=interactive,
|
@@ -25,6 +29,7 @@ class CompileServer:
|
|
25
29
|
auto_start=auto_start,
|
26
30
|
)
|
27
31
|
|
32
|
+
# May throw CompileServerError if server could not be started.
|
28
33
|
def start(self, wait_for_startup=True) -> None:
|
29
34
|
# from fastled.compile_server_impl import CompileServerImpl # avoid circular import
|
30
35
|
self.impl.start(wait_for_startup=wait_for_startup)
|
@@ -34,7 +39,7 @@ class CompileServer:
|
|
34
39
|
directory: Path | str,
|
35
40
|
build_mode: BuildMode = BuildMode.QUICK,
|
36
41
|
profile: bool = False,
|
37
|
-
) ->
|
42
|
+
) -> CompileResult:
|
38
43
|
return self.impl.web_compile(
|
39
44
|
directory=directory, build_mode=build_mode, profile=profile
|
40
45
|
)
|
fastled/compile_server_impl.py
CHANGED
@@ -6,7 +6,6 @@ from pathlib import Path
|
|
6
6
|
|
7
7
|
import httpx
|
8
8
|
|
9
|
-
from fastled.build_mode import BuildMode
|
10
9
|
from fastled.docker_manager import (
|
11
10
|
DISK_CACHE,
|
12
11
|
Container,
|
@@ -15,13 +14,27 @@ from fastled.docker_manager import (
|
|
15
14
|
)
|
16
15
|
from fastled.settings import SERVER_PORT
|
17
16
|
from fastled.sketch import looks_like_fastled_repo
|
18
|
-
from fastled.types import
|
17
|
+
from fastled.types import BuildMode, CompileResult, CompileServerError
|
19
18
|
|
20
19
|
_IMAGE_NAME = "niteris/fastled-wasm"
|
21
20
|
_DEFAULT_CONTAINER_NAME = "fastled-wasm-compiler"
|
22
21
|
|
23
22
|
|
24
|
-
SERVER_OPTIONS = [
|
23
|
+
SERVER_OPTIONS = [
|
24
|
+
"--allow-shutdown", # Allow the server to be shut down without a force kill.
|
25
|
+
"--no-auto-update", # Don't auto live updates from the git repo.
|
26
|
+
]
|
27
|
+
|
28
|
+
|
29
|
+
def _try_get_fastled_src(path: Path) -> Path | None:
|
30
|
+
fastled_src_dir: Path | None = None
|
31
|
+
if looks_like_fastled_repo(path):
|
32
|
+
print(
|
33
|
+
"Looks like a FastLED repo, using it as the source directory and mapping it into the server."
|
34
|
+
)
|
35
|
+
fastled_src_dir = path / "src"
|
36
|
+
return fastled_src_dir
|
37
|
+
return None
|
25
38
|
|
26
39
|
|
27
40
|
class CompileServerImpl:
|
@@ -40,52 +53,46 @@ class CompileServerImpl:
|
|
40
53
|
)
|
41
54
|
if not interactive and mapped_dir:
|
42
55
|
raise ValueError("Mapped directory is only used in interactive mode")
|
43
|
-
cwd = Path(".").resolve()
|
44
|
-
fastled_src_dir: Path | None = None
|
45
|
-
if looks_like_fastled_repo(cwd):
|
46
|
-
print(
|
47
|
-
"Looks like a FastLED repo, using it as the source directory and mapping it into the server."
|
48
|
-
)
|
49
|
-
fastled_src_dir = cwd / "src"
|
50
|
-
|
51
56
|
self.container_name = container_name
|
52
57
|
self.mapped_dir = mapped_dir
|
53
58
|
self.docker = DockerManager()
|
54
|
-
self.fastled_src_dir: Path | None =
|
59
|
+
self.fastled_src_dir: Path | None = _try_get_fastled_src(Path(".").resolve())
|
55
60
|
self.interactive = interactive
|
56
61
|
self.running_container: RunningContainer | None = None
|
57
62
|
self.auto_updates = auto_updates
|
58
|
-
# self._port = self._start()
|
59
63
|
self._port = 0 # 0 until compile server is started
|
60
|
-
# fancy print
|
61
|
-
if not interactive:
|
62
|
-
msg = f"# FastLED Compile Server started at {self.url()} #"
|
63
|
-
print("\n" + "#" * len(msg))
|
64
|
-
print(msg)
|
65
|
-
print("#" * len(msg) + "\n")
|
66
64
|
if auto_start:
|
67
65
|
self.start()
|
68
66
|
|
69
67
|
def start(self, wait_for_startup=True) -> None:
|
68
|
+
if not DockerManager.is_docker_installed():
|
69
|
+
raise CompileServerError("Docker is not installed")
|
70
70
|
if self._port != 0:
|
71
71
|
warnings.warn("Server has already been started")
|
72
72
|
self._port = self._start()
|
73
73
|
if wait_for_startup:
|
74
|
-
self.wait_for_startup()
|
74
|
+
ok = self.wait_for_startup()
|
75
|
+
if not ok:
|
76
|
+
raise CompileServerError("Server did not start")
|
77
|
+
if not self.interactive:
|
78
|
+
msg = f"# FastLED Compile Server started at {self.url()} #"
|
79
|
+
print("\n" + "#" * len(msg))
|
80
|
+
print(msg)
|
81
|
+
print("#" * len(msg) + "\n")
|
75
82
|
|
76
83
|
def web_compile(
|
77
84
|
self,
|
78
85
|
directory: Path | str,
|
79
86
|
build_mode: BuildMode = BuildMode.QUICK,
|
80
87
|
profile: bool = False,
|
81
|
-
) ->
|
88
|
+
) -> CompileResult:
|
82
89
|
from fastled.web_compile import web_compile # avoid circular import
|
83
90
|
|
84
91
|
if not self._port:
|
85
92
|
raise RuntimeError("Server has not been started yet")
|
86
93
|
if not self.ping():
|
87
94
|
raise RuntimeError("Server is not running")
|
88
|
-
out:
|
95
|
+
out: CompileResult = web_compile(
|
89
96
|
directory, host=self.url(), build_mode=build_mode, profile=profile
|
90
97
|
)
|
91
98
|
return out
|
fastled/live_client.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
import threading
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
from fastled.compile_server import CompileServer
|
5
|
+
from fastled.types import BuildMode
|
6
|
+
|
7
|
+
|
8
|
+
class LiveClient:
|
9
|
+
"""LiveClient class watches for changes and auto-triggeres rebuild."""
|
10
|
+
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
sketch_directory: Path,
|
14
|
+
host: str | CompileServer | None = None,
|
15
|
+
auto_start: bool = True,
|
16
|
+
open_web_browser: bool = True,
|
17
|
+
keep_running: bool = True,
|
18
|
+
build_mode: BuildMode = BuildMode.QUICK,
|
19
|
+
profile: bool = False,
|
20
|
+
) -> None:
|
21
|
+
self.sketch_directory = sketch_directory
|
22
|
+
self.host = host
|
23
|
+
self.open_web_browser = open_web_browser
|
24
|
+
self.keep_running = keep_running
|
25
|
+
self.build_mode = build_mode
|
26
|
+
self.profile = profile
|
27
|
+
self.auto_start = auto_start
|
28
|
+
self.shutdown = threading.Event()
|
29
|
+
self.thread: threading.Thread | None = None
|
30
|
+
if auto_start:
|
31
|
+
self.start()
|
32
|
+
|
33
|
+
def run(self) -> int:
|
34
|
+
"""Run the client."""
|
35
|
+
from fastled.client_server import run_client # avoid circular import
|
36
|
+
|
37
|
+
rtn = run_client(
|
38
|
+
directory=self.sketch_directory,
|
39
|
+
host=self.host,
|
40
|
+
open_web_browser=self.open_web_browser,
|
41
|
+
keep_running=self.keep_running,
|
42
|
+
build_mode=self.build_mode,
|
43
|
+
profile=self.profile,
|
44
|
+
shutdown=self.shutdown,
|
45
|
+
)
|
46
|
+
return rtn
|
47
|
+
|
48
|
+
@property
|
49
|
+
def running(self) -> bool:
|
50
|
+
return self.thread is not None and self.thread.is_alive()
|
51
|
+
|
52
|
+
def start(self) -> None:
|
53
|
+
"""Start the client."""
|
54
|
+
assert not self.running, "LiveClient is already running"
|
55
|
+
self.shutdown.clear()
|
56
|
+
self.thread = threading.Thread(target=self.run, daemon=True)
|
57
|
+
self.thread.start()
|
58
|
+
|
59
|
+
def stop(self) -> None:
|
60
|
+
"""Stop the client."""
|
61
|
+
self.shutdown.set()
|
62
|
+
if self.thread:
|
63
|
+
self.thread.join()
|
64
|
+
self.thread = None
|
65
|
+
|
66
|
+
def finalize(self) -> None:
|
67
|
+
"""Finalize the client."""
|
68
|
+
self.stop()
|
69
|
+
self.thread = None
|
fastled/types.py
CHANGED
@@ -1,18 +1,11 @@
|
|
1
|
+
import argparse
|
1
2
|
from dataclasses import dataclass
|
3
|
+
from enum import Enum
|
2
4
|
from typing import Any
|
3
5
|
|
4
6
|
|
5
7
|
@dataclass
|
6
|
-
class
|
7
|
-
"""Dataclass to hold the result of the compilation."""
|
8
|
-
|
9
|
-
success: bool
|
10
|
-
fastled_js: str
|
11
|
-
hash_value: str | None
|
12
|
-
|
13
|
-
|
14
|
-
@dataclass
|
15
|
-
class WebCompileResult:
|
8
|
+
class CompileResult:
|
16
9
|
success: bool
|
17
10
|
stdout: str
|
18
11
|
hash_value: str | None
|
@@ -23,3 +16,46 @@ class WebCompileResult:
|
|
23
16
|
|
24
17
|
def to_dict(self) -> dict[str, Any]:
|
25
18
|
return self.__dict__.copy()
|
19
|
+
|
20
|
+
|
21
|
+
class CompileServerError(Exception):
|
22
|
+
"""Error class for failing to instantiate CompileServer."""
|
23
|
+
|
24
|
+
pass
|
25
|
+
|
26
|
+
|
27
|
+
class BuildMode(Enum):
|
28
|
+
DEBUG = "DEBUG"
|
29
|
+
QUICK = "QUICK"
|
30
|
+
RELEASE = "RELEASE"
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
def from_string(cls, mode_str: str) -> "BuildMode":
|
34
|
+
try:
|
35
|
+
return cls[mode_str.upper()]
|
36
|
+
except KeyError:
|
37
|
+
valid_modes = [mode.name for mode in cls]
|
38
|
+
raise ValueError(f"BUILD_MODE must be one of {valid_modes}, got {mode_str}")
|
39
|
+
|
40
|
+
@staticmethod
|
41
|
+
def from_args(args: argparse.Namespace) -> "BuildMode":
|
42
|
+
if args.debug:
|
43
|
+
return BuildMode.DEBUG
|
44
|
+
elif args.release:
|
45
|
+
return BuildMode.RELEASE
|
46
|
+
else:
|
47
|
+
return BuildMode.QUICK
|
48
|
+
|
49
|
+
|
50
|
+
class Platform(Enum):
|
51
|
+
WASM = "WASM"
|
52
|
+
|
53
|
+
@classmethod
|
54
|
+
def from_string(cls, platform_str: str) -> "Platform":
|
55
|
+
try:
|
56
|
+
return cls[platform_str.upper()]
|
57
|
+
except KeyError:
|
58
|
+
valid_modes = [mode.name for mode in cls]
|
59
|
+
raise ValueError(
|
60
|
+
f"Platform must be one of {valid_modes}, got {platform_str}"
|
61
|
+
)
|
fastled/web_compile.py
CHANGED
@@ -11,10 +11,9 @@ from pathlib import Path
|
|
11
11
|
|
12
12
|
import httpx
|
13
13
|
|
14
|
-
from fastled.build_mode import BuildMode
|
15
14
|
from fastled.settings import SERVER_PORT
|
16
15
|
from fastled.sketch import get_sketch_files
|
17
|
-
from fastled.types import
|
16
|
+
from fastled.types import BuildMode, CompileResult
|
18
17
|
from fastled.util import hash_file
|
19
18
|
|
20
19
|
DEFAULT_HOST = "https://fastled.onrender.com"
|
@@ -160,7 +159,7 @@ def web_compile(
|
|
160
159
|
auth_token: str | None = None,
|
161
160
|
build_mode: BuildMode | None = None,
|
162
161
|
profile: bool = False,
|
163
|
-
) ->
|
162
|
+
) -> CompileResult:
|
164
163
|
if isinstance(directory, str):
|
165
164
|
directory = Path(directory)
|
166
165
|
host = _sanitize_host(host or DEFAULT_HOST)
|
@@ -171,7 +170,7 @@ def web_compile(
|
|
171
170
|
raise FileNotFoundError(f"Directory not found: {directory}")
|
172
171
|
zip_result = zip_files(directory, build_mode=build_mode)
|
173
172
|
if isinstance(zip_result, Exception):
|
174
|
-
return
|
173
|
+
return CompileResult(
|
175
174
|
success=False, stdout=str(zip_result), hash_value=None, zip_bytes=b""
|
176
175
|
)
|
177
176
|
zip_bytes = zip_result.zip_bytes
|
@@ -187,7 +186,7 @@ def web_compile(
|
|
187
186
|
connection_result = find_good_connection(urls)
|
188
187
|
if connection_result is None:
|
189
188
|
print("Connection failed to all endpoints")
|
190
|
-
return
|
189
|
+
return CompileResult(
|
191
190
|
success=False,
|
192
191
|
stdout="Connection failed",
|
193
192
|
hash_value=None,
|
@@ -229,7 +228,7 @@ def web_compile(
|
|
229
228
|
if response.status_code != 200:
|
230
229
|
json_response = response.json()
|
231
230
|
detail = json_response.get("detail", "Could not compile")
|
232
|
-
return
|
231
|
+
return CompileResult(
|
233
232
|
success=False, stdout=detail, hash_value=None, zip_bytes=b""
|
234
233
|
)
|
235
234
|
|
@@ -270,7 +269,7 @@ def web_compile(
|
|
270
269
|
relative_path = file_path.relative_to(extract_path)
|
271
270
|
out_zip.write(file_path, relative_path)
|
272
271
|
|
273
|
-
return
|
272
|
+
return CompileResult(
|
274
273
|
success=True,
|
275
274
|
stdout=stdout,
|
276
275
|
hash_value=hash_value,
|
@@ -281,6 +280,6 @@ def web_compile(
|
|
281
280
|
raise
|
282
281
|
except httpx.HTTPError as e:
|
283
282
|
print(f"Error: {e}")
|
284
|
-
return
|
283
|
+
return CompileResult(
|
285
284
|
success=False, stdout=str(e), hash_value=None, zip_bytes=b""
|
286
285
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.39
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -61,60 +61,155 @@ pip install fastled
|
|
61
61
|
|
62
62
|
**Note that you may need to install x86 docker emulation on Mac-m1 and later, as this is an x86 only image at the prsent.**
|
63
63
|
|
64
|
-
# Use
|
64
|
+
# Command Line Use
|
65
65
|
|
66
66
|
Change to the directory where the sketch lives and run, will run the compilation
|
67
67
|
on the web compiler.
|
68
68
|
|
69
69
|
```bash
|
70
|
+
# This will use the web-compiler, unless you have docker installed in which case a local
|
71
|
+
# server will be instantiated automatically.
|
70
72
|
cd <SKETCH-DIRECTORY>
|
71
73
|
fastled
|
72
74
|
```
|
73
75
|
|
74
|
-
|
76
|
+
Forces the local server to to spawn in order to run to do the compile.
|
75
77
|
|
76
78
|
```bash
|
77
79
|
cd <SKETCH-DIRECTORY>
|
78
|
-
fastled --local
|
80
|
+
fastled --local # if server doesn't already exist, one is created.
|
79
81
|
```
|
80
82
|
|
81
83
|
You can also spawn a server in one process and then access it in another, like this:
|
82
84
|
|
83
85
|
```bash
|
84
|
-
fastled --server
|
86
|
+
fastled --server # server will now run in the background.
|
85
87
|
# now launch the client
|
86
|
-
fastled examples/wasm --local
|
88
|
+
fastled examples/wasm --local # local will find the local server use it do the compile.
|
87
89
|
```
|
88
90
|
|
89
91
|
After compilation a web browser windows will pop up. Changes to the sketch will automatically trigger a recompilation.
|
90
92
|
|
91
|
-
#
|
93
|
+
# Python Api
|
94
|
+
|
95
|
+
**Compiling through the api**
|
96
|
+
```python
|
97
|
+
|
98
|
+
from fastapi import Api, CompileResult
|
99
|
+
|
100
|
+
out: CompileResult = Api.web_compile("path/to/sketch")
|
101
|
+
print(out.success)
|
102
|
+
print(out.stdout)
|
103
|
+
|
104
|
+
```
|
105
|
+
|
106
|
+
**Launching a compile server**
|
107
|
+
```python
|
108
|
+
|
109
|
+
from fastapi import Api, CompileServer
|
110
|
+
|
111
|
+
server: CompileServer = Api.spawn_server()
|
112
|
+
print(f"Local server running at {server.url()}")
|
113
|
+
server.web_compile("path/to/sketch") # output will be "path/to/sketch/fastled_js"
|
114
|
+
server.stop()
|
115
|
+
```
|
116
|
+
|
117
|
+
**Launching a server in a scope**
|
118
|
+
```python
|
119
|
+
|
120
|
+
from fastapi import Api
|
121
|
+
|
122
|
+
# Launching a server in a scope
|
123
|
+
with Api.server() as server:
|
124
|
+
server.web_compile("path/to/sketch")
|
125
|
+
|
126
|
+
```
|
127
|
+
|
128
|
+
**Initializing a project example from the web compiler**
|
129
|
+
```python
|
130
|
+
|
131
|
+
from fastapi import Api
|
132
|
+
|
133
|
+
examples = Api.get_examples()
|
134
|
+
print(f"Print available examples: {examples}")
|
135
|
+
Api.project_init(examples[0])
|
136
|
+
|
137
|
+
|
138
|
+
```
|
139
|
+
|
140
|
+
**Initializing a project example from the CompileServer**
|
141
|
+
```python
|
142
|
+
|
143
|
+
from fastapi import Api
|
144
|
+
|
145
|
+
with Api.server() as server:
|
146
|
+
examples = server.get_examples()
|
147
|
+
server.project_init(examples[0])
|
148
|
+
|
149
|
+
```
|
150
|
+
|
151
|
+
**LiveClient will auto-trigger a build on code changes, just like the cli does**
|
152
|
+
```python
|
153
|
+
|
154
|
+
# Live Client will compile against the web-compiler
|
155
|
+
from fastapi import Api, LiveClient
|
156
|
+
client: LiveClient = Api.live_client(
|
157
|
+
"path/to/sketch_directory",
|
158
|
+
)
|
159
|
+
# Now user can start editing their sketch and it will auto-compile
|
160
|
+
# ... after a while stop it like this.
|
161
|
+
client.stop()
|
162
|
+
```
|
163
|
+
|
164
|
+
**LiveClient with local CompileServer**
|
165
|
+
```python
|
166
|
+
|
167
|
+
# Live Client will compile against a local server.
|
168
|
+
from fastapi import Api, LiveClient
|
169
|
+
|
170
|
+
with Api.server() as server:
|
171
|
+
client: LiveClient = Api.live_client(
|
172
|
+
"path/to/sketch_directory",
|
173
|
+
host=server
|
174
|
+
)
|
175
|
+
# Now user can start editing their sketch and it will auto-compile
|
176
|
+
# ... after a while stop it like this.
|
177
|
+
client.stop()
|
178
|
+
```
|
179
|
+
|
180
|
+
# Features
|
181
|
+
|
182
|
+
## Hot reload by default
|
92
183
|
|
93
184
|
Once launched, the compiler will remain open, listening to changes and recompiling as necessary and hot-reloading the sketch into the current browser.
|
94
185
|
|
95
186
|
This style of development should be familiar to those doing web development.
|
96
187
|
|
97
|
-
|
188
|
+
## Hot Reload fastled/src when working in the FastLED repo
|
98
189
|
|
99
190
|
If you launch `fastled` in the FastLED repo then this tool will automatically detect this and map the src directory into the
|
100
191
|
host container. Whenever there are changes in the source code from the mapped directory, then these will be re-compiled
|
101
192
|
on the next change or if you hit the space bar when prompted. Unlike a sketch folder, a re-compile on the FastLED src
|
102
193
|
can be much longer, for example if you modify a header file.
|
103
194
|
|
104
|
-
|
195
|
+
## Big Data in `/data` directory won't be round-tripped
|
105
196
|
|
106
197
|
Huge blobs of data like video will absolutely kill the compile performance as these blobs would normally have to be shuffled
|
107
198
|
back and forth. Therefore a special directory `data/` is implicitly used to hold this blob data. Any data in this directory
|
108
199
|
will be replaced with a stub containing the size and hash of the file during upload. On download these stubs are swapped back
|
109
|
-
with their originals.
|
200
|
+
with their originals during decompression.
|
110
201
|
|
111
202
|
The wasm compiler will recognize all files in the `data/` directory and generate a `files.json` manifest and can be used
|
112
203
|
in your wasm sketch using an emulated SD card system mounted at `/data/` on the SD Card. In order to increase load speed, these
|
113
|
-
files will be asynchroniously streamed into the running sketch instance during runtime.
|
204
|
+
files will be asynchroniously streamed into the running sketch instance during runtime. Files named with *.json, *.csv, *.txt will be
|
205
|
+
immediately injected in the app before setup() is called and can be used immediatly in setup() in their entirety.
|
206
|
+
|
207
|
+
All other files will be streamed in. The `Video` element in FastLED is designed to gracefully handle missing data streamed in through
|
208
|
+
the file system.
|
114
209
|
|
115
210
|
For an example of how to use this see `examples/SdCard` which is fully wasm compatible.
|
116
211
|
|
117
|
-
|
212
|
+
## Compile Speed
|
118
213
|
|
119
214
|
The compile speeds for this compiler have been optimized pretty much to the max. There are three compile settings available to the user. The default is `--quick`. Aggressive optimizations are done with `--release` which will aggressively optimize for size. The speed difference between `--release` and `--quick` seems negligable. But `--release` will produce a ~1/3 smaller binary. There is also `--debug`, which will include symbols necessary for debugging and getting the C++ function symbols working correctly in the browser during step through debugging. It works better than expected, but don't expect to have gdb or msvc debugger level of debugging experience.
|
120
215
|
|
@@ -122,24 +217,22 @@ We use `ccache` to cache object files. This seems actually help a lot and is bet
|
|
122
217
|
|
123
218
|
The compilation to wasm will happen under a lock. Removing this lock requires removing the platformio toolchain as the compiler backend which enforces it's own internal lock preventing parallel use.
|
124
219
|
|
125
|
-
|
126
|
-
|
127
|
-
# Sketch Cache
|
220
|
+
## Sketch Cache
|
128
221
|
|
129
|
-
Sketchs are
|
222
|
+
Sketchs are aggressively finger-printed and stored in a cache. White space, comments, and other superficial data will be stripped out during pre-processing and minimization for fingerprinting. This source file decimation is only used for finger
|
130
223
|
printing while the actual source files are sent to compiler to preserve line numbers and file names.
|
131
224
|
|
132
225
|
This pre-processing done is done via gcc and special regex's and will happen without a lock. This will allow you to have extremely quick recompiles for whitespace and changes in comments even if the compiler is executing under it's lock.
|
133
226
|
|
134
|
-
|
227
|
+
## Local compiles
|
135
228
|
|
136
229
|
If the web-compiler get's congested then it's recommend that you run the compiler locally. This requires docker and will be invoked whenever you pass in `--local`. This will first pull the most recent Docker image of the Fastled compiler, launching a webserver and then connecting to it with the client once it's been up.
|
137
230
|
|
138
|
-
|
231
|
+
## Auto updates
|
139
232
|
|
140
233
|
In server mode the git repository will be cloned as a side repo and then periodically updated and rsync'd to the src directory. This allows a long running instance to stay updated.
|
141
234
|
|
142
|
-
|
235
|
+
## Compatibility with Arduino sketchs
|
143
236
|
|
144
237
|
The compatibility is actually pretty good. Most simple sketchs should compile out of the box. Even some of the avr platform includes are stubbed out to make it work. The familiar `digitalWrite()`, `Serial.println()` and other common functions work. Although `digitalRead()` will always return 0 and `analogRead()` will return random numbers.
|
145
238
|
|
@@ -163,6 +256,8 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` is
|
|
163
256
|
|
164
257
|
# Revisions
|
165
258
|
|
259
|
+
* 1.1.39 - Added `LiveClient`, `fastled.Api.live_server()` will spawn it. Allows user to have a live compiling client that re-triggers a compile on file changes.
|
260
|
+
* 1.1.38 - Cleanup the `fastled.Api` object and streamline for general use.
|
166
261
|
* 1.1.37 - `Test.test_examples()` is now unit tested to work correctly.
|
167
262
|
* 1.1.36 - We now have an api. `from fastled import Api` and `from fastled import Test` for testing.
|
168
263
|
* 1.1.35 - When searching for files cap the limit at a high amount to prevent hang.
|
@@ -1,13 +1,13 @@
|
|
1
|
-
fastled/__init__.py,sha256=
|
1
|
+
fastled/__init__.py,sha256=SQF8-PpioJm6DAQn5vCcc-muwXHBfs0loIofSRoWK8g,3613
|
2
2
|
fastled/app.py,sha256=3xg7oVD-UYnKPU8SAY-Cs5UnAYdwpdpuEFRR2N8P1Tg,1787
|
3
|
-
fastled/build_mode.py,sha256=joMwsV4K1y_LijT4gEAcjx69RZBoe_KmFmHZdPYbL_4,631
|
4
3
|
fastled/cli.py,sha256=CNR_pQR0sNVPNuv8e_nmm-0PI8sU-eUBUgnWgWkzW9c,237
|
5
|
-
fastled/client_server.py,sha256=
|
6
|
-
fastled/compile_server.py,sha256=
|
7
|
-
fastled/compile_server_impl.py,sha256=
|
4
|
+
fastled/client_server.py,sha256=KQsBKjHfkhgF5EOCHSbJcqu0dPKlOCsbXA2V035VCH0,12403
|
5
|
+
fastled/compile_server.py,sha256=Z7rHFs3M6QPbSCsbgHAQDk6GTVAJMMPCXtD4Y0mu8RM,2659
|
6
|
+
fastled/compile_server_impl.py,sha256=ClBLtFHB0ucaT8tAJfI6o3bJ-LRnXc4Pxy7bVKnFiww,8803
|
8
7
|
fastled/docker_manager.py,sha256=zBCFGk2P3_bS7_SUQ5j2lpsOS3RvIzXYkrJXC6xP69k,25383
|
9
8
|
fastled/filewatcher.py,sha256=LwEQJkqADsArZyY499RLAer6JjJyDwaQBcAvT7xmp3c,6708
|
10
9
|
fastled/keyboard.py,sha256=Zz_ggxOUTX2XQEy6K6kAoorVlUev4wEk9Awpvv9aStA,3241
|
10
|
+
fastled/live_client.py,sha256=_KvqmyUyyGpoYET1Z9CdeUVoIbFjIUWwPcTp5XCQuxY,2075
|
11
11
|
fastled/open_browser.py,sha256=vzMBcpDNY0f-Bx9KmEILKDANZ6gvsywCVwn1FRhPXh4,1770
|
12
12
|
fastled/parse_args.py,sha256=37WsELphNEqGQgmjppZx6uMWE2E-dZ58zCKUl-3mr3Q,6150
|
13
13
|
fastled/paths.py,sha256=VsPmgu0lNSCFOoEC0BsTYzDygXqy15AHUfN-tTuzDZA,99
|
@@ -17,14 +17,14 @@ fastled/settings.py,sha256=3eMKv0tLXgIQ0CFDboIp_l5_71rzIIyWg353YjnYJnc,323
|
|
17
17
|
fastled/sketch.py,sha256=483TrrIdZJfo1MIu5FkD-V5OGmOfHmsZ2f6VvNsJBJM,3299
|
18
18
|
fastled/spinner.py,sha256=VHxmvB92P0Z_zYxRajb5HiNmkHHvZ5dG7hKtZltzpcs,867
|
19
19
|
fastled/string_diff.py,sha256=UR1oRhg9lsPzAG4bn_MwJMCn0evP5AigkBiwLiI9fgA,1354
|
20
|
-
fastled/types.py,sha256=
|
20
|
+
fastled/types.py,sha256=PpSEtzFCkWtSIEMC0QXGl966R97vLoryVl3yFW0YhTs,1475
|
21
21
|
fastled/util.py,sha256=t4M3NFMhnCzfYbLvIyJi0RdFssZqbTN_vVIaej1WV-U,265
|
22
|
-
fastled/web_compile.py,sha256=
|
22
|
+
fastled/web_compile.py,sha256=05PeLJ77QQC6PUKjDhsntBmyBola6QQIfF2k-zjYNE4,10261
|
23
23
|
fastled/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
24
24
|
fastled/test/examples.py,sha256=EDXb6KastKOOWzew99zrpmcNcXTcAtYi8eud6F1pnWA,980
|
25
|
-
fastled-1.1.
|
26
|
-
fastled-1.1.
|
27
|
-
fastled-1.1.
|
28
|
-
fastled-1.1.
|
29
|
-
fastled-1.1.
|
30
|
-
fastled-1.1.
|
25
|
+
fastled-1.1.39.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
26
|
+
fastled-1.1.39.dist-info/METADATA,sha256=a-iU6xg5tbGNPN-2l0Bydnk3Xax9-jfWAFV7ltioC6U,17889
|
27
|
+
fastled-1.1.39.dist-info/WHEEL,sha256=0VNUDWQJzfRahYI3neAhz2UVbRCtztpN5dPHAGvmGXc,109
|
28
|
+
fastled-1.1.39.dist-info/entry_points.txt,sha256=RCwmzCSOS4-C2i9EziANq7Z2Zb4KFnEMR1FQC0bBwAw,101
|
29
|
+
fastled-1.1.39.dist-info/top_level.txt,sha256=Bbv5kpJpZhWNCvDF4K0VcvtBSDMa8B7PTOrZa9CezHY,8
|
30
|
+
fastled-1.1.39.dist-info/RECORD,,
|
fastled/build_mode.py
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
import argparse
|
2
|
-
from enum import Enum
|
3
|
-
|
4
|
-
|
5
|
-
class BuildMode(Enum):
|
6
|
-
DEBUG = "DEBUG"
|
7
|
-
QUICK = "QUICK"
|
8
|
-
RELEASE = "RELEASE"
|
9
|
-
|
10
|
-
@classmethod
|
11
|
-
def from_string(cls, mode_str: str) -> "BuildMode":
|
12
|
-
try:
|
13
|
-
return cls[mode_str.upper()]
|
14
|
-
except KeyError:
|
15
|
-
valid_modes = [mode.name for mode in cls]
|
16
|
-
raise ValueError(f"BUILD_MODE must be one of {valid_modes}, got {mode_str}")
|
17
|
-
|
18
|
-
|
19
|
-
def get_build_mode(args: argparse.Namespace) -> BuildMode:
|
20
|
-
if args.debug:
|
21
|
-
return BuildMode.DEBUG
|
22
|
-
elif args.release:
|
23
|
-
return BuildMode.RELEASE
|
24
|
-
else:
|
25
|
-
return BuildMode.QUICK
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|