11"""SchemaForge CLI — bidirectional ORM schema converter."""
2+
23from __future__ import annotations
34
45import click
1415
1516# All supported format names (used for CLI choices and detection)
1617_FORMATS = [
17- "sql" , "prisma" , "drizzle" , "typeorm" , "django" ,
18- "sqlalchemy" , "alembic" , "json_schema" , "graphql" , "ef" , "scala" ,
18+ "sql" ,
19+ "prisma" ,
20+ "drizzle" ,
21+ "typeorm" ,
22+ "django" ,
23+ "sqlalchemy" ,
24+ "alembic" ,
25+ "json_schema" ,
26+ "graphql" ,
27+ "ef" ,
28+ "scala" ,
1929]
2030
2131
@@ -29,25 +39,45 @@ def main() -> None:
2939 """
3040
3141
32-
3342@main .command ()
34- @click .option ("--from" , "from_fmt" , required = True ,
35- type = click .Choice (_FORMATS ),
36- help = "Source format" )
37- @click .option ("--to" , "to_fmt" , required = True ,
38- type = click .Choice (_FORMATS ),
39- help = "Target format" )
40- @click .option ("--input" , "-i" , "input_path" , required = True ,
41- type = click .Path (exists = True , readable = True ),
42- help = "Input file path" )
43- @click .option ("--output" , "-o" , "output_path" ,
44- type = click .Path (writable = True ),
45- help = "Output file path (default: stdout)" )
46- @click .option ("--type-map" , "type_map_path" ,
47- type = click .Path (exists = True , readable = True ),
48- help = "Custom type mapping config file (.yaml or .json)" )
49- def convert (from_fmt : str , to_fmt : str , input_path : str ,
50- output_path : str | None , type_map_path : str | None ) -> None :
43+ @click .option (
44+ "--from" ,
45+ "from_fmt" ,
46+ required = True ,
47+ type = click .Choice (_FORMATS ),
48+ help = "Source format" ,
49+ )
50+ @click .option (
51+ "--to" , "to_fmt" , required = True , type = click .Choice (_FORMATS ), help = "Target format"
52+ )
53+ @click .option (
54+ "--input" ,
55+ "-i" ,
56+ "input_path" ,
57+ required = True ,
58+ type = click .Path (exists = True , readable = True ),
59+ help = "Input file path" ,
60+ )
61+ @click .option (
62+ "--output" ,
63+ "-o" ,
64+ "output_path" ,
65+ type = click .Path (writable = True ),
66+ help = "Output file path (default: stdout)" ,
67+ )
68+ @click .option (
69+ "--type-map" ,
70+ "type_map_path" ,
71+ type = click .Path (exists = True , readable = True ),
72+ help = "Custom type mapping config file (.yaml or .json)" ,
73+ )
74+ def convert (
75+ from_fmt : str ,
76+ to_fmt : str ,
77+ input_path : str ,
78+ output_path : str | None ,
79+ type_map_path : str | None ,
80+ ) -> None :
5181 """Convert schema between formats."""
5282 # Load custom type mapping if specified
5383 type_config : TypeConfig | None = None
@@ -75,9 +105,13 @@ def convert(from_fmt: str, to_fmt: str, input_path: str,
75105@main .command ()
76106@click .argument ("file_a" , type = click .Path (exists = True , readable = True ))
77107@click .argument ("file_b" , type = click .Path (exists = True , readable = True ))
78- @click .option ("--format" , "fmt" , default = "auto" ,
79- type = click .Choice (["auto" ] + _FORMATS ),
80- help = "Schema format (auto = detect from extension)" )
108+ @click .option (
109+ "--format" ,
110+ "fmt" ,
111+ default = "auto" ,
112+ type = click .Choice (["auto" ] + _FORMATS ),
113+ help = "Schema format (auto = detect from extension)" ,
114+ )
81115def diff (file_a : str , file_b : str , fmt : str ) -> None :
82116 """Show differences between two schema files."""
83117 text_a = Path (file_a ).read_text (encoding = "utf-8" )
@@ -96,15 +130,25 @@ def diff(file_a: str, file_b: str, fmt: str) -> None:
96130
97131
98132@main .command ()
99- @click .option ("--dir" , "directory" , required = True ,
100- type = click .Path (exists = True , file_okay = False , readable = True ),
101- help = "Directory containing schema files to check" )
102- @click .option ("--canonical" , default = "sql" ,
103- type = click .Choice ([f for f in _FORMATS if f != "alembic" ]),
104- help = "Canonical format for comparison (default: sql)" )
105- @click .option ("--type-map" , "type_map_path" ,
106- type = click .Path (exists = True , readable = True ),
107- help = "Custom type mapping config file (.yaml or .json)" )
133+ @click .option (
134+ "--dir" ,
135+ "directory" ,
136+ required = True ,
137+ type = click .Path (exists = True , file_okay = False , readable = True ),
138+ help = "Directory containing schema files to check" ,
139+ )
140+ @click .option (
141+ "--canonical" ,
142+ default = "sql" ,
143+ type = click .Choice ([f for f in _FORMATS if f != "alembic" ]),
144+ help = "Canonical format for comparison (default: sql)" ,
145+ )
146+ @click .option (
147+ "--type-map" ,
148+ "type_map_path" ,
149+ type = click .Path (exists = True , readable = True ),
150+ help = "Custom type mapping config file (.yaml or .json)" ,
151+ )
108152def check (directory : str , canonical : str , type_map_path : str | None ) -> None :
109153 """Verify all schema files in a directory produce equivalent schemas.
110154
@@ -113,8 +157,9 @@ def check(directory: str, canonical: str, type_map_path: str | None) -> None:
113157 consistency across format representations.
114158 """
115159 try :
116- result = check_directory (directory , canonical = canonical ,
117- type_map_path = type_map_path )
160+ result = check_directory (
161+ directory , canonical = canonical , type_map_path = type_map_path
162+ )
118163 click .echo (result )
119164 if "FAIL" in result and "PASS" not in result :
120165 sys .exit (1 )
@@ -134,4 +179,3 @@ def _detect_format(path: str) -> str:
134179
135180if __name__ == "__main__" :
136181 main ()
137-
0 commit comments