140 lines
3.6 KiB
Python
140 lines
3.6 KiB
Python
"""Export functionality for generating scripts from detected patterns."""
|
|
|
|
import os
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
from shellhist.core.patterns import CommandPattern
|
|
|
|
|
|
SCRIPT_TEMPLATE = '''#!/bin/bash
|
|
# Generated by Shell History Automation Tool
|
|
# Generated at: {timestamp}
|
|
# Pattern: {pattern}
|
|
# Frequency: {frequency} occurrences
|
|
|
|
{commands}
|
|
|
|
# End of generated script
|
|
'''
|
|
|
|
|
|
def generate_alias(
|
|
pattern: CommandPattern,
|
|
alias_name: Optional[str] = None,
|
|
) -> str:
|
|
"""Generate a shell alias from a command pattern.
|
|
|
|
Args:
|
|
pattern: CommandPattern to generate alias from.
|
|
alias_name: Optional custom alias name.
|
|
|
|
Returns:
|
|
Formatted alias string.
|
|
"""
|
|
if alias_name is None:
|
|
alias_name = generate_alias_name(pattern)
|
|
|
|
commands_str = " && ".join(pattern.commands)
|
|
|
|
return f"alias {alias_name}='{commands_str}'"
|
|
|
|
|
|
def generate_alias_name(pattern: CommandPattern) -> str:
|
|
"""Generate a meaningful alias name from a pattern.
|
|
|
|
Args:
|
|
pattern: CommandPattern to generate name from.
|
|
|
|
Returns:
|
|
Generated alias name.
|
|
"""
|
|
if len(pattern.commands) == 1:
|
|
cmd = pattern.commands[0]
|
|
parts = cmd.split()
|
|
if parts:
|
|
base = os.path.basename(parts[0])
|
|
return base.replace("-", "_")
|
|
|
|
keywords = []
|
|
for cmd in pattern.commands:
|
|
parts = cmd.split()
|
|
if parts:
|
|
keywords.append(parts[0][:3])
|
|
|
|
return "_".join(keywords) if keywords else "custom_alias"
|
|
|
|
|
|
def generate_script(
|
|
pattern: CommandPattern,
|
|
script_name: Optional[str] = None,
|
|
output_dir: str = ".",
|
|
dry_run: bool = False,
|
|
force: bool = False,
|
|
) -> tuple[str, str]:
|
|
"""Generate an executable shell script from a pattern.
|
|
|
|
Args:
|
|
pattern: CommandPattern to generate script from.
|
|
script_name: Name for the script file.
|
|
output_dir: Directory to write script to.
|
|
dry_run: If True, return content without writing.
|
|
force: If True, overwrite existing files.
|
|
|
|
Returns:
|
|
Tuple of (script_path, content).
|
|
"""
|
|
if script_name is None:
|
|
script_name = generate_script_name(pattern)
|
|
|
|
if not script_name.endswith(".sh"):
|
|
script_name += ".sh"
|
|
|
|
script_path = os.path.join(output_dir, script_name)
|
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
commands_str = "\n".join(pattern.commands)
|
|
|
|
content = SCRIPT_TEMPLATE.format(
|
|
timestamp=timestamp,
|
|
pattern=" -> ".join(pattern.commands),
|
|
frequency=pattern.frequency,
|
|
commands=commands_str,
|
|
)
|
|
|
|
if dry_run:
|
|
return script_path, content
|
|
|
|
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
|
|
|
if os.path.exists(script_path) and not force:
|
|
raise FileExistsError(f"Script already exists: {script_path}")
|
|
|
|
with open(script_path, "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
|
|
os.chmod(script_path, 0o755)
|
|
|
|
return script_path, content
|
|
|
|
|
|
def generate_script_name(pattern: CommandPattern) -> str:
|
|
"""Generate a script filename from a pattern.
|
|
|
|
Args:
|
|
pattern: CommandPattern to generate name from.
|
|
|
|
Returns:
|
|
Generated script filename.
|
|
"""
|
|
parts = []
|
|
for cmd in pattern.commands[:3]:
|
|
cmd_parts = cmd.split()
|
|
if cmd_parts:
|
|
base = os.path.basename(cmd_parts[0])
|
|
safe = "".join(c for c in base if c.isalnum() or c in "-_")
|
|
parts.append(safe[:10])
|
|
|
|
name = "_".join(parts) if parts else "script"
|
|
return f"shellhist_{name}"
|