def push_changes(self, tmp, images):
        """Pushes changes for components into downstream dist-git repository"""
        # Check for kerberos ticket
        failed = []
        for image in images:
            component = image["component"]
            try:
                repo = Repo(component)
                # If a commit message is provided do a commit first
                if self.commit_msg and repo.is_dirty():
                    # commit_msg is set so it is always returned
                    commit = self.get_commit_msg(None, image)
                    repo.git.commit("-am", commit)
                if self._get_unpushed_commits(repo):
                    self.logger.info("Pushing: " + component)

                    repo.git.push()
                else:
                    self.logger.info(f"There are no unpushed commits."
                                     f" Push skipped for {component}.")
            except GitCommandError as e:
                failed.append(image)
                self.logger.error(e)

        if failed:
            self.logger.error("Failed pushing images:")
            for image in failed:
                self.logger.error(u._2sp(image["component"]))
            self.logger.error("Please check the failures and push the changes manually.")
 def merge_future_branches(self, images):
     """Merges current branch with future branches"""
     # Check for kerberos ticket
     failed = []
     for image in images:
         component = image["component"]
         branch = image["git_branch"]
         # TODO: config only has one future branch
         fb_list = [image["git_future"]]
         repo = self._clone_downstream(component, branch)
         for fb in fb_list:
             try:
                 repo.git.checkout(fb)
                 repo.git.merge(branch)
                 # print("Pushing into: {}".format(res))
                 self.logger.info("NOT Pushing into: {}".format(fb))
                 # repo.git.push()
             except GitCommandError as e:
                 failed.append(image)
                 self.logger.error(e)
                 continue
     if failed:
         self.logger.error("Failed merging images:")
         for image in failed:
             self.logger.error(u._2sp(image["component"]))
         self.logger.error("Please check the failures and push the changes manually.")
    def check_script(self, component, script_path, component_path):
        """Method that runs a given script against given directory

        Runs the script as provided by script_path and checks its exit value.
        Prints the content of stderr when the sciprt fails (exit value != 0).

        Args:
            component (string): name of the component being checked
            script_path (string): script that should be run during the check
            component_path (string): path to the directory being checked
        """
        template = "{name}: {status}"
        ret = subprocess.run(script_path,
                             shell=True,
                             stderr=subprocess.PIPE,
                             stdout=subprocess.DEVNULL,
                             cwd=component_path)

        if ret.returncode is not 0:
            self.logger.info(template.format(name=component,
                                             status="Affected"))
            err = ret.stderr.decode('utf-8').strip()
            if err:
                self.logger.error(u._2sp(err))
        else:
            self.logger.info(template.format(name=component, status="OK"))