<commit_before># -*- coding: utf-8 -*-
from datetime import datetime
from dateutil import tz

import humanize

from . import Command as _Command
from .. import io

from ...domain.vendor import NoChangesEmptyCommit
from ...domain.vendor import SyncRemoteError
from ...vendor.terraform import TFVarsConfig
from ...vendor import dockerhub, git_extensions


class Bump(_Command):
    def _validate_and_configure(self):
        super(self.__class__, self)._validate_and_configure()

        self.tf = TFVarsConfig(self.tfvars_path)
        self.tf.load()

        self.deployment_repo = self.config['TF_DEPLOYMENT_REPO']

        self.service_name = self.kwargs['service']
        self.service_name_normalized = self.tf.normalize_service_name(self.service_name)

        self.should_push = self.kwargs['should_push']
        self.is_latest = self.kwargs['is_latest']

        self.artifact_key = self.tf.get_artifact_key(self.service_name_normalized)

        io.info('authenticating "%s" against dockerhub' % self.config['DOCKER_ORG'])
        self.auth = dockerhub.DockerHubAuthentication(
            self.config['DOCKER_USERNAME'],
            self.config['DOCKER_PASSWORD'],
            self.config['DOCKER_ORG']
        )

    def _prompt_artifact_selection(self, artifacts):
        current_image = self.tf.get_var(self.artifact_key)

        io.info('found artifacts for "%s/%s"' % (self.config['DOCKER_ORG'], self.service_name))
        table_data = [
            ['id', 'tag name (* = current)', 'created at', 'size'],
        ]
        for i, artifact in enumerate(artifacts, 1):
            last_updated = datetime.strptime(artifact['last_updated'], '%Y-%m-%dT%H:%M:%S.%fZ')
            last_updated = last_updated.replace(tzinfo=tz.gettz('UTC'))
            last_updated = last_updated.astimezone(tz.tzlocal())

            last_updated_friendly = last_updated.strftime('%a %d %b, %I:%M%p')
            last_updated_humanized = humanize.naturaltime(last_updated.replace(tzinfo=None))

            updated_at = '%s (%s)' % (last_updated_friendly, last_updated_humanized)
            image_size = humanize.naturalsize(artifact['full_size'])
            image_name = artifact['name']
            if image_name in current_image:  # indicate the current artifact.
                image_name += ' *'

            table_data.append([i, image_name, updated_at, image_size])
        io.print_table(table_data, 'recent artifacts')

        # Handle the case where the selected artifact is the current artifact.
        selected_artifact = io.collect_input('select the artifact you want to use [q]:', artifacts)
        if selected_artifact and selected_artifact['name'] in current_image:
            io.err('selected artifact is already the current active artifact')
            return None
        return selected_artifact

    def _prompt_latest_confirmation(self, artifacts):
        latest_artifact = artifacts[0]
        tag = latest_artifact['name']

        input_ = io.collect_single_input('are you sure (latest: %s)? [y/n/q]:' % tag)
        if input_ not in ['y', None]:
            return None
        return latest_artifact

    def _get_artifact(self):
        io.info('retrieving image tags for "%s" from dockerhub' % self.service_name)
        artifacts = dockerhub.list_image_tags(self.auth, self.service_name)
        artifacts = artifacts[:10]

        if not artifacts:
            io.err('no artifacts were found for "%s/%s"' % (self.config['DOCKER_ORG'], self.service_name))
            return None

        if self.is_latest:
            return self._prompt_latest_confirmation(artifacts)
        return self._prompt_artifact_selection(artifacts)

    def _run(self):
        artifact = self._get_artifact()

        did_sync = git_extensions.sync_updates(self.deployment_repo)
        if not did_sync:
            raise SyncRemoteError('failed to sync "%s" repo' % self.deployment_repo.working_dir)

        if artifact is None:  # An artifact wasn't selected, end command.
            return None<commit_msg>fix(commands/bump): successful syncs should error out<commit_after># -*- coding: utf-8 -*-
