fastled 1.0.8__py2.py3-none-any.whl → 1.0.10__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 +1 -1
- fastled/app.py +383 -376
- fastled/filewatcher.py +169 -146
- fastled/util.py +10 -0
- fastled/web_compile.py +277 -227
- {fastled-1.0.8.dist-info → fastled-1.0.10.dist-info}/METADATA +4 -1
- fastled-1.0.10.dist-info/RECORD +20 -0
- fastled-1.0.8.dist-info/RECORD +0 -19
- {fastled-1.0.8.dist-info → fastled-1.0.10.dist-info}/LICENSE +0 -0
- {fastled-1.0.8.dist-info → fastled-1.0.10.dist-info}/WHEEL +0 -0
- {fastled-1.0.8.dist-info → fastled-1.0.10.dist-info}/entry_points.txt +0 -0
- {fastled-1.0.8.dist-info → fastled-1.0.10.dist-info}/top_level.txt +0 -0
fastled/app.py
CHANGED
@@ -1,376 +1,383 @@
|
|
1
|
-
"""
|
2
|
-
Uses the latest wasm compiler image to compile the FastLED sketch.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import argparse
|
6
|
-
import os
|
7
|
-
import platform
|
8
|
-
import shutil
|
9
|
-
import subprocess
|
10
|
-
import sys
|
11
|
-
import tempfile
|
12
|
-
import time
|
13
|
-
from dataclasses import dataclass
|
14
|
-
from pathlib import Path
|
15
|
-
|
16
|
-
from fastled import __version__
|
17
|
-
from fastled.build_mode import BuildMode, get_build_mode
|
18
|
-
from fastled.compile_server import CompileServer
|
19
|
-
from fastled.docker_manager import DockerManager
|
20
|
-
from fastled.filewatcher import
|
21
|
-
from fastled.open_browser import open_browser_thread
|
22
|
-
from fastled.sketch import looks_like_sketch_directory
|
23
|
-
from fastled.web_compile import web_compile
|
24
|
-
|
25
|
-
machine = platform.machine().lower()
|
26
|
-
IS_ARM: bool = "arm" in machine or "aarch64" in machine
|
27
|
-
PLATFORM_TAG: str = "-arm64" if IS_ARM else ""
|
28
|
-
CONTAINER_NAME = f"fastled-wasm-compiler{PLATFORM_TAG}"
|
29
|
-
DEFAULT_URL = "https://fastled.onrender.com"
|
30
|
-
|
31
|
-
|
32
|
-
@dataclass
|
33
|
-
class CompiledResult:
|
34
|
-
"""Dataclass to hold the result of the compilation."""
|
35
|
-
|
36
|
-
success: bool
|
37
|
-
fastled_js: str
|
38
|
-
hash_value: str | None
|
39
|
-
|
40
|
-
|
41
|
-
DOCKER = DockerManager(container_name=CONTAINER_NAME)
|
42
|
-
|
43
|
-
|
44
|
-
def parse_args() -> argparse.Namespace:
|
45
|
-
"""Parse command-line arguments."""
|
46
|
-
parser = argparse.ArgumentParser(description=f"FastLED WASM Compiler {__version__}")
|
47
|
-
parser.add_argument(
|
48
|
-
"--version", action="version", version=f"%(prog)s {__version__}"
|
49
|
-
)
|
50
|
-
parser.add_argument(
|
51
|
-
"directory",
|
52
|
-
type=str,
|
53
|
-
nargs="?",
|
54
|
-
default=None,
|
55
|
-
help="Directory containing the FastLED sketch to compile",
|
56
|
-
)
|
57
|
-
parser.add_argument(
|
58
|
-
"--just-compile",
|
59
|
-
action="store_true",
|
60
|
-
help="Just compile, skip opening the browser and watching for changes.",
|
61
|
-
)
|
62
|
-
parser.add_argument(
|
63
|
-
"--web",
|
64
|
-
"-w",
|
65
|
-
type=str,
|
66
|
-
nargs="?",
|
67
|
-
# const does not seem to be working as expected
|
68
|
-
const=DEFAULT_URL, # Default value when --web is specified without value
|
69
|
-
help="Use web compiler. Optional URL can be provided (default: https://fastled.onrender.com)",
|
70
|
-
)
|
71
|
-
parser.add_argument(
|
72
|
-
"-i",
|
73
|
-
"--interactive",
|
74
|
-
action="store_true",
|
75
|
-
help="Run in interactive mode (Not available with --web)",
|
76
|
-
)
|
77
|
-
parser.add_argument(
|
78
|
-
"--profile",
|
79
|
-
action="store_true",
|
80
|
-
help="Enable profiling for web compilation",
|
81
|
-
)
|
82
|
-
build_mode = parser.add_mutually_exclusive_group()
|
83
|
-
build_mode.add_argument("--debug", action="store_true", help="Build in debug mode")
|
84
|
-
build_mode.add_argument(
|
85
|
-
"--quick",
|
86
|
-
action="store_true",
|
87
|
-
default=True,
|
88
|
-
help="Build in quick mode (default)",
|
89
|
-
)
|
90
|
-
build_mode.add_argument(
|
91
|
-
"--release", action="store_true", help="Build in release mode"
|
92
|
-
)
|
93
|
-
build_mode.add_argument(
|
94
|
-
"--
|
95
|
-
action="store_true",
|
96
|
-
help="
|
97
|
-
)
|
98
|
-
|
99
|
-
|
100
|
-
"
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
)
|
147
|
-
print(
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
return
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
if
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
return
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
)
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
sys.
|
1
|
+
"""
|
2
|
+
Uses the latest wasm compiler image to compile the FastLED sketch.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import argparse
|
6
|
+
import os
|
7
|
+
import platform
|
8
|
+
import shutil
|
9
|
+
import subprocess
|
10
|
+
import sys
|
11
|
+
import tempfile
|
12
|
+
import time
|
13
|
+
from dataclasses import dataclass
|
14
|
+
from pathlib import Path
|
15
|
+
|
16
|
+
from fastled import __version__
|
17
|
+
from fastled.build_mode import BuildMode, get_build_mode
|
18
|
+
from fastled.compile_server import CompileServer
|
19
|
+
from fastled.docker_manager import DockerManager
|
20
|
+
from fastled.filewatcher import create_file_watcher_process
|
21
|
+
from fastled.open_browser import open_browser_thread
|
22
|
+
from fastled.sketch import looks_like_sketch_directory
|
23
|
+
from fastled.web_compile import web_compile
|
24
|
+
|
25
|
+
machine = platform.machine().lower()
|
26
|
+
IS_ARM: bool = "arm" in machine or "aarch64" in machine
|
27
|
+
PLATFORM_TAG: str = "-arm64" if IS_ARM else ""
|
28
|
+
CONTAINER_NAME = f"fastled-wasm-compiler{PLATFORM_TAG}"
|
29
|
+
DEFAULT_URL = "https://fastled.onrender.com"
|
30
|
+
|
31
|
+
|
32
|
+
@dataclass
|
33
|
+
class CompiledResult:
|
34
|
+
"""Dataclass to hold the result of the compilation."""
|
35
|
+
|
36
|
+
success: bool
|
37
|
+
fastled_js: str
|
38
|
+
hash_value: str | None
|
39
|
+
|
40
|
+
|
41
|
+
DOCKER = DockerManager(container_name=CONTAINER_NAME)
|
42
|
+
|
43
|
+
|
44
|
+
def parse_args() -> argparse.Namespace:
|
45
|
+
"""Parse command-line arguments."""
|
46
|
+
parser = argparse.ArgumentParser(description=f"FastLED WASM Compiler {__version__}")
|
47
|
+
parser.add_argument(
|
48
|
+
"--version", action="version", version=f"%(prog)s {__version__}"
|
49
|
+
)
|
50
|
+
parser.add_argument(
|
51
|
+
"directory",
|
52
|
+
type=str,
|
53
|
+
nargs="?",
|
54
|
+
default=None,
|
55
|
+
help="Directory containing the FastLED sketch to compile",
|
56
|
+
)
|
57
|
+
parser.add_argument(
|
58
|
+
"--just-compile",
|
59
|
+
action="store_true",
|
60
|
+
help="Just compile, skip opening the browser and watching for changes.",
|
61
|
+
)
|
62
|
+
parser.add_argument(
|
63
|
+
"--web",
|
64
|
+
"-w",
|
65
|
+
type=str,
|
66
|
+
nargs="?",
|
67
|
+
# const does not seem to be working as expected
|
68
|
+
const=DEFAULT_URL, # Default value when --web is specified without value
|
69
|
+
help="Use web compiler. Optional URL can be provided (default: https://fastled.onrender.com)",
|
70
|
+
)
|
71
|
+
parser.add_argument(
|
72
|
+
"-i",
|
73
|
+
"--interactive",
|
74
|
+
action="store_true",
|
75
|
+
help="Run in interactive mode (Not available with --web)",
|
76
|
+
)
|
77
|
+
parser.add_argument(
|
78
|
+
"--profile",
|
79
|
+
action="store_true",
|
80
|
+
help="Enable profiling for web compilation",
|
81
|
+
)
|
82
|
+
build_mode = parser.add_mutually_exclusive_group()
|
83
|
+
build_mode.add_argument("--debug", action="store_true", help="Build in debug mode")
|
84
|
+
build_mode.add_argument(
|
85
|
+
"--quick",
|
86
|
+
action="store_true",
|
87
|
+
default=True,
|
88
|
+
help="Build in quick mode (default)",
|
89
|
+
)
|
90
|
+
build_mode.add_argument(
|
91
|
+
"--release", action="store_true", help="Build in release mode"
|
92
|
+
)
|
93
|
+
build_mode.add_argument(
|
94
|
+
"--localhost",
|
95
|
+
action="store_true",
|
96
|
+
help="Use localhost for web compilation from an instance of fastled --server",
|
97
|
+
)
|
98
|
+
build_mode.add_argument(
|
99
|
+
"--server",
|
100
|
+
action="store_true",
|
101
|
+
help="Run the server in the current directory, volume mapping fastled if we are in the repo",
|
102
|
+
)
|
103
|
+
|
104
|
+
build_mode.add_argument(
|
105
|
+
"--force-compile",
|
106
|
+
action="store_true",
|
107
|
+
help="Skips the test to see if the current directory is a valid FastLED sketch directory",
|
108
|
+
)
|
109
|
+
|
110
|
+
args = parser.parse_args()
|
111
|
+
if args.localhost:
|
112
|
+
args.web = "localhost"
|
113
|
+
if args.web is not None:
|
114
|
+
args.web = args.web if args.web == "" else args.web
|
115
|
+
if args.server and args.web:
|
116
|
+
parser.error("--server and --web are mutually exclusive")
|
117
|
+
if args.directory is None and not args.server:
|
118
|
+
# does current directory look like a sketch?
|
119
|
+
maybe_sketch_dir = Path(os.getcwd())
|
120
|
+
if looks_like_sketch_directory(maybe_sketch_dir):
|
121
|
+
args.directory = str(maybe_sketch_dir)
|
122
|
+
else:
|
123
|
+
print(
|
124
|
+
"\nYou either need to specify a sketch directory or run in --server mode."
|
125
|
+
)
|
126
|
+
sys.exit(1)
|
127
|
+
return args
|
128
|
+
|
129
|
+
|
130
|
+
def run_web_compiler(
|
131
|
+
directory: Path,
|
132
|
+
host: str,
|
133
|
+
build_mode: BuildMode,
|
134
|
+
profile: bool,
|
135
|
+
last_hash_value: str | None,
|
136
|
+
) -> CompiledResult:
|
137
|
+
input_dir = Path(directory)
|
138
|
+
output_dir = input_dir / "fastled_js"
|
139
|
+
start = time.time()
|
140
|
+
web_result = web_compile(
|
141
|
+
directory=input_dir, host=host, build_mode=build_mode, profile=profile
|
142
|
+
)
|
143
|
+
diff = time.time() - start
|
144
|
+
if not web_result.success:
|
145
|
+
print("\nWeb compilation failed:")
|
146
|
+
print(f"Time taken: {diff:.2f} seconds")
|
147
|
+
print(web_result.stdout)
|
148
|
+
return CompiledResult(success=False, fastled_js="", hash_value=None)
|
149
|
+
|
150
|
+
def print_results() -> None:
|
151
|
+
hash_value = (
|
152
|
+
web_result.hash_value
|
153
|
+
if web_result.hash_value is not None
|
154
|
+
else "NO HASH VALUE"
|
155
|
+
)
|
156
|
+
print(
|
157
|
+
f"\nWeb compilation successful\n Time: {diff:.2f}\n output: {output_dir}\n hash: {hash_value}\n zip size: {len(web_result.zip_bytes)} bytes"
|
158
|
+
)
|
159
|
+
|
160
|
+
# now check to see if the hash value is the same as the last hash value
|
161
|
+
if last_hash_value is not None and last_hash_value == web_result.hash_value:
|
162
|
+
print("\nSkipping redeploy: No significant changes found.")
|
163
|
+
print_results()
|
164
|
+
return CompiledResult(
|
165
|
+
success=True, fastled_js=str(output_dir), hash_value=web_result.hash_value
|
166
|
+
)
|
167
|
+
|
168
|
+
# Extract zip contents to fastled_js directory
|
169
|
+
output_dir.mkdir(exist_ok=True)
|
170
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
171
|
+
temp_path = Path(temp_dir)
|
172
|
+
temp_zip = temp_path / "result.zip"
|
173
|
+
temp_zip.write_bytes(web_result.zip_bytes)
|
174
|
+
|
175
|
+
# Clear existing contents
|
176
|
+
shutil.rmtree(output_dir, ignore_errors=True)
|
177
|
+
output_dir.mkdir(exist_ok=True)
|
178
|
+
|
179
|
+
# Extract zip contents
|
180
|
+
shutil.unpack_archive(temp_zip, output_dir, "zip")
|
181
|
+
|
182
|
+
print(web_result.stdout)
|
183
|
+
print_results()
|
184
|
+
return CompiledResult(
|
185
|
+
success=True, fastled_js=str(output_dir), hash_value=web_result.hash_value
|
186
|
+
)
|
187
|
+
|
188
|
+
|
189
|
+
def _try_start_server_or_get_url(args: argparse.Namespace) -> str | CompileServer:
|
190
|
+
if args.web:
|
191
|
+
if isinstance(args.web, str):
|
192
|
+
return args.web
|
193
|
+
if isinstance(args.web, bool):
|
194
|
+
return DEFAULT_URL
|
195
|
+
return args.web
|
196
|
+
else:
|
197
|
+
try:
|
198
|
+
compile_server = CompileServer()
|
199
|
+
print("Waiting for the local compiler to start...")
|
200
|
+
if not compile_server.wait_for_startup():
|
201
|
+
print("Failed to start local compiler.")
|
202
|
+
raise RuntimeError("Failed to start local compiler.")
|
203
|
+
return compile_server
|
204
|
+
except KeyboardInterrupt:
|
205
|
+
raise
|
206
|
+
except RuntimeError:
|
207
|
+
print("Failed to start local compile server, using web compiler instead.")
|
208
|
+
return DEFAULT_URL
|
209
|
+
|
210
|
+
|
211
|
+
def run_client(args: argparse.Namespace) -> int:
|
212
|
+
compile_server: CompileServer | None = None
|
213
|
+
open_web_browser = not args.just_compile
|
214
|
+
profile = args.profile
|
215
|
+
if not args.force_compile and not looks_like_sketch_directory(Path(args.directory)):
|
216
|
+
print(
|
217
|
+
"Error: Not a valid FastLED sketch directory, if you are sure it is, use --force-compile"
|
218
|
+
)
|
219
|
+
return 1
|
220
|
+
|
221
|
+
# If not explicitly using web compiler, check Docker installation
|
222
|
+
if not args.web and not DOCKER.is_docker_installed():
|
223
|
+
print(
|
224
|
+
"\nDocker is not installed on this system - switching to web compiler instead."
|
225
|
+
)
|
226
|
+
args.web = True
|
227
|
+
|
228
|
+
url: str
|
229
|
+
try:
|
230
|
+
try:
|
231
|
+
url_or_server: str | CompileServer = _try_start_server_or_get_url(args)
|
232
|
+
if isinstance(url_or_server, str):
|
233
|
+
print(f"Found URL: {url_or_server}")
|
234
|
+
url = url_or_server
|
235
|
+
else:
|
236
|
+
compile_server = url_or_server
|
237
|
+
print(f"Server started at {compile_server.url()}")
|
238
|
+
url = compile_server.url()
|
239
|
+
except KeyboardInterrupt:
|
240
|
+
print("\nExiting from first try...")
|
241
|
+
if compile_server:
|
242
|
+
compile_server.stop()
|
243
|
+
return 1
|
244
|
+
except Exception as e:
|
245
|
+
print(f"Error: {e}")
|
246
|
+
return 1
|
247
|
+
build_mode: BuildMode = get_build_mode(args)
|
248
|
+
|
249
|
+
def compile_function(
|
250
|
+
url: str = url,
|
251
|
+
build_mode: BuildMode = build_mode,
|
252
|
+
profile: bool = profile,
|
253
|
+
last_hash_value: str | None = None,
|
254
|
+
) -> CompiledResult:
|
255
|
+
return run_web_compiler(
|
256
|
+
args.directory,
|
257
|
+
host=url,
|
258
|
+
build_mode=build_mode,
|
259
|
+
profile=profile,
|
260
|
+
last_hash_value=last_hash_value,
|
261
|
+
)
|
262
|
+
|
263
|
+
result: CompiledResult = compile_function(last_hash_value=None)
|
264
|
+
last_compiled_result: CompiledResult = result
|
265
|
+
|
266
|
+
if not result.success:
|
267
|
+
print("\nCompilation failed.")
|
268
|
+
return 1
|
269
|
+
|
270
|
+
browser_proc: subprocess.Popen | None = None
|
271
|
+
if open_web_browser:
|
272
|
+
browser_proc = open_browser_thread(Path(args.directory) / "fastled_js")
|
273
|
+
else:
|
274
|
+
print(
|
275
|
+
"\nCompilation successful. Run without --just-compile to open in browser and watch for changes."
|
276
|
+
)
|
277
|
+
if compile_server:
|
278
|
+
print("Shutting down compile server...")
|
279
|
+
compile_server.stop()
|
280
|
+
return 0
|
281
|
+
|
282
|
+
if args.just_compile:
|
283
|
+
if compile_server:
|
284
|
+
compile_server.stop()
|
285
|
+
if browser_proc:
|
286
|
+
browser_proc.kill()
|
287
|
+
return 0 if result.success else 1
|
288
|
+
except KeyboardInterrupt:
|
289
|
+
print("\nExiting from main")
|
290
|
+
if compile_server:
|
291
|
+
compile_server.stop()
|
292
|
+
return 1
|
293
|
+
|
294
|
+
# Watch mode
|
295
|
+
print("\nWatching for changes. Press Ctrl+C to stop...")
|
296
|
+
# watcher = FileChangedNotifier(args.directory, excluded_patterns=["fastled_js"])
|
297
|
+
# watcher.start()
|
298
|
+
|
299
|
+
from multiprocessing import Process, Queue
|
300
|
+
|
301
|
+
proc: Process
|
302
|
+
queue: Queue
|
303
|
+
proc, queue = create_file_watcher_process(
|
304
|
+
args.directory, excluded_patterns=["fastled_js"]
|
305
|
+
)
|
306
|
+
|
307
|
+
try:
|
308
|
+
while True:
|
309
|
+
try:
|
310
|
+
size = queue.qsize()
|
311
|
+
changed_files = []
|
312
|
+
for i in range(size):
|
313
|
+
changed_files.append(queue.get())
|
314
|
+
except KeyboardInterrupt:
|
315
|
+
print("\nExiting from watcher...")
|
316
|
+
raise
|
317
|
+
except Exception as e:
|
318
|
+
print(f"Error getting changes: {e}")
|
319
|
+
changed_files = []
|
320
|
+
if changed_files:
|
321
|
+
print(f"\nChanges detected in {changed_files}")
|
322
|
+
last_hash_value = last_compiled_result.hash_value
|
323
|
+
result = compile_function(last_hash_value=last_hash_value)
|
324
|
+
if not result.success:
|
325
|
+
print("\nRecompilation failed.")
|
326
|
+
else:
|
327
|
+
print("\nRecompilation successful.")
|
328
|
+
time.sleep(0.3)
|
329
|
+
except KeyboardInterrupt:
|
330
|
+
print("\nStopping watch mode...")
|
331
|
+
return 0
|
332
|
+
except Exception as e:
|
333
|
+
print(f"Error: {e}")
|
334
|
+
return 1
|
335
|
+
finally:
|
336
|
+
proc.terminate()
|
337
|
+
if compile_server:
|
338
|
+
compile_server.stop()
|
339
|
+
if browser_proc:
|
340
|
+
browser_proc.kill()
|
341
|
+
|
342
|
+
|
343
|
+
def run_server(args: argparse.Namespace) -> int:
|
344
|
+
interactive = args.interactive
|
345
|
+
compile_server = CompileServer(interactive=interactive)
|
346
|
+
if not interactive:
|
347
|
+
print(f"Server started at {compile_server.url()}")
|
348
|
+
compile_server.wait_for_startup()
|
349
|
+
try:
|
350
|
+
while True:
|
351
|
+
if not compile_server.proceess_running():
|
352
|
+
print("Server process is not running. Exiting...")
|
353
|
+
return 1
|
354
|
+
time.sleep(1)
|
355
|
+
except KeyboardInterrupt:
|
356
|
+
print("\nExiting from server...")
|
357
|
+
return 1
|
358
|
+
finally:
|
359
|
+
compile_server.stop()
|
360
|
+
return 0
|
361
|
+
|
362
|
+
|
363
|
+
def main() -> int:
|
364
|
+
args = parse_args()
|
365
|
+
if args.server:
|
366
|
+
print("Running in server only mode.")
|
367
|
+
return run_server(args)
|
368
|
+
else:
|
369
|
+
print("Running in client/server mode.")
|
370
|
+
return run_client(args)
|
371
|
+
|
372
|
+
|
373
|
+
if __name__ == "__main__":
|
374
|
+
try:
|
375
|
+
sys.argv.append("examples/SdCard")
|
376
|
+
sys.argv.append("--local")
|
377
|
+
sys.exit(main())
|
378
|
+
except KeyboardInterrupt:
|
379
|
+
print("\nExiting from main...")
|
380
|
+
sys.exit(1)
|
381
|
+
except Exception as e:
|
382
|
+
print(f"Error: {e}")
|
383
|
+
sys.exit(1)
|