Beispiel #1
0
    def process(self):
        if not self.__gitflow.is_release():
            raise NoBranchSelected('Checkout to release branch before')

        if not self.__git.is_clean_working_tree():
            raise NotCleanWorkingTree()

        self.__pull_master()

        if self.__git.is_branch_ahead(self.__config_handler.master(),
                                      self.__name):
            Log.error("""

            {fg_fail}{list}{reset_fg}

                        """.format(
                fg_fail=Fg.FAIL.value,
                list=self.__git.list_commit_diff(
                    self.__config_handler.master(), self.__name),
                reset_fg=Fg.RESET.value,
            ))
            self.__checkout_current_release()

            raise BranchHaveDiverged("""
    
    {fg_fail}{message}{reset_fg}
    
                            """.format(
                fg_fail=Fg.FAIL.value,
                message='Oups !!! Master:' + self.__config_handler.master() +
                ' have commit ahead ' + self.__name + ' merge before',
                reset_fg=Fg.RESET.value,
            ))

        self.__pull_develop().__finish_release()
    def __attach(self) -> bool:

        topic_number: int
        if self.__would_attach_topics():

            for topic_number in self.__topics_number():

                request_topic: FlexioTopic = FlexioTopic().with_number(
                    topic_number)

                try:
                    Log.info('waiting... from Flexio... Topic : ' +
                             str(topic_number))
                    topic: FlexioTopic = self.__get_topic_with_number(
                        request_topic)
                    CommonTopic.print_resume_topic(topic)
                    self.__topics.append(topic)
                except FileNotFoundError:
                    Log.error(Fg.FAIL.value + 'Topic not found : retry' +
                              Fg.RESET.value)
                    self.__topics = []
                    return self.process()
            return True
        else:
            return False
Beispiel #3
0
    def process(self):
        if not self.__git.is_clean_working_tree():
            raise NotCleanWorkingTree()
        if not self.__gitflow.is_feature():
            raise BranchNotExist(self.__config_handler.feature())

        self.__pull_develop()
        if self.__git.is_branch_ahead(self.__config_handler.develop(),
                                      self.__current_branch_name):
            Log.error("""

{fg_fail}{list}{reset_fg}

            """.format(
                fg_fail=Fg.FAIL.value,
                list=self.__git.list_commit_diff(
                    self.__config_handler.develop(),
                    self.__current_branch_name),
                reset_fg=Fg.RESET.value,
            ))
            self.__checkout_current_feature()
            raise BranchHaveDiverged("""
    
{fg_fail}{message}{reset_fg}
    
                            """.format(
                fg_fail=Fg.FAIL.value,
                message='Oups !!! Develop have commit ahead ' +
                self.__current_branch_name + ' merge before',
                reset_fg=Fg.RESET.value,
            ))

        self.__finish_feature()
Beispiel #4
0
    def __merge_develop(self) -> Finish:
        self.__checkout_current_feature()

        message: Message = Message(message=''.join([
            "'Finish feature ` ", self.__current_branch_name, " ` for dev: ",
            self.__state_handler.version_as_str()
        ]),
                                   issue=self.__issue)

        message_str: str = ''
        if self.__close_issue:
            message_str = message.with_close()
        else:
            message_str = message.message

        self.__git.commit(message_str, ['--allow-empty']).try_to_push()

        self.__git.checkout(self.__config_handler.develop(
        )).merge_with_version_message_from_branch_name(
            branch=self.__current_branch_name,
            message=Message(message='', issue=self.__issue).with_ref(),
        ).try_to_push()

        if self.__git.has_conflict():
            Log.error("""

{fg_fail}CONFLICT : resolve conflict, and remove your feature branch manually{reset_fg}

""".format(
                fg_fail=Fg.FAIL.value,
                reset_fg=Fg.RESET.value,
            ))
            raise GitMergeConflictError(self.__config_handler.develop(),
                                        self.__git.get_conflict())
        return self
Beispiel #5
0
    def comment_issue_with_topic(self, topic: Topic) -> IssueBuilder:
        if self.__issue is not None:
            Log.info('Waiting... Comment issue with topics : ' +
                     str(topic.number))
            self.__issuer.comment(self.__issue, 'Topic : ' + topic.url())

        return self
