def actions_for_dir_path( path: str, path_acc: t.Set[str] = set()) -> t.List[Action]: """ Returns a list of actions that is needed to create a folder and it's parent folders. :param path: :param path_acc: paths already examined """ path = abspath(path) typecheck_locals(path=FileName(allow_non_existent=False) | DirName(), create=Bool()) assert os.path.exists(path) if path == "" or path == "~": return [] path = normalize_path(path) parts = path.split("/") ret = [] for i in range( 2 if parts[0] == "~" else 1, len(parts) + 1 if os.path.isdir(abspath(path)) else len(parts)): subpath = "/".join(parts[:i]) subpath_norm = normalize_path(subpath) if subpath_norm in path_acc: continue ret.append(CreateDir(subpath_norm)) path_acc.add(subpath_norm) return ret
def __init__(self, cmd: str, working_dir: str = normalize_path("."), send_mail: bool = None, mail_address: str = None, mail_header: str = None): """ Creates an instance. :param cmd: command to execute :param working_dir: directory in which the command is executed :param send_mail: send a mail after the execution of the program? :param mail_address: recipient of the mail :param mail_header: header of the mail """ super().__init__() if send_mail == None: send_mail = Settings()["package/send_mail"] != "" if mail_address == None: mail_address = Settings()["package/send_mail"] if mail_address == "": mail_address = None assert mail_address or not send_mail self.cmd = cmd # type: str """ Command to execute """ self.working_dir = working_dir # type: str """ Directory in which the command is executed """ self.send_mail = send_mail # type: bool """ Send a mail after the execution of the program? """ self.mail_address = mail_address # type: str """ Recipient of the mail """ self.mail_header = mail_header or "Executed command {!r}".format(self.cmd) # type: str """ Header of the mail """ self.typecheck()
def __init__(self, cmd: str, working_dir: str = normalize_path("."), send_mail: bool = None, mail_address: str = None, mail_header: str = None): """ Creates an instance. :param cmd: command to execute :param working_dir: directory in which the command is executed :param send_mail: send a mail after the execution of the program? :param mail_address: recipient of the mail :param mail_header: header of the mail """ super().__init__() if send_mail == None: send_mail = Settings()["package/send_mail"] != "" if mail_address == None: mail_address = Settings()["package/send_mail"] if mail_address == "": mail_address = None assert mail_address or not send_mail self.cmd = cmd # type: str """ Command to execute """ self.working_dir = working_dir # type: str """ Directory in which the command is executed """ self.send_mail = send_mail # type: bool """ Send a mail after the execution of the program? """ self.mail_address = mail_address # type: str """ Recipient of the mail """ self.mail_header = mail_header or "Executed command {!r}".format( self.cmd) # type: str """ Header of the mail """ self.typecheck()
def IncludeFile(filename: str) -> t.List[Action]: """ Returns the actions to include the file with the given name. :param filename: given file name :return: created actions """ typecheck_locals(filename=FileName(allow_non_existent=False)) ret = [] ret.extend(actions_for_dir_path(filename)) ret.append(CopyFile(normalize_path(filename))) return ret
def __init__(self, source: str, dest: str = None): """ Creates an instance. :param source: name of the file to copy :param dest: copy destination or None if ``source`` should be used """ super().__init__() self.source = source # type: str """ Name of the file to copy """ self.dest = dest or normalize_path(self.source) # type: str """ Copy destination """ self.typecheck()
def actions_for_dir_path(path: str, path_acc: t.Set[str] = set()) -> t.List[Action]: """ Returns a list of actions that is needed to create a folder and it's parent folders. :param path: :param path_acc: paths already examined """ path = abspath(path) typecheck_locals(path=FileName(allow_non_existent=False)|DirName(), create=Bool()) assert os.path.exists(path) if path == "" or path == "~": return [] path = normalize_path(path) parts = path.split("/") ret = [] for i in range(2 if parts[0] == "~" else 1, len(parts) + 1 if os.path.isdir(abspath(path)) else len(parts)): subpath = "/".join(parts[:i]) subpath_norm = normalize_path(subpath) if subpath_norm in path_acc: continue ret.append(CreateDir(subpath_norm)) path_acc.add(subpath_norm) return ret
def copy_tree_actions(base: str, include_patterns: t.Union[t.List[str], str] = ["**", "**/.*"], exclude_patterns: t.List[str] = None) -> t.List[Action]: """ Actions for all files and directories in the base directory that match the given patterns. It's used to copy a whole directory tree. :param base: base directory :param include_pattern: patterns that match the paths that should be included :param exclude_patterns: patterns that match the paths that should be excluded :return: list of actions """ paths = matched_paths(base, include_patterns, exclude_patterns) files = set() # type: t.Set[str] dirs = set() # type: t.Set[str] ret = [] # type: t.List[Action] for path in paths: ret.extend(actions_for_dir_path(path, path_acc=dirs)) if os.path.isfile(path) and path not in files: files.add(path) ret.append(CopyFile(normalize_path(path))) return ret
class ExecuteCmd(Action): """ Execute a command and mail it's output (optional). """ name = "execute_cmd" config_type = Dict({ "cmd": Str() // Default(""), "working_dir": Str() // Default(normalize_path(".")), "send_mail": Bool() // Default(False), "mail_address": Optional(Str()), "mail_header": Optional(Str()) }) def __init__(self, cmd: str, working_dir: str = normalize_path("."), send_mail: bool = None, mail_address: str = None, mail_header: str = None): """ Creates an instance. :param cmd: command to execute :param working_dir: directory in which the command is executed :param send_mail: send a mail after the execution of the program? :param mail_address: recipient of the mail :param mail_header: header of the mail """ super().__init__() if send_mail == None: send_mail = Settings()["package/send_mail"] != "" if mail_address == None: mail_address = Settings()["package/send_mail"] if mail_address == "": mail_address = None assert mail_address or not send_mail self.cmd = cmd # type: str """ Command to execute """ self.working_dir = working_dir # type: str """ Directory in which the command is executed """ self.send_mail = send_mail # type: bool """ Send a mail after the execution of the program? """ self.mail_address = mail_address # type: str """ Recipient of the mail """ self.mail_header = mail_header or "Executed command {!r}".format( self.cmd) # type: str """ Header of the mail """ self.typecheck() def _dry_run_message(self) -> str: return "Would execute {!r} in directory {!r}".format( self.cmd, self.working_dir) def _execute(self, db: Database): logging.info("Execute {!r} in directory {!r}".format( self.cmd, self.working_dir)) proc = subprocess.Popen(["/bin/sh", "-c", self.cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, cwd=abspath(self.working_dir)) out, err = proc.communicate() ret_code = proc.wait() if self.send_mail: def format_out(out): return out.replace("\n", "\n\t") content = """ Command: {cmd} Return code: {ret} Standard out: {out} Standard Error: {err} """.format(cmd=self.cmd, ret=ret_code, out=format_out(out), err=format_out(err)) send_mail(self.mail_address, self.mail_header, content)