from datetime import datetime
from dateutil import tz

import humanize

from . import Command as _Command
from .. import io

from ...domain.vendor import NoChangesEmptyCommit
from ...domain.vendor import SyncRemoteError
from ...vendor.terraform import TFVarsConfig
from ...vendor import dockerhub, git_extensions


class Bump(_Command):
    def _validate_and_configure(self):
        super(self.__class__, self)._validate_and_configure()

        self.tf = TFVarsConfig(self.tfvars_path)
        self.tf.load()

        self.deployment_repo = self.config['TF_DEPLOYMENT_REPO']

        self.service_name = self.kwargs['service']
        self.service_name_normalized = self.tf.normalize_service_name(self.service_name)

        self.should_push = self.kwargs['should_push']
        self.is_latest = self.kwargs['is_latest']

        self.artifact_key = self.tf.get_artifact_key(self.service_name_normalized)

        io.info('authenticating "%s" against dockerhub' % self.config['DOCKER_ORG'])
        self.auth = dockerhub.DockerHubAuthentication(
            self.config['DOCKER_USERNAME'],
            self.config['DOCKER_PASSWORD'],
            self.config['DOCKER_ORG']
        )

    def _prompt_artifact_selection(self, artifacts):
        current_image = self.tf.get_var(self.artifact_key)

        io.info('found artifacts for "%s/%s"' % (self.config['DOCKER_ORG'], self.service_name))
        table_data = [
            ['id', 'tag name (* = current)', 'created at', 'size'],
        ]
        for i, artifact in enumerate(artifacts, 1):
            last_updated = datetime.strptime(artifact['last_updated'], '%Y-%m-%dT%H:%M:%S.%fZ')
            last_updated = last_updated.replace(tzinfo=tz.gettz('UTC'))
            last_updated = last_updated.astimezone(tz.tzlocal())

            last_updated_friendly = last_updated.strftime('%a %d %b, %I:%M%p')
            last_updated_humanized = humanize.naturaltime(last_updated.replace(tzinfo=None))

            updated_at = '%s (%s)' % (last_updated_friendly, last_updated_humanized)
            image_size = humanize.naturalsize(artifact['full_size'])
            image_name = artifact['name']
            if image_name in current_image:  # indicate the current artifact.
                image_name += ' *'

            table_data.append([i, image_name, updated_at, image_size])
        io.print_table(table_data, 'recent artifacts')

        # Handle the case where the selected artifact is the current artifact.
        selected_artifact = io.collect_input('select the artifact you want to use [q]:', artifacts)
        if selected_artifact and selected_artifact['name'] in current_image:
            io.err('selected artifact is already the current active artifact')
            return None
        return selected_artifact

    def _prompt_latest_confirmation(self, artifacts):
        latest_artifact = artifacts[0]
        tag = latest_artifact['name']

        input_ = io.collect_single_input('are you sure (latest: %s)? [y/n/q]:' % tag)
        if input_ not in ['y', None]:
            return None
        return latest_artifact

    def _get_artifact(self):
        io.info('retrieving image tags for "%s" from dockerhub' % self.service_name)
        artifacts = dockerhub.list_image_tags(self.auth, self.service_name)
        artifacts = artifacts[:10]

        if not artifacts:
            io.err('no artifacts were found for "%s/%s"' % (self.config['DOCKER_ORG'], self.service_name))
            return None

        if self.is_latest:
            return self._prompt_latest_confirmation(artifacts)
        return self._prompt_artifact_selection(artifacts)

    def _run(self):
        artifact = self._get_artifact()
        git_extensions.sync_updates(self.deployment_repo)

        if artifact is None:  # An artifact wasn't selected, end command.
            return None
{'fraction_non_alphanumeric': 0.10770775797137835, 'fraction_numerical': 0.0012553351744915891, 'mean_word_length': 2.934320987654321, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '640552', 'n_tokens_mistral': 2420, 'n_tokens_neox': 2270, 'n_words': 511}