Beispiel #6
0
 def create_branch_from(self, target_branch_name: str, source: str) -> GitCmd:
     source_branch_name: str = self.get_branch_name_from_git(source)
     self.__exec(['git', 'checkout', '-b', target_branch_name, source_branch_name])
     try:
         self.__state_handler.load_file_config()
     except FileNotFoundError as e:
         Log.error(str(e))
     return self
 def init_repo(cls, version: str) -> StateHandler:
     cls.clean_workdir()
     cls.mount_workdir_and_clone()
     state_handler: StateHandler = StateHandler(cls.DIR_PATH_TEST)
     state_handler.state = cls.fake_state(version)
     Git(state_handler).build_branch(Branches.DEVELOP).with_action(
         Actions.INIT).process()
     Log.info('init repo : ' + str(version))
     return state_handler
 def clean_remote_repo(cls, version: Version = Version(0, 0, 0)):
     git: GitCmd = GitCmd(
         state_handler=StateHandler(TestGitFlowHelper.DIR_PATH_TEST))
     git.checkout(Branches.MASTER).reset_to_tag(cls.TAG_INIT) \
         .push_force() \
         .delete_remote_branch_from_name(Branches.DEVELOP.value) \
         .delete_tag(str(version), remote=True) \
         .delete_tag('-'.join([str(version.next_minor()), Level.DEV.value]), remote=True)
     Log.info('clean remote repo : ' + str(version))
Beispiel #9
0
 def ensure_develop_branch(self) -> GitFlowCmd:
     Log.info('Ensure have Develop branch : ' +
              self.__config_handler.develop())
     if not self.__git.branch_exists(self.__config_handler.develop()):
         self.__git.checkout(
             self.__config_handler.master()).create_branch_from(
                 self.__config_handler.develop(),
                 self.__config_handler.master()).try_to_set_upstream(
                 ).try_to_push()
     return self
Beispiel #10
0
    def process(self):
        Log.info('Start unstable version precheck')

        scheme: Schemes
        for scheme in self.state_handler.state.schemes:
            Log.info('Precheck for : ' + scheme.value)
            sc: Scheme = SchemeBuilder.create(scheme, self.state_handler)
            dev_dependencies: Dependencies = sc.release_precheck()
            print(dev_dependencies.__dict__())
            if len(dev_dependencies):
                raise HaveDevDependencyException(dev_dependencies)
Beispiel #11
0
 def __list_topics(self, count: int):
     Log.info('waiting... Flexio... last 100 Topics')
     records: List[dict] = self.__get_last_100_records()
     for t_d in records:
         t: FlexioTopic
         t = FlexioTopic.build_from_api(t_d)
         print(
             '{fg_cyan}{topic_number!s} : {topic_title!s}{reset_fg}'.format(
                 fg_cyan=Fg.INFO.value,
                 reset_fg=Fg.RESET.value,
                 topic_number=t.number,
                 topic_title=t.title))
     return self.__topics_number()
Beispiel #12
0
 def has_repo(self) -> bool:
     has_repo: bool = False
     try:
         repo: Repo = GitCmd(self.state_handler,
                             self.options.debug).with_config_handler(
                                 self.config_handler).get_repo()
         has_repo = True
     except ValueError as e:
         if self.options.debug:
             print(e)
         Log.info('GithubIssuer have not repo')
     finally:
         return has_repo
Beispiel #13
0
    def __ensure_stash_start(self):
        if not self.options.auto_stash and not self.options.default:
            if self.options.no_cli is not True:
                auto_stash: str = input(' Stash your working tree Y/N : ' +
                                        Fg.SUCCESS.value + 'N' +
                                        Fg.RESET.value + ' ')
                auto_stash_b = True if auto_stash.capitalize(
                ) == 'Y' else False
                self.options.auto_stash = auto_stash_b

        if self.options.auto_stash:
            self.version_control.stash_start()
            Log.info('Working tree stashed')
Beispiel #14
0
    def find_issue_from_branch_name(self) -> IssueBuilder:
        if self.__issuer is not None:
            issue_number: Optional[
                int] = self.__version_control.get_issue_number()

            if issue_number is not None:
                self.__issue = self.__issuer.issue_builder().with_number(
                    issue_number)
                if self.__issue is not None:
                    Log.info('Issue number ' + str(self.__issue.number) +
                             ' found')
            else:
                Log.info('No Issue found')
        return self
Beispiel #15
0
    def is_clean_working_tree(self) -> bool:
        if len(self.__exec_for_stdout(['git', 'rev-parse', '--verify', 'HEAD'])) == 0:
            return False
        self.__exec(['git', 'update-index', '-q', '--ignore-submodules', '--refresh'])

        if len(self.__exec_for_stdout(['git', 'diff-files', '--ignore-submodules'])) > 0:
            Log.error("Working tree contains unstaged changes. Aborting.")
            return False

        if len(self.__exec_for_stdout(
                ['git', 'diff-index', '--cached', '--ignore-submodules', 'HEAD'])) > 0:
            Log.error("Index contains uncommited changes. Aborting.")
            return False

        return True
