Exemplo n.º 1
0
Arquivo: igit.py Projeto: alexQi/iflow
def set_last_sync_master_date(branch):
    last_merge_date = ihelper.read_runtime('last_merge_date')

    if not last_merge_date:
        last_merge_date = {}

    last_merge_date[branch] = datetime.datetime.now().strftime('%Y-%m-%d')

    #垃圾回收:删除7天之前的记录
    for key, mdate in last_merge_date.items():
        if mdate and time.mktime(time.strptime(str(mdate), '%Y-%m-%d')) < time.time() - 604800:
            last_merge_date.pop(key)

    ihelper.write_runtime('last_merge_date', last_merge_date)
Exemplo n.º 2
0
def check_sprint():
    """
    迭代版本号检查
    """
    sprint = ihelper.read_runtime('sprint')

    if not sprint:
        raise exception.FlowException(u'尚未设置迭代版本号,请使用sp指令设置正确的迭代版本号')
    else:
        sp_date = get_date_from_sprint(sprint).split('-')
        now = time.strftime('%Y-%m-' + '01').split('-')
        d1 = datetime.datetime(int(sp_date[0]), int(sp_date[1]),
                               int(sp_date[2]))
        d2 = datetime.datetime(int(now[0]), int(now[1]), int(now[2]))
        diff = abs((d1 - d2).days)

        if diff >= 90:
            raise exception.FlowException(u'迭代版本号(' + sprint +
                                          u')和当前日期不符,请使用sp指令重新设置正确的迭代版本号')

    return True
Exemplo n.º 3
0
Arquivo: igit.py Projeto: alexQi/iflow
def check_product_branch_has_new_update():
    """
    检查生产分支是否有更新内容
    检查方法:获取远程生产分支的最近一次commitid,检验该commitid是否出现在当前分支中
    :return:
    """
    prod_branch = product_branch()
    curr_branch = current_branch()

    if curr_branch in [prod_branch, test_branch()]:
        return

    #一天只检验一次
    last_merge_date = ihelper.read_runtime('last_merge_date')
    if last_merge_date \
            and last_merge_date.has_key(curr_branch) \
            and last_merge_date[curr_branch] == datetime.datetime.now().strftime('%Y-%m-%d'):
        return

    info(u'正在检查%s分支有无更新...' % prod_branch)

    #拉取最新生产分支
    fetch(branch = prod_branch)

    #拉取最新当前分支
    fetch(branch=curr_branch)

    #获取生产分支最新一次提交的commit_id
    last_cmt_id = __get_last_commit_id(prod_branch)

    if not last_cmt_id:
        return

    #检查该commit_id是否在当前分支上
    if not ihelper.popen("git branch --list -a --contains %s *%s" % (last_cmt_id, curr_branch)).splitlines():
        warn(u'%s分支已有更新,请执行merge指令合并到当前分支' % prod_branch)
    else:
        set_last_sync_master_date(curr_branch)
Exemplo n.º 4
0
Arquivo: igit.py Projeto: alexQi/iflow
def check_workspace_health():
    """
    检查工作区是否健康:是否处于conflict、rebasing状态
    :return:
    """
    text = ihelper.popen('git status')

    if workspace_at_status(iglobal.GIT_CONFLICT, raw_text=text, use_cache=True):
        if workspace_at_status(iglobal.GIT_REBASING, raw_text=text, use_cache=True):
            warn(u'rebase出现冲突。请手工解决冲突后执行 git add . && git rebase --continue 继续完成操作。或者执行 git rebase --abort取消操作')
        elif workspace_at_status(iglobal.GIT_CHERRING, raw_text=text, use_cache=True):
            warn(u'cherry-pick出现冲突。请手工解决冲突后执行 git add . && git cherry-pick --continue 继续完成操作。或者执行git cherry-pick --abort取消操作')
        elif workspace_at_status(iglobal.GIT_MERGING, raw_text=text, use_cache=True):
            warn(u'merge出现冲突。请手工解决冲突后执行 git add . && git commit 完成合并操作。或者执行 git merge --abort取消操作')
        else:
            warn(u'当前工作区存在冲突,请手工处理冲突后执行 git add . && git commit 解决冲突')
    elif workspace_at_status(iglobal.GIT_REBASING, raw_text=text, use_cache=True):
        warn(u'工作区正处于rebasing中,请执行 git rebase --continue 完成操作')
    elif workspace_at_status(iglobal.GIT_CHERRING, raw_text=text, use_cache=True):
        warn(u'工作区正处于cherry picking中,请执行 git cherry-pick --continue 完成操作')
    elif workspace_at_status(iglobal.GIT_MERGING, raw_text=text, use_cache=True):
        warn(u'工作区正处于merging中,请执行 git commit 完成操作')
    elif ihelper.read_runtime('publish_branches'):
        warn(u'上次发布尚未完成,请解决冲突后执行 ft p --continue 继续完成发布。或者执行 ft p --abort 结束该发布')
