Files
shell-history-automation-tool/shellhist/cli/export.py
7000pctAUTO c5007a7bb8
Some checks failed
CI / test (push) Has been cancelled
Initial upload with CI/CD workflow
2026-01-31 13:13:10 +00:00

152 lines
4.4 KiB
Python

"""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)