Beispiel #1
0
def main():
    """
    常量信息最好通过配置文件输入
    当存在delete_build文件,且这次push的commit数量为0的时候删除build。
    否则继续进行代码规范检测
    """
    if os.path.isfile('delete_build'):
        repo = Github('jiyaodian', 'mm6801112').get_user().get_repo('jydtest')
        event = repo.get_events()[0]
        if event.payload['size'] == 0:
            print 'delete build'
            #delete_build()
        os.remove('delete_build')
        code = 0
    else:
        style_check = StyleCheck('jydtest', REPO_HOME, 'jiyaodian', 'mm6801112')
        code = style_check.test()
    return code
Beispiel #2
0
class StyleCheck:
    """
    运行test进行测试
    """
    def __init__(self, repo_name, local_repo_home, git_user, git_pwd):
        """
        初始化工作,没有考虑异常
        如果event.payload['size']为0,直接返回
        """
        self.repo = Github(git_user, git_pwd).get_user().get_repo(repo_name)
        self.event = self.repo.get_events()[0]
        if self.event.payload['size'] == 0:
            return
        tmp = self.event.payload['commits'][0]['sha']
        self.before_sha = self.repo.get_commit(tmp).parents[0].sha
        self.git_url = u'[email protected]:'+self.repo.full_name+u'.git'
        self.local_repo_home = local_repo_home
        self.repo_dir = local_repo_home + '/'+repo_name+'/'

        self.logger = init_log()

    def run_command(self, args, cwd=os.environ['WORKSPACE']):
        """
        运行命令
        """
        try:
            proc = subprocess.Popen(args, stdout=subprocess.PIPE, \
                    stderr=subprocess.PIPE, cwd=cwd)
        except OSError:
            self.logger.error(str(sys.exc_info()))
        if DEBUG:
            print ' '.join(args)
        self.logger.info(' '.join(args))
        return proc.communicate()

    def git_clone(self):
        """
        git clone
        """
        (results, code) = self.run_command(('git', 'clone', self.git_url), \
                cwd=self.local_repo_home)
        if DEBUG:
            print code
            print results

    def git_pull(self):
        """
        pull the newest data
        """
        (results, code) = self.run_command(('git', 'pull'), self.repo_dir)
        if DEBUG:
            print code
            print results

    def git_reset(self):
        """
        hard-reset
        """
        (results, code) = self.run_command(('git', 'reset', '--hard', \
                self.before_sha), self.repo_dir)
        if DEBUG:
            print code
            print results
        (results, code) = self.run_command(('git', 'push', '--force'), \
                self.repo_dir)
        if DEBUG:
            print code
            print results

    def single_style_check(self, code_path):
        """
        检查代码风格,返回检查结果和分数
        """
        try:
            (results, code) = self.run_command(('pylint', '-f', 'parseable', 
                code_path), self.repo_dir)
        except Exception:
            print 'run pylint error'
            return ("", 0)
        if DEBUG:
            print "error info", code
        try:
            score = float([r for r in results.split('\n') if
                    r.startswith('Your code')][0].split(' ')[6].split('/')[0])
        except Exception:
            score = None
        return (results, score)

    def test(self):
        """
        进行代码检测
        如果event里面commit数量为0,或者event不是PushEent类型,直接返回
        """
        if self.event.payload['size'] == 0 or self.event.type != 'PushEvent': #没有commit,直接返回,不用进行代码检测
            return 2
        if not os.path.exists(self.repo_dir):
            self.git_clone()
        else:
            self.git_pull()

        pylint_log = codecs.open('pylint.log', 'w', 'utf-8')
        style_pass = True
        file_list = self.get_file_list()

        for file_path in file_list:
            (detail, score) = self.single_style_check(file_path)
            if score is not None:
                if score < PYLINT_MIN_SCORE:
                    style_pass = False
                print detail
                pylint_log.writelines(detail)
            else:
                print 'score is None'
        pylint_log.close()

        if style_pass is False:
            self.git_reset()
            tmp_f = open('delete_build', 'w')
            tmp_f.write(os.environ['BUILD_NUMBER'])
            tmp_f.close()
            return 1
        return 0

    def get_ignore_list(self):
        """
        从配置文件中读取不进行代码检测的文件列表
        配置文件规则:
        每行一个相对路径
        以.py结尾,则认为是文件 ------> 通过file_name in ignore_list 判断
        否则认为是文件夹-----> startswith 进行判断
        return: (文件夹名列表, 文件名列表)
        """
        pass

    def get_file_list(self):
        """
        从payload字典中获取commits的sha,在通过sha获取commit,
        然后从commit里面得到修改的文件
        只检查.py文件
        """
        file_list = []
        #ignore_list = []
        for i in self.event.payload['commits']:
            commit = self.repo.get_commit(i['sha'])
            for j in commit.files:
                if DEBUG:
                    print i['sha'], j.filename, j.status
                if j.filename.endswith('.py'):
                    if j.status == "added" or j.status == 'modified':
                        file_list.append(j.filename)
                    file_list = list(set(file_list))
                    if j.status == 'removed' and j.filename in file_list:
                        file_list.remove(j.filename)
        return file_list