Exemplo n.º 5
0
    def publish_to_master(self, branches=None):
        """
        发布分支到生产环境
        :param branches: 待发布分支列表:[(proj_name, branch)]
        """
        curr_p_branch = None
        tag_list = []

        if not branches:
            #接着上次的继续发布
            branches = ihelper.read_runtime('publish_branches')
            tag_list = ihelper.read_runtime('publish_tags') or []

        if not branches:
            info(u'没有需要发布的分支')
            return

        orig_branches = list(branches)

        try:
            curr_proj = None
            for index, item in enumerate(branches):
                curr_p_branch = item
                proj, branch = tuple(item)

                if iglobal.PROJECT != proj:
                    info(u'进入项目%s' % proj)
                    extra.Extra('cd', [proj]).execute()

                if not igit.workspace_is_clean():
                    raise exception.FlowException(
                        u'项目%s工作空间有未提交的更改,请先提交(或丢弃)后执行 %s p --continue 继续' %
                        (proj, self.cmd))

                # 首次进入项目执行fetch获取本地和远程分支差异
                if curr_proj != proj:
                    info('fetch...')
                    igit.fetch(useCache=False)

                # 切换到将要合并的分支(如果不存在本地分支则会自动创建)
                ihelper.execute('git checkout %s' % branch)

                # 同步当前本地和远程分支(此处可能会出现冲突)
                igit.sync_branch()

                # 切换到master分支
                ihelper.execute('git checkout %s' % igit.product_branch())

                is_last_branch = index >= len(
                    branches) - 1 or proj != branches[index + 1][0]

                # 合并
                info(u'合并%s...' % branch)
                igit.merge(branch,
                           need_pull=proj != curr_proj,
                           need_push=is_last_branch)
                info(u'合并完成:%s' % branch)

                # 完成
                orig_branches.remove(curr_p_branch)

                if proj != curr_proj:
                    curr_proj = proj

                # 本项目发布完成后的一些操作
                if is_last_branch:
                    self.__post_publish(proj, tag_list)

            ok(u'发布完成!tag:')

            # 打印tag信息
            for (proj_name, tag_name) in tag_list:
                info(' %s  %s' % (proj_name, tag_name))

            # 清空tag list
            tag_list = []
        except Exception, e:
            error(e.message)
            warn(u'处理完成后执行 %s p --continue 继续。或执行 %s p --abort 结束' %
                 (self.cmd, self.cmd))
Exemplo n.º 6
0
    def product(self, args):
        """
        发布到生产分支
        :param list args:
        :return:
        """
        continue_p = False
        abort_p = False
        branch_alias = {}
        tick = 1

        line_branches = []
        while args:
            c = args.pop(0)

            if c == '--abort':
                abort_p = True
            elif c == '--continue':
                continue_p = True
            else:
                if c.endswith(':'):
                    c += '*'
                line_branches.append(c)

        if abort_p:
            # 清除runtime后退出
            ok(u'取消发布')
            ihelper.write_runtime('publish_branches')
            ihelper.write_runtime('publish_tags')
            return

        if continue_p:
            # 继续上次的发布
            self.publish_to_master()
            return

        if ihelper.read_runtime('publish_branches'):
            error(u'上次发布尚未完成,请执行 %s p --continue 继续,或执行 %s p --abort 结束' %
                  (self.cmd, self.cmd))
            return

        branches = self.__resolve_branches(line_branches)
        for key, val in branches.items():
            if not val:
                branches.pop(key)

        if not branches:
            warn(u'没有需要发布的分支')
            return

        # 打印列表,并为分支设置别名
        warn(u'待发布分支列表:')
        for proj, p_brs in branches.items():
            ok(proj + u':')
            for pbr in p_brs:
                alias = 'f%s' % tick
                say(('white', ' [ '), ('green', alias),
                    ('white', ' ] %s' % pbr))
                branch_alias[alias] = (proj, pbr)
                tick += 1

        print
        info(u'1. 输入 "in 分支简称列表(f1 f2...,多个分支用空格隔开)" 告知系统要发布的分支。或者')
        info(u'2. 输入 "ex 分支简称列表" 告知系统要排除的分支。或者')
        info(u'3. 输入 all 发布以上列出的所有项目分支。或者')
        info(u'4. 输入 cancel 取消发布')
        print

        retr = True
        while retr:
            retr = False

            final_branches = self.__choose_branch_dialog(branch_alias)

            if final_branches == 'cancel':
                return

            print
            warn(u'将发布以下分支到生产环境:')

            the_proj = None
            for ele in final_branches:
                if the_proj != ele[0]:
                    the_proj = ele[0]
                    ok(ele[0] + ':')
                info('  ' + ele[1])

            print
            confirm = ihelper.confirm(u'请确认')
            if confirm == 'c':
                return
            elif confirm == 'n':
                # 返回分支选择
                info(u'请重新选择待发布分支...')
                retr = True
            elif confirm == 'y':
                # 开始执行发布,发布前先持久化待发布列表
                ihelper.write_runtime('publish_branches', final_branches)
                info(u'正在发布...')
                self.publish_to_master(final_branches)