From 43c7f041344cb35ea50e9e24fcc1f291c9f9f38c Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sat, 31 Jan 2026 13:13:05 +0000 Subject: [PATCH] Initial upload with CI/CD workflow --- shellhist/core/export.py | 139 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 shellhist/core/export.py diff --git a/shellhist/core/export.py b/shellhist/core/export.py new file mode 100644 index 0000000..e2ca26d --- /dev/null +++ b/shellhist/core/export.py @@ -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}"