#!/bin/python3 import pandoc import pandoc.types as t import sys # There are three parts: # - Parse a given markdown and extract the commands # - Also: keep track of the groups / ... # - Let the user decide, what to run / edit / split / skip # - Run the commands remotely # Usage: $0 remote.host.name md1 md2 ... # TODO: implement it @dataclass class Command: user: str directory: str command: str context: str def stringify(block) -> str: """ Take an object of some of pandoc.types and make the best of it. """ # The pandoc library has a fancy function for that... return pandoc.write(block) def extract_snippets(pd: t.Pandoc) -> Sequence[Tuple[str, str]]: """ This extracts snippets from the code. The problem is, that we want context with it, so we return a list of tuples (previous_block_stringified, code_snippet). """ result = [] last_block = "" for block in pd[1]: if isinstance(block, t.CodeBlock): result.append((last_block, block[1])) last_block = stringify(block) return result def parse_snippet(s: Tuple[str, str]) -> Sequence[Sequence[Command]]: # We need to preserve the groups of commands, so we return a list of groups (lists) of commands. # Will return always a list, even if it has only one element. # This is where we handle blank lines, comments, cd's and sudo's, so that the Commands in the output are "runnable" context_prefix = s[1] # TODO def user_action(hunk: Sequence[Command]) -> Sequence[Command]: # Maybe modify the commands to run. # This should have a simple UI: show the hunk with context (ideally in grey), ask what to do, return the wanted command # Actions: yes(y): accept input; no(n): skip this command; edit(e): launch $EDITOR or vim on the hunk; quit(q): terminate; split(s): split hunks to individual lines and ask for each one. # TODO pass def run_command(cmd: Command): # Generate and run the SSH command. def process_file(fn: str): """ To be called upon each file on the command line. This function should perform all the steps needed in order to remotely run a parsed markdown, id est the three parts above. """ # TODO pass # FIXME: tohle má být parametr TARGET="nothing.nowhere.invalid" def format_command(command, user=None, directory=None, target=None): -> str cmd = "ssh " if user is not None: cmd += f"{user}@" if target is None: global TARGET cmd += TARGET else: cmd += target # Be safe: cmd += " set -e ';' " if directory is not None cmd += f"cd '{directory}' ';' " cmd += command return cmd