예제 #1
0
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
예제 #2
0
    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()
예제 #3
0
    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()
예제 #4
0
파일: dsl.py 프로젝트: jspam/temci
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
예제 #5
0
파일: dsl.py 프로젝트: RaphaelKimmig/temci
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
예제 #6
0
    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()
예제 #7
0
    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()
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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)