Exemple #1
0
    def _checkout_git_plugin_revision(repo, revision, update_string):
        """Checkout a specific revision for a git plugin
        Before checking out the new branch a new backup branch will be created

        :param repo: Repo object that points to plugin local repo
        :param revision: revision to checkout
        :param update_string: name of the backup branch
        :return:
        """
        LOG.warning("Create a branch '{}' that will point "
                    "to the current HEAD".format(update_string))
        repo.git.branch(update_string)

        LOG.debug("Fetching changes from the "
                  "'{}' remote".format(repo.remote().name))
        repo.git.fetch(repo.remote().name)

        try:
            if revision not in (None, 'latest'):
                LOG.debug("Checking out revision {}".format(revision))
                repo.git.checkout(revision)
        except git.exc.GitCommandError:
            raise IRFailedToUpdatePlugin(
                "Failed to update plugin!\n"
                "revision '{}' could not be checked out".format(revision))
Exemple #2
0
    def _pull_git_plugin_changes(repo):
        """Pull changes on a git plugin

        :param repo: Repo object that points to plugin local repo
        :return:
        """
        try:
            # only pull if not detached
            if not repo.head.is_detached:
                for ref in repo.remotes.origin.refs:
                    # check if active branch has a remote branch to pull from
                    if repo.active_branch.name in ref.name:
                        LOG.debug("Pulling changes from the "
                                  "'{}' remote".format(repo.remote().name))
                        repo.git.pull('--rebase')
                        break
        except git.exc.GitCommandError as ex:
            repo.git.rebase('--abort')
            raise IRFailedToUpdatePlugin(
                "Failed to update plugin!\nPlease go to plugin dir ({})"
                " and manually resolve Git issues.\n"
                "{}\n{}".format(repo.working_dir, ex.stdout, ex.stderr))
Exemple #3
0
    def update_plugin(self,
                      plugin_name,
                      revision=None,
                      skip_reqs=False,
                      hard_reset=False):
        """Updates a Git-based plugin

        Pulls changes from the remote, and checkout a specific revision.
        (will point to the tip of the branch if revision isn't given)
        :param plugin_name: Name of plugin to update.
        :param revision: Revision to checkout.
        :param skip_reqs: If True, will skip plugin requirements installation.
        :param hard_reset: Whether to drop all changes using git hard reset
        """
        if plugin_name not in self.PLUGINS_DICT:
            raise IRFailedToUpdatePlugin(
                "Plugin '{}' isn't installed".format(plugin_name))

        plugin = self.get_plugin(plugin_name)

        try:
            repo = git.Repo(plugin.path, search_parent_directories=True)
        except git.InvalidGitRepositoryError:
            raise IRFailedToUpdatePlugin(
                "Plugin '{}' isn't a Git-based plugin".format(plugin_name))

        # microseconds ('%f') required for unit testing
        timestamp = \
            datetime.datetime.fromtimestamp(
                time.time()).strftime('%B-%d-%Y_%H-%M-%S-%f')
        update_string = \
            'IR_Plugin_update_{plugin_name}_{timestamp}' \
            ''.format(plugin_name=plugin_name, timestamp=timestamp)

        LOG.debug("Checking for changes of tracked files "
                  "in {}".format(plugin.path))
        changed_tracked_files = \
            repo.git.status('--porcelain', '--untracked-files=no')
        all_changed_files = repo.git.status('--porcelain')

        if changed_tracked_files and not hard_reset:
            raise IRFailedToUpdatePlugin("Failed to update plugin {}\n"
                                         "Found changes in tracked files, "
                                         "please go to {}, and manually save "
                                         "your changes!".format(
                                             plugin_name, plugin.path))

        if hard_reset:
            if all_changed_files:
                repo.git.stash('save', '-u', update_string)
                LOG.warning("All changes have been "
                            "stashed - '{}'".format(update_string))
            repo.git.reset('--hard', 'HEAD')

        # checkout revision
        self._checkout_git_plugin_revision(repo, revision, update_string)

        if not hard_reset:
            # pull changes
            self._pull_git_plugin_changes(repo)

        if repo.git.status('--porcelain', '--untracked-files=no'):
            LOG.warning("Changes in tracked files have been found")

        if not skip_reqs:
            reqs_file = os.path.join(plugin.path, 'requirements.txt')
            if os.path.isfile(reqs_file):
                pip_main(['install', '-r', reqs_file])
