Initial upload with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-01-31 13:13:05 +00:00
parent 4439f8030d
commit 43c7f04134

139
shellhist/core/export.py Normal file
View File

@@ -0,0 +1,139 @@
"""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}"