import click import json import logging import sys from mrds import __version__ from mrds.core import main @click.command() @click.version_option(version=__version__, prog_name="mrds") @click.option( "--workflow-context", "-w", required=False, help="Workflow context to be used by the application. This is required unless --generate-workflow-context is provided.", ) @click.option( "--source-filename", "-s", required=True, help="Source filename to be processed.", ) @click.option( "--config-file", "-c", type=click.Path(exists=True), required=True, help="Path to the YAML configuration file.", ) @click.option( "--generate-workflow-context", is_flag=True, default=False, help="Generate a workflow context automatically. If this is set, --workflow-context is not required.", ) @click.option( "--keep-source-file", is_flag=True, default=False, help="Keep source file, instead of deleting it.", ) @click.option( "--keep-tmp-dir", is_flag=True, default=False, help="Keep tmp directory, instead of deleting it.", ) def cli_main( workflow_context, source_filename, config_file, generate_workflow_context, keep_source_file, keep_tmp_dir, ): # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s - %(message)s", handlers=[ logging.StreamHandler(sys.stdout), ], ) # Handle conflicting options if workflow_context and generate_workflow_context: raise click.UsageError( "You cannot use both --workflow-context and --generate-workflow-context at the same time. " "Please provide only one." ) # Enforce that either --workflow-context or --generate-workflow-context must be provided if not workflow_context and not generate_workflow_context: raise click.UsageError( "You must provide --workflow-context or use --generate-workflow-context flag." ) # Parse and validate the workflow_context if provided if workflow_context: try: workflow_context = json.loads(workflow_context) except json.JSONDecodeError as e: raise click.UsageError(f"Invalid JSON for --workflow-context: {e}") # Validate that the workflow_context matches the expected structure if ( not isinstance(workflow_context, dict) or "run_id" not in workflow_context or "a_workflow_history_key" not in workflow_context ): raise click.UsageError( "Invalid workflow context structure. It must be a JSON object with 'run_id' and 'a_workflow_history_key'." ) # Call the core processing function main( workflow_context, source_filename, config_file, generate_workflow_context, keep_source_file, keep_tmp_dir, ) if __name__ == "__main__": try: cli_main() sys.exit(0) except click.UsageError as e: logging.error(f"Usage error: {e}") sys.exit(2) except Exception as e: logging.error(f"Unexpected error: {e}") sys.exit(1)