Beispiel #16
0
    def find_topic_from_branch_name(self) -> TopicBuilder:
        if self.__topicer is not None:
            topics_number: Optional[List[int]] = self.__version_control.get_topics_number()
            if topics_number is not None and len(topics_number) > 0:
                self.__topics = []
                for number in topics_number:
                    self.__topics.append(self.__topicer.topic_builder().with_number(number))

            if self.__topics is not None and len(self.__topics) > 0:
                for topic in self.__topics:
                    Log.info('Topic number ' + str(topic.number) + ' found')
            else:
                Log.info('No Topic found')

        return self
Beispiel #17
0
class UserController:
    def __init__(self):
        self.logger = Log("AdminController")
        self.STATES = dict()
        self.NEXT_STATES = dict()

    def update_create_user(self, chat):
        try:
            user = User.objects.filter(chat_id=chat.id).first()
            if user:
                user.last_checked_bot = timezone.now()
                user.state = self.NEXT_STATES[user.state]
                user.save(force_update=True)
                return user
            else:
                self.logger.info("New User start subX : \n{}".format(chat))
                username = chat.username
                last_name = chat.last_name
                first_name = chat.first_name
                new_user = User(chat_id=chat.id,
                                username=username,
                                first_name=first_name,
                                last_name=last_name,
                                chat_type=chat.type)
                new_user.save(force_insert=True)
                return user
        except Exception as e:
            self.logger.error("update_create_user : {}".format(e))

    def update_user_state(self, chat_id, user=None):
        if user is None:
            user = User.objects.filter(chat_id=chat_id).first()
            if not user:
                raise NotImplementedError(
                    "user {} not implemented".format(chat_id))
        user.state = self.NEXT_STATES[user.state]
        user.save(force_update=True)
        return user.state

    @staticmethod
    def get_user_state(chat_id):
        return User.filter.objects(chat_id=chat_id).first().state

    def set_states(self, states):
        self.STATES = states

    def set_next_states_dict(self, next_states):
        self.NEXT_STATES = next_states
Beispiel #18
0
    def __input_topics(self) -> Init:

        if self.config_handler.has_topicer():
            self.__topicer: Optional[Topicer] = TopicerHandler(
                self.state_handler, self.config_handler).topicer()

            self.__topics: List[Topic] = self.__topicer.attach_or_create()
            self.state_handler.state.topics = []
            for topic in self.__topics:
                self.state_handler.state.topics.append(
                    DefaultTopic().with_number(topic.number))
        else:
            Log.info('No topicer found')
            self.state_handler.state.topics = None

        return self
Beispiel #19
0
    def __merge_develop(self) -> Finish:
        self.__checkout_current_hotfix()
        self.__state_handler.next_dev_minor()
        self.__state_handler.set_dev()
        self.__state_handler.write_file()
        UpdateSchemeVersion.from_state_handler(self.__state_handler)
        self.__git.commit(
            Message(message=''.join([
                "'Finish hotfix for dev: ",
                self.__state_handler.version_as_str()
            ]),
                    issue=self.__issue).with_ref()).try_to_push()

        self.__git.checkout(
            self.__config_handler.develop()).merge_with_version_message(
                branch=self.__config_handler.hotfix(),
                message=Message(message='',
                                issue=self.__issue).with_ref()).try_to_push()
        if (self.__git.has_conflict()):
            Log.error("""

{fg_fail}CONFLICT : resolve conflict, and remove your hotfix branch manually{reset_fg}

            """.format(
                fg_fail=Fg.FAIL.value,
                reset_fg=Fg.RESET.value,
            ))
            raise GitMergeConflictError(self.__config_handler.develop(),
                                        self.__git.get_conflict())

        self.__git.checkout(self.__config_handler.develop()).merge_with_theirs(
            branch=self.__config_handler.master()).try_to_push()
        if (self.__git.has_conflict()):
            Log.error("""

        {fg_fail}CONFLICT : resolve conflict, and remove your hotfix branch manually{reset_fg}

                    """.format(
                fg_fail=Fg.FAIL.value,
                reset_fg=Fg.RESET.value,
            ))
            raise GitMergeConflictError(self.__config_handler.develop(),
                                        self.__git.get_conflict())

        return self
