1import os
2
3import click
4from watchfiles import Change, DefaultFilter, watch
5
6from plain.assets.finders import iter_asset_dirs, iter_assets
7from plain.cli import register_cli
8
9from .core import esbuild, get_esbuilt_path
10
11
12@register_cli("esbuild")
13@click.group("esbuild")
14def cli() -> None:
15 pass
16
17
18@cli.command()
19@click.option("--minify", is_flag=True, default=True)
20def build(minify: bool) -> None:
21 returncode = 0
22 for asset in iter_assets():
23 if ".esbuild." in asset.absolute_path:
24 if not esbuild(
25 asset.absolute_path,
26 get_esbuilt_path(asset.absolute_path),
27 minify=minify,
28 ):
29 returncode = 1
30 print()
31
32 if returncode:
33 exit(returncode)
34
35
36@cli.command()
37@click.pass_context
38def dev(ctx: click.Context) -> None:
39 # Do an initial build of the assets
40 ctx.invoke(build, minify=False)
41
42 asset_dirs = list(iter_asset_dirs())
43
44 class EsbuildFilter(DefaultFilter):
45 ignore_entity_patterns = (
46 *DefaultFilter.ignore_entity_patterns,
47 r"\.tmp\.",
48 r"\.esbuilt\.",
49 )
50
51 def __call__(self, change: Change, path: str) -> bool:
52 return super().__call__(change, path) and ".esbuild." in path
53
54 print("Watching for changes in .esbuild. asset files...")
55
56 for changes in watch(*asset_dirs, watch_filter=EsbuildFilter()):
57 for change, path in changes:
58 if change in [Change.added, Change.modified]:
59 esbuild(path, get_esbuilt_path(path))
60 elif change == Change.deleted:
61 dist_path = get_esbuilt_path(path)
62 if os.path.exists(dist_path):
63 print(f"Deleting {os.path.relpath(dist_path)}")
64 os.remove(dist_path)