"""Export command for generating scripts from detected patterns.""" import os from pathlib import Path from typing import Optional import click from rich.console import Console from shellhist.core import HistoryLoader from shellhist.core.export import generate_script, generate_script_name from shellhist.core.patterns import detect_common_sequences @click.command("export-script") @click.option( "--history", "-H", type=str, help="Path to history file", ) @click.option( "--output", "-o", type=str, default=".", help="Output directory for generated scripts (default: current directory)", ) @click.option( "--name", "-n", type=str, help="Custom name for the script file", ) @click.option( "--dry-run", "-d", is_flag=True, default=False, help="Preview script without writing to disk", ) @click.option( "--force", "-f", is_flag=True, default=False, help="Overwrite existing scripts", ) @click.option( "--shell", "-s", type=click.Choice(["bash", "zsh"]), help="Shell type for parsing", ) @click.option( "--min-occurrences", "-m", type=int, default=3, help="Minimum occurrences for pattern (default: 3)", ) @click.pass_context def export_script_command( ctx: click.Context, history: Optional[str], output: str, name: Optional[str], dry_run: bool, force: bool, shell: Optional[str], min_occurrences: int, ) -> None: """Export detected command patterns to executable shell scripts. Examples: \b shellhist export-script --output ./scripts/ shellhist export-script --output ./scripts/ --name myroutine shellhist export-script --dry-run --min-occurrences 5 """ console = Console() try: loader = HistoryLoader(history_path=history) store = loader.load() if not store.entries: console.print("[yellow]No entries found in history.[/yellow]") return sequences = detect_common_sequences( store, max_length=5, min_occurrences=min_occurrences, ) if not sequences: console.print( f"[yellow]No significant patterns found with minimum {min_occurrences} occurrences.[/yellow]" ) console.print("Try lowering --min-occurrences or run more commands.") return console.print(f"[bold cyan]Detected Patterns for Script Export[/bold cyan]\n") scripts_generated = 0 for i, pattern in enumerate(sequences[:5], 1): script_name = name or generate_script_name(pattern) console.print(f"{i}. Pattern: {' -> '.join(pattern.commands)}") console.print(f" Script name: {script_name}") try: script_path, content = generate_script( pattern=pattern, script_name=script_name, output_dir=output, dry_run=dry_run, force=force, ) if dry_run: console.print(f" [yellow](dry-run) Would create: {script_path}[/yellow]") console.print(f" Content preview:") for line in content.split("\n")[:5]: console.print(f" {line}") console.print() else: console.print(f" [green]Created: {script_path}[/green]\n") scripts_generated += 1 except FileExistsError: console.print(f" [yellow]Skipped: {script_name}.sh (already exists, use --force to overwrite)[/yellow]\n") except Exception as e: console.print(f" [red]Error: {e}[/red]\n") if not dry_run and scripts_generated > 0: console.print( f"[green]Successfully generated {scripts_generated} script(s) in {output}[/green]" ) elif dry_run: console.print("[yellow]Scripts not created (dry-run mode)[/yellow]") except FileNotFoundError as e: console.print(f"[red]Error: {e}[/red]") ctx.exit(1) except Exception as e: console.print(f"[red]Error exporting scripts: {e}[/red]") ctx.exit(1)