Beispiel #20
0
    def __merge_master(self) -> Finish:
        self.__git.checkout(self.__config_handler.hotfix())
        self.__state_handler.set_stable()
        self.__state_handler.write_file()
        UpdateSchemeVersion.from_state_handler(self.__state_handler)

        message: Message = Message(message=''.join([
            "'Finish hotfix for master: ",
            self.__state_handler.version_as_str()
        ]),
                                   issue=self.__issue)

        message_str: str = ''
        if self.__close_issue:
            message_str = message.with_close()
        else:
            message_str = message.message

        self.__git.commit(message_str).try_to_push()

        self.__git.checkout(
            self.__config_handler.master()).merge_with_version_message(
                branch=self.__config_handler.hotfix(),
                message=Message(message='', issue=self.__issue).with_ref(),
                options=['--no-ff']).tag(
                    self.__state_handler.version_as_str(), ' '.join([
                        "'From Finished hotfix : ",
                        self.__git.get_branch_name_from_git(
                            self.__config_handler.hotfix()), 'tag : ',
                        self.__state_handler.version_as_str(), "'"
                    ])).try_to_push_tag(
                        self.__state_handler.version_as_str()).try_to_push()

        if (self.__git.has_conflict()):
            Log.error("""

{fg_fail}CONFLICT : resolve conflict, merge into develop and remove your hotfix branch manually{reset_fg}

            """.format(
                fg_fail=Fg.FAIL.value,
                reset_fg=Fg.RESET.value,
            ))
            raise GitMergeConflictError(self.__config_handler.master(),
                                        self.__git.get_conflict())
        return self
Beispiel #21
0
    def __merge_master(self) -> Finish:

        message: Message = Message(message='Merge ' + self.__name + 'into ' +
                                   self.__config_handler.master(),
                                   issue=self.__issue)

        message_str: str = ''
        if self.__close_issue:
            message_str = message.with_close()
        else:
            message_str = message.message

        self.__git.commit(message_str, ['--allow-empty'])

        self.__git.checkout(
            self.__config_handler.master()).merge_with_version_message(
                branch=self.__config_handler.release(),
                message=message_str,
                options=['--no-ff', '--strategy-option', 'theirs'])

        if self.__git.has_conflict():
            raise GitMergeConflictError(self.__config_handler.master(),
                                        self.__git.get_conflict())

        tag: str = self.__state_handler.version_as_str()

        if tag != self.__version_check:
            Log.error('Version have diverged during merge : ' + tag +
                      'should be ' + self.__version_check)
            raise GitMergeConflictError(self.__config_handler.master())

        self.__git.tag(
            tag, ' '.join(
                ["'From Finished release : ", self.__name, 'tag : ', tag,
                 "'"])).try_to_push_tag(tag).try_to_push()

        self.__git.checkout(self.__config_handler.release(
        )).merge_with_version_message_from_branch_name(
            branch=tag,
            message=Message(message='Merge ' + tag + ' tag into ' +
                            self.__name,
                            issue=self.__issue).with_ref(),
            options=['--no-ff'])

        return self
Beispiel #22
0
    def __init_develop(self) -> Init:
        version: str = '-'.join(
            [str(self.__state_handler.state.version), Level.DEV.value])

        self.__git.checkout_without_refresh_state(
            self.__config_handler.develop())

        self.__state_handler.write_file()
        UpdateSchemeVersion.from_state_handler(self.__state_handler)

        self.__git.add_all().commit(''.join([
            "'Init develop as branch name: ",
            self.__config_handler.develop(), " at version:", version, "'"
        ])).try_to_set_upstream()

        Log.info('Init develop as branch name: ' +
                 self.__config_handler.develop() + ' at version: ' + version)
        return self
Beispiel #23
0
    def process(self):
        if self.action is IssueActions.READ:

            issuer_builder: issuer_builder = IssueBuilder(
                self.version_control, self.state_handler, self.config_handler,
                None, self.options)

            issue: Optional[
                AbstractIssue] = issuer_builder.find_issue_from_branch_name(
                ).issue()

            if issue is not None:
                Log.info('waiting... from github...')
                read_issue: Optional[AbstractIssue] = issuer_builder.issuer(
                ).read_issue_by_number(issue.number)
                if read_issue is not None:
                    pprint(read_issue.__dict__())

        elif self.action is IssueActions.COMMENT:
            raise NotImplementedError
Beispiel #24
0
    def __attach(self) -> bool:
        if self.__would_attach_issue():
            issue_number = self.__number_issue()
            issue: IssueGithub = IssueGithub().with_number(issue_number)

            try:
                Log.info('waiting... from Github... Issue : ' +
                         str(issue_number))

                r: Response = self.__read_issue(issue)
                self.__issue: IssueGithub = IssueGithub.from_api_dict(r.json())
                CommonIssue.print_resume_issue(self.__issue)
            except FileNotFoundError:
                Log.error(Fg.FAIL.value + 'Issue not found : retry' +
                          Fg.RESET.value)
                return self.process()

            return True
        else:
            return False
