33from pathlib import Path
44from dataclasses import dataclass
55
6- import click
76from sqlglot import Dialect
87from sqlmesh .integrations .dlt import generate_dlt_models_and_settings
98from sqlmesh .utils .date import yesterday_ds
9+ from sqlmesh .utils .errors import SQLMeshError
1010
1111from sqlmesh .core .config .connection import CONNECTION_CONFIG_TO_TYPE
1212
1515
1616
1717class ProjectTemplate (Enum ):
18+ DEFAULT = "default"
19+ EMPTY = "empty"
1820 DBT = "dbt"
1921 DLT = "dlt"
22+
23+
24+ class InitCliMode (Enum ):
2025 DEFAULT = "default"
21- EMPTY = "empty "
26+ SIMPLE = "simple "
2227
2328
2429def _gen_config (
2530 dialect : t .Optional [str ],
2631 settings : t .Optional [str ],
2732 start : t .Optional [str ],
2833 template : ProjectTemplate ,
34+ cli_mode : InitCliMode ,
2935) -> str :
3036 connection_settings = (
3137 settings
@@ -76,16 +82,29 @@ def _gen_config(
7682 )
7783
7884 default_configs = {
79- ProjectTemplate .DEFAULT : f"""gateways:
85+ ProjectTemplate .DEFAULT : f"""# --- Gateway Connection ---
86+ gateways:
8087 { dialect } :
8188 connection:
8289{ connection_settings }
83-
8490default_gateway: { dialect }
8591
92+ # --- Model Defaults ---
93+ # https://sqlmesh.readthedocs.io/en/stable/reference/model_configuration/#model-defaults
94+
8695model_defaults:
8796 dialect: { dialect }
8897 start: { start or yesterday_ds ()}
98+
99+ # --- Linting Rules ---
100+ # Enforce standards for your team
101+ # https://sqlmesh.readthedocs.io/en/stable/guides/linter/
102+
103+ linter:
104+ enabled: true
105+ rules:
106+ - ambiguousorinvalidcolumn
107+ - invalidselectstarexpansion
89108""" ,
90109 ProjectTemplate .DBT : """from pathlib import Path
91110
@@ -97,7 +116,29 @@ def _gen_config(
97116
98117 default_configs [ProjectTemplate .EMPTY ] = default_configs [ProjectTemplate .DEFAULT ]
99118 default_configs [ProjectTemplate .DLT ] = default_configs [ProjectTemplate .DEFAULT ]
100- return default_configs [template ]
119+
120+ simple_cli_mode = """
121+ # --- SIMPLE CLI MODE ---
122+ # Minimal prompts, automatic changes, summary output
123+ # https://sqlmesh.readthedocs.io/en/stable/reference/configuration/#plan
124+
125+ plan:
126+ enable_preview: true # Enable preview for forward-only models when targeting a development environment
127+ no_diff: true # Hide detailed text differences for changed models
128+ use_finalized_state: true # Compare only against finalized snapshots
129+ no_prompts: true # No interactive prompts
130+ auto_apply: true # Apply changes automatically
131+
132+ # --- Optional: Set a default target environment ---
133+ # default_target_environment: dev_{{ env_var('USER', 'your_name') }}
134+
135+ # Example usage:
136+ # export USER=your_name
137+ # sqlmesh plan # Resolves to: sqlmesh plan dev_your_name
138+ # sqlmesh plan prod # To apply changes to production
139+ """
140+
141+ return default_configs [template ] + (simple_cli_mode if cli_mode == InitCliMode .SIMPLE else "" )
101142
102143
103144@dataclass
@@ -237,7 +278,8 @@ def init_example_project(
237278 pipeline : t .Optional [str ] = None ,
238279 dlt_path : t .Optional [str ] = None ,
239280 schema_name : str = "sqlmesh_example" ,
240- ) -> None :
281+ cli_mode : InitCliMode = InitCliMode .DEFAULT ,
282+ ) -> t .Union [str , Path ]:
241283 root_path = Path (path )
242284 config_extension = "py" if template == ProjectTemplate .DBT else "yaml"
243285 config_path = root_path / f"config.{ config_extension } "
@@ -248,12 +290,12 @@ def init_example_project(
248290 tests_path = root_path / "tests"
249291
250292 if config_path .exists ():
251- raise click .ClickException (f"Found an existing config in '{ config_path } '" )
293+ raise SQLMeshError (
294+ f"Found an existing config file '{ config_path } '.\n \n Please change to another directory or remove the existing file."
295+ )
252296
253297 if not dialect and template != ProjectTemplate .DBT :
254- raise click .ClickException (
255- "Default SQL dialect is a required argument for SQLMesh projects"
256- )
298+ raise SQLMeshError ("Please provide a default SQL dialect for your project's models." )
257299
258300 models : t .Set [t .Tuple [str , str ]] = set ()
259301 settings = None
@@ -264,19 +306,19 @@ def init_example_project(
264306 pipeline_name = pipeline , dialect = dialect , dlt_path = dlt_path
265307 )
266308 else :
267- raise click . ClickException (
268- "DLT pipeline is a required argument to generate a SQLMesh project from DLT"
309+ raise SQLMeshError (
310+ "Please provide a DLT pipeline with the `--dlt-pipeline` flag to generate a SQLMesh project from DLT. "
269311 )
270312
271- _create_config (config_path , dialect , settings , start , template )
313+ _create_config (config_path , dialect , settings , start , template , cli_mode )
272314 if template == ProjectTemplate .DBT :
273- return
315+ return config_path
274316
275317 _create_folders ([audits_path , macros_path , models_path , seeds_path , tests_path ])
276318
277319 if template == ProjectTemplate .DLT :
278320 _create_models (models_path , models )
279- return
321+ return config_path
280322
281323 example_objects = _gen_example_objects (schema_name = schema_name )
282324
@@ -287,6 +329,8 @@ def init_example_project(
287329 _create_seeds (seeds_path , example_objects )
288330 _create_tests (tests_path , example_objects )
289331
332+ return config_path
333+
290334
291335def _create_folders (target_folders : t .Sequence [Path ]) -> None :
292336 for folder_path in target_folders :
@@ -300,11 +344,12 @@ def _create_config(
300344 settings : t .Optional [str ],
301345 start : t .Optional [str ],
302346 template : ProjectTemplate ,
347+ cli_mode : InitCliMode ,
303348) -> None :
304349 if dialect :
305350 Dialect .get_or_raise (dialect )
306351
307- project_config = _gen_config (dialect , settings , start , template )
352+ project_config = _gen_config (dialect , settings , start , template , cli_mode )
308353
309354 _write_file (
310355 config_path ,
0 commit comments