Exemple #4
0
    def update_plugin(self,
                      plugin_name,
                      revision=None,
                      skip_reqs=False,
                      hard_reset=False):
        """Updates a Git-based plugin

        Pulls changes from the remote, and checkout a specific revision.
        (will point to the tip of the branch if revision isn't given)
        :param plugin_name: Name of plugin to update.
        :param revision: Revision to checkout.
        :param skip_reqs: If True, will skip plugin requirements installation.
        :param hard_reset: Whether to drop all changes using git hard reset
        """
        if plugin_name not in self.PLUGINS_DICT:
            raise IRFailedToUpdatePlugin(
                "Plugin '{}' isn't installed".format(plugin_name))

        repo = plugin = None
        try:
            plugin = self.get_plugin(plugin_name)
            repo = git.Repo(plugin.path)

            # microseconds ('%f') required for unit testing
            timestamp = \
                datetime.datetime.fromtimestamp(
                    time.time()).strftime('%B-%d-%Y_%H-%M-%S-%f')
            update_string = \
                'IR_Plugin_update_{plugin_name}_{timestamp}' \
                ''.format(plugin_name=plugin_name, timestamp=timestamp)

            LOG.debug("Checking for changes of tracked files "
                      "in {}".format(plugin.path))
            changed_tracked_files = \
                repo.git.status('--porcelain', '--untracked-files=no')
            all_changed_files = repo.git.status('--porcelain')

            if changed_tracked_files and not hard_reset:
                raise IRFailedToUpdatePlugin(
                    "Failed to update plugin {}\n"
                    "Found changes in tracked files, "
                    "please go to {}, and manually save "
                    "your changes!".format(plugin_name, plugin.path))

            if hard_reset:
                if all_changed_files:
                    repo.git.stash('save', '-u', update_string)
                    LOG.warning("All changes have been "
                                "stashed - '{}'".format(update_string))
                repo.git.reset('--hard', 'HEAD')

            LOG.warning("Create a branch '{}' that will point "
                        "to the current HEAD".format(update_string))
            repo.git.branch(update_string)

            LOG.debug("Fetching changes from the "
                      "'{}' remote".format(repo.remote().name))
            repo.git.fetch(repo.remote().name)

            repo.git.pull('--rebase')
            if revision not in (None, 'latest'):
                repo.git.reset(revision)
                if hard_reset:
                    repo.git.reset('--hard', 'HEAD')

            if repo.git.status('--porcelain', '--untracked-files=no'):
                LOG.warning("Changes in tracked files have been found")

            if not skip_reqs:
                reqs_file = os.path.join(plugin.path, 'requirements.txt')
                if os.path.isfile(reqs_file):
                    pip.main(['install', '-r', reqs_file])

        except git.InvalidGitRepositoryError:
            raise IRFailedToUpdatePlugin(
                "Plugin '{}' isn't a Git-based plugin".format(plugin_name))
        except ValueError:
            raise IRFailedToUpdatePlugin(
                "Failed to update '{}' plugin to point to '{}'".format(
                    plugin_name, revision))
        except git.exc.GitCommandError as ex:
            repo.git.rebase('--abort')
            raise IRFailedToUpdatePlugin(
                "Failed to update plugin"
                "Failed to update plugin!\nPlease go to plugin dir ({})"
                " and manually resolve Git issues.\n"
                "{}\n{}".format(plugin.path, ex.stdout, ex.stderr))