Beispiel #25
0
    def try_ensure_topic(self) -> TopicBuilder:

        if self.__config_handler.has_topicer() and self.__topicer is not None:
            if self.__state_handler.has_default_topic():

                Log.info('waiting for... default Topics...')
                self.__build_default()
                Log.info(str(len(self.__topics)) + ' Topics found')

                if self.__topics is not None:
                    for topic in self.__topics:
                        CommonTopic.print_resume_topic(topic)

                    if not self.__options.default:

                        use_default_topic: str = input(
                            'Use these topics ' + Fg.SUCCESS.value + 'y' + Fg.RESET.value + '/n : ')
                        if use_default_topic.lower() == 'n':
                            self.__topics = None
            else:
                Log.info('No default Topic found')

            if self.__topics is None and not self.__options.default:
                self.__topics: List[Topic] = self.__topicer.attach_or_create()

        return self
Beispiel #26
0
    def is_local_remote_equal(self, branch: str) -> bool:
        if not self.branch_exists(branch):
            raise BranchNotExist(branch)

        local_branch: str = self.local_branch_name(branch)
        remote_branch: str = self.remote_branch_name(branch)
        compare_refs: int = self.compare_refs(local_branch, remote_branch)

        if compare_refs > 0:
            print("Branches '{local_branch!s}' and '{remote_branch!s}' have diverged.".format(local_branch=local_branch,
                                                                                              remote_branch=remote_branch))
            if compare_refs == 1:
                print("And branch '{local_branch!s}' may be fast-forwarded.".format(local_branch=local_branch))
            elif compare_refs == 2:
                print("And local branch '{local_branch!s}' is ahead of '{remote_branch!s}'.".format(
                    local_branch=local_branch,
                    remote_branch=remote_branch
                ))
            else:
                Log.warning("Branches need merging first.")
            return False
        return True
Beispiel #27
0
    def __ensure_is_major(self, branch: Branch) -> Branch:
        if self.branch is Branches.RELEASE:
            if not self.version_control.is_current_branch_develop():
                raise NoBranchSelected('Checkout to develop branch before')
            is_major_b: bool = False

            if self.options.major is None and not self.options.default:
                if self.options.no_cli is not True:
                    is_major: str = input(' Is major Release Y/N : ' +
                                          Fg.SUCCESS.value + 'N' +
                                          Fg.RESET.value + ' ')
                    is_major_b = True if is_major.capitalize(
                    ) == 'Y' else False
                    self.options.major = is_major_b

            else:
                is_major_b = self.options.major is True
                if is_major_b:
                    Log.info('Release option Major set from options')

            branch.with_major(is_major=is_major_b)
        return branch
Beispiel #28
0
    def process(self):

        if self.action is TopicActions.READ:
            topic_builder: TopicBuilder = TopicBuilder(self.version_control,
                                                       self.state_handler,
                                                       self.config_handler,
                                                       None, self.options)

            topics: Optional[List[
                AbstractTopic]] = topic_builder.find_topic_from_branch_name(
                ).topics()

            if topics is not None and len(topics) > 0:
                for topic in topics:
                    Log.info('waiting... from flexio...')

                    read_topic: Optional[
                        AbstractTopic] = topic_builder.topicer(
                        ).read_topic_by_number(int(topic.number))
                    if read_topic is not None:
                        CommonTopic.print_resume_topic(read_topic)
            else:
                Log.warning('No Topic found')
Beispiel #29
0
 def ensure_master_branch(self) -> GitFlowCmd:
     Log.info('Ensure have Master branch : ' +
              self.__config_handler.master())
     if not self.__git.local_branch_exists(self.__config_handler.master()):
         if not self.__git.remote_branch_exists(
                 self.__config_handler.master()):
             Log.warning(self.__config_handler.master() + ' not exists')
             create: str = input('Create ' +
                                 self.__config_handler.master() +
                                 ' from current branch ?  y/' +
                                 Fg.SUCCESS.value + 'n' + Fg.RESET.value +
                                 ' : ')
             if create == 'y':
                 self.__git.create_branch_from(
                     self.__config_handler.master(),
                     self.__git.get_current_branch_name()
                 ).try_to_set_upstream().try_to_push()
                 self.ensure_master_branch()
             else:
                 raise BranchNotExist(self.__config_handler.master())
         else:
             Log.error('Remote branch : ' + self.__config_handler.master() +
                       ' already exists, pull before')
     return self
Beispiel #30
0
 def __ensure_stash_end(self):
     if self.options.auto_stash:
         self.version_control.stash_end()
         Log.info('Stashed work restored ')