美文网首页
infer objective-C 如何实现增量分析

infer objective-C 如何实现增量分析

作者: 令狐冲_ | 来源:发表于2021-12-03 14:35 被阅读0次

    背景:

    公司需要接入infer,但是技委会那边提供的脚本只支持全量,脚本代码如下:

    infer run --keep-going --skip-analysis-in-path Pods --compilation-database $compile_commands_path &> $inferlog_path
    

    单次infer执行的时长特别的长,非常影响构建机的其他工作效率,我们希望能够把全量改为增量,只分析当前分支最近一次提交修改的文件即可,不需要次次走全量。

    infer工作流程

    infer-run指令实际分为两步

    1. infer-capture
      这个指令相当于infer的编译操作,会把当前语言翻译成infer自己内部的中间语言,这个翻译过程类似于编译,并把中间文件存储在results目录中,该目录存储在这一步生成的infer-out文件夹,里面有全部的分析结果。
    2. infer-analysis
      分析阶段,这时候infer会分析infer-out文件夹中的文件,每个函数,每个方法,并把错误输出在infer-out/report.txt
      现在我们知道了infer-run具体的工作流程是以上两步,我们不难得出infer-analysis这一步是可以优化的想法,我们不需要每次都分析所有的文件,只需要分析有变化的文件即可。

    优化思路

    我的思路如下:

    1. 保存infer-out
      为什么要保存infer-out,因为我司使用gitlab CI/CD的runner来触发工作流的,导致每次都会重新初始化仓库,删除之前所有的无关变量,包括infer-out(这个文件夹包含了上一次的扫描结果),所以我们要想办法存储上一次的infer-out,并且在下一次分析的时候把它重新拉回来。
    2. infer分析步骤只分析差异性文件

    需要注意的点

    1. 一台构建机上可能有多个runner;
    2. 每个runner可以执行多个项目;
    3. 每个项目可以有多个分支;

    实现方式

    1. 在根目录下按照runner ID 建立多个目录,保证每个runner之间互不干涉;
    2. 在runner目录下按照项目建立新的目录,保证每个项目都可以保存自己的infer分析结果;
    3. 在项目目录下按照分支保存infer分析结果;
      例如保存目录如下


      image.png

    这样做的优点在于,每个runner之间跑的结果互不干涉,且可以保存多个项目多个分支的分析结果。

    代码实现如下

    # infer
    echo "🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵  🍵   infer working... "
    
    infer_start_time=$(date +%s)
    execute_infer(){
         # --skip-analysis-in-path 是忽略扫描目录  --keep-going 忽略错误继续运行
        if which infer >/dev/null; then
            #当前分支名
            echo "============当前分支名称$CI_COMMIT_REF_NAME============="
            #上次保存的目录
            lastInferoutPath="$HOME/$CI_RUNNER_TAGS-infer-out/$CI_PROJECT_NAME/$CI_COMMIT_REF_NAME/infer-out/"
            #看看上次有没有记录
            if [ -d ${lastInferoutPath} ]; then
                #当前infer扫描保存目录
                currentInferoutPath="$CI_PROJECT_DIR/infer-out"
                cp -Rf ${lastInferoutPath} ${currentInferoutPath}
                echo "=========获取infer-out成功,走增量分析流程========="
                # 获取当前分支最近一次提交修改的文件
                git diff --name-only HEAD~ HEAD > change.txt
                # capture 操作
                infer-capture --reactive \
                --keep-going \
                --compilation-database $compile_commands_path &> $inferlog_path
                inferAnalyzePath="$cilogPath/inferAnalyzePath.log"
                # analyze 操作
                infer-analyze --reactive \
                --keep-going \
                --compilation-database $compile_commands_path &> $inferAnalyzePath \
                --changed-files-index change.txt
            else
                echo "====没有上次infer分析的结果, 走全量正常分析流程===="
                # 添加reactive模式
                infer run --reactive --keep-going --skip-analysis-in-path Pods --compilation-database $compile_commands_path &> $inferlog_path
            fi
            
            echo "🍺  infer Success"
            #当前infer扫描保存目录
            currentInferoutPath="$CI_PROJECT_DIR/infer-out/"
            #上次保存的目录
            lastInferoutProject="$HOME/$CI_RUNNER_TAGS-infer-out/$CI_PROJECT_NAME/$CI_COMMIT_REF_NAME"
            if [ ! -d ${lastInferoutProject} ]; then
                mkdir -p $lastInferoutProject
            fi
            lastInferoutPath="$HOME/$CI_RUNNER_TAGS-infer-out/$CI_PROJECT_NAME/$CI_COMMIT_REF_NAME/infer-out"
            # 保存infer扫描记录
            cp -Rf ${currentInferoutPath} ${lastInferoutPath}
            echo "=========保存infer-out成功,保存路径在$lastInferoutPath========="
            
        else
            echo "warning: infer not installed, download from https://fbinfer.com"
        fi
    }
    
    if [ -f $compile_commands_path ]; then
        execute_infer
    else
        echo "warning:  ${compile_commands_path} not found !!";
    fi
    infer_end_time=$(date +%s)
    
    

    结果图

    注:infer的扫描时长仅供参考,要保证测试数据的可比较性,请尽量在构建机没有其他工作任务,保证完全clean的状态下执行。
    全量扫描


    image.png

    增量分析


    image.png

    可以看到,采取增量分析后,时长减少了72%。
    如果您有更好的能够减少infer-capture这一步时长的想法,欢迎一起交流学习!

    相关文章

      网友评论

          本文标题:infer objective-C 如何实现增量分析

          本文链接:https://www.haomeiwen.com/subject/xjmpxrtx.html