1
+ import functools
2
+ from collections .abc import Callable , Generator
1
3
from pathlib import Path
2
4
3
5
import click
4
6
7
+ from pyjsx .linter import fix , lint
5
8
from pyjsx .transpiler import transpile
6
9
7
10
@@ -14,37 +17,59 @@ def cli(*, version: bool) -> None:
14
17
click .echo (pyjsx .__version__ )
15
18
16
19
17
- @cli .command ()
18
- @click .argument ("sources" , type = click .Path (exists = True ), nargs = - 1 )
19
- @click .option ("-r" , "--recursive" , type = bool , is_flag = True , default = False , help = "Recurse into directories." )
20
- def compile (sources : list [str ], recursive : bool ) -> None :
20
+ def accept_files_and_dirs (f : Callable ) -> Callable :
21
+ @click .argument ("sources" , type = click .Path (exists = True ), nargs = - 1 )
22
+ @click .option ("-r" , "--recursive" , type = bool , is_flag = True , default = False , help = "Recurse into directories." )
23
+ @functools .wraps (f )
24
+ def wrapper (* args , ** kwargs ) -> None :
25
+ return f (* args , ** kwargs )
26
+
27
+ return wrapper
28
+
29
+
30
+ @cli .command ("compile" )
31
+ @accept_files_and_dirs
32
+ def compile_files (sources : list [str ], * , recursive : bool ) -> None :
21
33
"""Compile .px files to regular .py files."""
34
+ paths = [Path (source ) for source in sources ]
22
35
count = 0
23
- for source in sources :
24
- path = Path ( source )
25
- count += transpile_dir ( path , recursive = recursive )
36
+ for path in iter_files ( paths , recursive = recursive ) :
37
+ transpile_file ( path )
38
+ count += 1
26
39
msg = f"Compiled { count } file" + ("s" if count != 1 else "" ) + "."
27
40
click .secho (msg , fg = "green" , bold = True )
28
41
29
42
30
- def transpile_dir (path : Path , * , recursive : bool = False ) -> int :
31
- if path .is_file ():
32
- return transpile_file (path )
33
- count = 0
34
- for file in path .iterdir ():
35
- if file .is_dir () and recursive :
36
- count += transpile_dir (file )
37
- elif file .is_file () and file .suffix == ".px" :
38
- count += transpile_file (file )
39
- return count
40
-
41
-
42
- def transpile_file (path : Path ) -> int :
43
- if path .suffix != ".px" :
44
- click .secho (f"Skipping { path } (not a .px file)" , fg = "yellow" )
45
- return 0
43
+ @cli .command ("lint" )
44
+ @accept_files_and_dirs
45
+ def lint_files (sources : list [str ], * , recursive : bool ) -> None :
46
+ """Find issues with JSX."""
47
+ paths = [Path (source ) for source in sources ]
48
+ for path in iter_files (paths , recursive = recursive ):
49
+ for error in lint (path .read_text ("utf-8" )):
50
+ click .secho (f"{ error [1 ]} " , fg = "red" )
51
+
52
+
53
+ @cli .command ("fix" )
54
+ @accept_files_and_dirs
55
+ def fix_files (sources : list [str ], * , recursive : bool ) -> None :
56
+ """Fix issues with JSX."""
57
+ paths = [Path (source ) for source in sources ]
58
+ for path in iter_files (paths , recursive = recursive ):
59
+ fixed = fix (path .read_text ("utf-8" ))
60
+ path .write_text (fixed , encoding = "utf-8" )
61
+
62
+
63
+ def transpile_file (path : Path ) -> None :
46
64
click .echo (f"Compiling { path } ..." )
47
65
transpiled = transpile (path .read_text ())
48
66
path .with_suffix (".py" ).write_text (transpiled )
49
- return 1
50
67
68
+
69
+ def iter_files (sources : list [Path ], * , recursive : bool = False ) -> Generator [Path , None , None ]:
70
+ for source in sources :
71
+ path = Path (source )
72
+ if path .is_file () and path .suffix == ".px" :
73
+ yield path
74
+ elif path .is_dir ():
75
+ yield from iter_files ([path ], recursive = recursive )
0 commit comments