22
33import ast
44from importlib .metadata import version as get_version
5+ from pathlib import Path
56from typing import Any , Optional
67
78import click
2122from .writer import run_write
2223
2324
25+ def run_project_flow (flow_file : str , flow_name : Optional [str ]) -> None :
26+ """Placeholder for running a project flow."""
27+ log .info (f"Running project flow from '{ flow_file } '" )
28+ if flow_name :
29+ log .info (f"Executing specific flow: '{ flow_name } '" )
30+ else :
31+ log .info ("Executing all flows defined in the file." )
32+
33+
2434@click .group (
2535 context_settings = dict (help_option_names = ["-h" , "--help" ]),
2636 invoke_without_command = True ,
3545 type = click .Path (),
3646 help = "Path to a file to write logs to, in addition to the console." ,
3747)
48+ @click .option (
49+ "--flow-file" ,
50+ type = click .Path (exists = True , dir_okay = False ),
51+ help = "Path to the YAML flow file. Defaults to 'flows.yml' in current directory." ,
52+ )
53+ @click .option (
54+ "--run" ,
55+ "flow_name" ,
56+ help = "Name of a specific flow to run from the flow file." ,
57+ )
3858@click .pass_context
39- def cli (ctx : click .Context , verbose : bool , log_file : Optional [str ]) -> None :
59+ def cli (
60+ ctx : click .Context ,
61+ verbose : bool ,
62+ log_file : Optional [str ],
63+ flow_file : Optional [str ],
64+ flow_name : Optional [str ],
65+ ) -> None :
4066 """Odoo Data Flow: A tool for importing, exporting, and processing data."""
4167 setup_logging (verbose , log_file )
42- if ctx .invoked_subcommand is None :
43- click .echo (ctx .get_help ())
68+
69+ # If a subcommand is invoked, it's Single-Action mode. Let it proceed.
70+ if ctx .invoked_subcommand is not None :
71+ return
72+
73+ # --- Project Mode Logic ---
74+ effective_flow_file = flow_file
75+ if not effective_flow_file :
76+ default_flow_file = Path ("flows.yml" )
77+ if default_flow_file .exists ():
78+ log .info ("No --flow-file specified, using default 'flows.yml'." )
79+ effective_flow_file = str (default_flow_file )
80+ else :
81+ # No subcommand, no --flow-file, and no default flows.yml -> show help.
82+ click .echo (ctx .get_help ())
83+ return
84+
85+ run_project_flow (effective_flow_file , flow_name )
4486
4587
4688# --- Module Management Command Group ---
@@ -52,24 +94,22 @@ def module_group() -> None:
5294
5395@module_group .command (name = "update-list" )
5496@click .option (
55- "-c" ,
56- "--config" ,
57- default = "conf/connection.conf" ,
58- show_default = True ,
59- help = "Path to the connection configuration file." ,
97+ "--connection-file" ,
98+ required = True ,
99+ type = click .Path (exists = True , dir_okay = False ),
100+ help = "Path to the Odoo connection file." ,
60101)
61- def update_module_list_cmd (config : str ) -> None :
102+ def update_module_list_cmd (connection_file : str ) -> None :
62103 """Scans the addons path and updates the list of available modules."""
63- run_update_module_list (config = config )
104+ run_update_module_list (config = connection_file )
64105
65106
66107@module_group .command (name = "install" )
67108@click .option (
68- "-c" ,
69- "--config" ,
70- default = "conf/connection.conf" ,
71- show_default = True ,
72- help = "Path to the connection configuration file." ,
109+ "--connection-file" ,
110+ required = True ,
111+ type = click .Path (exists = True , dir_okay = False ),
112+ help = "Path to the Odoo connection file." ,
73113)
74114@click .option (
75115 "-m" ,
@@ -78,19 +118,18 @@ def update_module_list_cmd(config: str) -> None:
78118 required = True ,
79119 help = "A comma-separated list of module names to install or upgrade." ,
80120)
81- def install_modules_cmd (config : str , modules_str : str ) -> None :
121+ def install_modules_cmd (connection_file : str , modules_str : str ) -> None :
82122 """Installs or upgrades a list of Odoo modules."""
83- modules_list = [mod .strip () for mod in modules_str .split ("," )]
84- run_module_installation (config = config , modules = modules_list )
123+ modules_list = [mod .strip () for mod in modules_str .split ("," ) if mod . strip () ]
124+ run_module_installation (config = connection_file , modules = modules_list )
85125
86126
87127@module_group .command (name = "uninstall" )
88128@click .option (
89- "-c" ,
90- "--config" ,
91- default = "conf/connection.conf" ,
92- show_default = True ,
93- help = "Path to the connection configuration file." ,
129+ "--connection-file" ,
130+ required = True ,
131+ type = click .Path (exists = True , dir_okay = False ),
132+ help = "Path to the Odoo connection file." ,
94133)
95134@click .option (
96135 "-m" ,
@@ -99,19 +138,18 @@ def install_modules_cmd(config: str, modules_str: str) -> None:
99138 required = True ,
100139 help = "A comma-separated list of module names to uninstall." ,
101140)
102- def uninstall_modules_cmd (config : str , modules_str : str ) -> None :
141+ def uninstall_modules_cmd (connection_file : str , modules_str : str ) -> None :
103142 """Uninstalls a list of Odoo modules."""
104143 modules_list = [mod .strip () for mod in modules_str .split ("," )]
105- run_module_uninstallation (config = config , modules = modules_list )
144+ run_module_uninstallation (config = connection_file , modules = modules_list )
106145
107146
108147@module_group .command (name = "install-languages" )
109148@click .option (
110- "-c" ,
111- "--config" ,
112- default = "conf/connection.conf" ,
113- show_default = True ,
114- help = "Path to the connection configuration file." ,
149+ "--connection-file" ,
150+ required = True ,
151+ type = click .Path (exists = True , dir_okay = False ),
152+ help = "Path to the Odoo connection file." ,
115153)
116154@click .option (
117155 "-l" ,
@@ -120,10 +158,10 @@ def uninstall_modules_cmd(config: str, modules_str: str) -> None:
120158 required = True ,
121159 help = "A comma-separated list of language codes to install (e.g., 'nl_BE,fr_FR')." ,
122160)
123- def install_languages_cmd (config : str , languages_str : str ) -> None :
161+ def install_languages_cmd (connection_file : str , languages_str : str ) -> None :
124162 """Installs one or more languages in the Odoo database."""
125163 languages_list = [lang .strip () for lang in languages_str .split ("," )]
126- run_language_installation (config = config , languages = languages_list )
164+ run_language_installation (config = connection_file , languages = languages_list )
127165
128166
129167# --- Workflow Command Group ---
@@ -136,11 +174,10 @@ def workflow_group() -> None:
136174# --- Invoice v9 Workflow Sub-command ---
137175@workflow_group .command (name = "invoice-v9" )
138176@click .option (
139- "-c" ,
140- "--config" ,
141- default = "conf/connection.conf" ,
142- show_default = True ,
143- help = "Path to the connection configuration file." ,
177+ "--connection-file" ,
178+ required = True ,
179+ type = click .Path (exists = True , dir_okay = False ),
180+ help = "Path to the Odoo connection file." ,
144181)
145182@click .option (
146183 "--action" ,
@@ -179,19 +216,19 @@ def workflow_group() -> None:
179216@click .option (
180217 "--max-connection" , default = 4 , type = int , help = "Number of parallel threads."
181218)
182- def invoice_v9_cmd (** kwargs : Any ) -> None :
219+ def invoice_v9_cmd (connection_file : str , ** kwargs : Any ) -> None :
183220 """Runs the legacy Odoo v9 invoice processing workflow."""
221+ kwargs ["config" ] = connection_file
184222 run_invoice_v9_workflow (** kwargs )
185223
186224
187225# --- Import Command ---
188226@cli .command (name = "import" )
189227@click .option (
190- "-c" ,
191- "--config" ,
192- default = "conf/connection.conf" ,
193- show_default = True ,
194- help = "Configuration file for connection parameters." ,
228+ "--connection-file" ,
229+ required = True ,
230+ type = click .Path (exists = True , dir_okay = False ),
231+ help = "Path to the Odoo connection file." ,
195232)
196233@click .option ("--file" , "filename" , required = True , help = "File to import." )
197234@click .option (
@@ -266,8 +303,9 @@ def invoice_v9_cmd(**kwargs: Any) -> None:
266303 help = "Special handling for one-to-many imports." ,
267304)
268305@click .option ("--encoding" , default = "utf-8" , help = "Encoding of the data file." )
269- def import_cmd (** kwargs : Any ) -> None :
306+ def import_cmd (connection_file : str , ** kwargs : Any ) -> None :
270307 """Runs the data import process."""
308+ kwargs ["config" ] = connection_file
271309 try :
272310 kwargs ["context" ] = ast .literal_eval (kwargs .get ("context" , "{}" ))
273311 except (ValueError , SyntaxError ) as e :
@@ -279,11 +317,10 @@ def import_cmd(**kwargs: Any) -> None:
279317# --- Write Command (New) ---
280318@cli .command (name = "write" )
281319@click .option (
282- "-c" ,
283- "--config" ,
284- default = "conf/connection.conf" ,
285- show_default = True ,
286- help = "Configuration file for connection parameters." ,
320+ "--connection-file" ,
321+ required = True ,
322+ type = click .Path (exists = True , dir_okay = False ),
323+ help = "Path to the Odoo connection file." ,
287324)
288325@click .option ("--file" , "filename" , required = True , help = "File with records to update." )
289326@click .option ("--model" , required = True , help = "Odoo model to write to." )
@@ -310,8 +347,9 @@ def import_cmd(**kwargs: Any) -> None:
310347 help = "Odoo context as a dictionary string." ,
311348)
312349@click .option ("--encoding" , default = "utf-8" , help = "Encoding of the data file." )
313- def write_cmd (** kwargs : Any ) -> None :
350+ def write_cmd (connection_file : str , ** kwargs : Any ) -> None :
314351 """Runs the batch update (write) process."""
352+ kwargs ["config" ] = connection_file
315353 try :
316354 kwargs ["context" ] = ast .literal_eval (kwargs .get ("context" , "{}" ))
317355 except (ValueError , SyntaxError ) as e :
@@ -323,11 +361,10 @@ def write_cmd(**kwargs: Any) -> None:
323361# --- Export Command ---
324362@cli .command (name = "export" )
325363@click .option (
326- "-c" ,
327- "--config" ,
328- default = "conf/connection.conf" ,
329- show_default = True ,
330- help = "Configuration file for connection parameters." ,
364+ "--connection-file" ,
365+ required = True ,
366+ type = click .Path (exists = True , dir_okay = False ),
367+ help = "Path to the Odoo connection file." ,
331368)
332369@click .option ("--output" , required = True , help = "Output file path." )
333370@click .option ("--model" , required = True , help = "Odoo model to export from." )
@@ -379,8 +416,9 @@ def write_cmd(**kwargs: Any) -> None:
379416 like 'selection' or 'binary'.
380417 """ ,
381418)
382- def export_cmd (** kwargs : Any ) -> None :
419+ def export_cmd (connection_file : str , ** kwargs : Any ) -> None :
383420 """Runs the data export process."""
421+ kwargs ["config" ] = connection_file
384422 run_export (** kwargs )
385423
386424
0 commit comments