- Add return type annotations to __hash__ (-> int) and __eq__ (-> bool) in HistoryEntry - Add TextIO import and type annotations for file parameters - Add type ignore comment for fuzzywuzzy import - Add HistoryEntry import and list type annotations in time_analysis - Add assert statements for Optional[datetime] timestamps - Add TypedDict classes for type-safe pattern dictionaries - Add CommandPattern import and list[CommandPattern] type annotation - Add -> None return types to all test methods - Remove unused HistoryEntry import (F401)
110 lines
2.7 KiB
Python
110 lines
2.7 KiB
Python
"""Export command for generating scripts from detected patterns."""
|
|
|
|
from typing import Optional
|
|
|
|
import click
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
|
|
from shellhist.core import HistoryLoader
|
|
from shellhist.core.patterns import (
|
|
detect_command_pairs,
|
|
detect_command_triplets,
|
|
detect_repetitive_commands,
|
|
)
|
|
from shellhist.core.export import generate_script
|
|
|
|
|
|
@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",
|
|
)
|
|
@click.option(
|
|
"--name",
|
|
"-n",
|
|
type=str,
|
|
default="shellhist_script",
|
|
help="Name for the generated script",
|
|
)
|
|
@click.option(
|
|
"--dry-run",
|
|
"-d",
|
|
is_flag=True,
|
|
default=False,
|
|
help="Show script content without writing to file",
|
|
)
|
|
@click.option(
|
|
"--shell",
|
|
"-s",
|
|
type=click.Choice(["bash", "zsh"]),
|
|
help="Shell type for parsing",
|
|
)
|
|
@click.pass_context
|
|
def export_command(
|
|
ctx: click.Context,
|
|
history: Optional[str],
|
|
output: str,
|
|
name: str,
|
|
dry_run: bool,
|
|
shell: Optional[str],
|
|
) -> None:
|
|
"""Export detected patterns to executable shell scripts.
|
|
|
|
Examples:
|
|
|
|
\b
|
|
shellhist export-script
|
|
shellhist export-script --output ./scripts/ --name myscript
|
|
shellhist export-script --dry-run
|
|
"""
|
|
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
|
|
|
|
pairs = detect_command_pairs(store, min_frequency=2)
|
|
triplets = detect_command_triplets(store, min_frequency=2)
|
|
repetitive = detect_repetitive_commands(store, min_frequency=2)
|
|
|
|
all_patterns = pairs + triplets + repetitive
|
|
|
|
if not all_patterns:
|
|
console.print(
|
|
"[yellow]No patterns found to export.[/yellow]"
|
|
)
|
|
return
|
|
|
|
result = generate_script(
|
|
all_patterns,
|
|
script_name=name,
|
|
output_dir=output,
|
|
dry_run=dry_run,
|
|
)
|
|
|
|
if dry_run:
|
|
console.print(Panel(result, title="Generated Script (Dry Run)", expand=False))
|
|
else:
|
|
console.print(f"\n[green]Script exported to: {result}[/green]")
|
|
|
|
except FileNotFoundError as e:
|
|
console.print(f"[red]Error: {e}[/red]")
|
|
ctx.exit(1)
|
|
except Exception as e:
|
|
console.print(f"[red]Error exporting script: {e}[/red]")
|
|
ctx.exit(1)
|