find扫描软件的使用方法,哪种扫描软件最好用

首页 > 经验 > 作者:YD1662022-11-01 01:52:03

通过对Task耗时排序,主要的耗时体现在FindBugs和Lint对每一个Module的扫描任务上,CheckStyle任务并不占主要影响。整体来看,除了工具本身的扫描时间外,耗时主要分为多Module、多Variant带来的任务数量耗时

优化思路分析

对于工具本身的扫描时间,一方面受工具自身扫描算法和检测规则的影响,另一方面也跟扫描的文件数量相关。针对源码类型的工具比如CheckStyle和Lint,需要经过词法分析、语法分析生成抽象语法树,再遍历抽象语法树跟定义的检测规则去匹配;而针对字节码文件的工具FindBugs,需要先编译源码成Class文件,再通过BCEL分析字节码指令并与探测器规则匹配。如果要在工具本身算法上去寻找优化点,代价比较大也不一定能找到有效思路,投入产出比不高,所以我们把精力放在减少Module和Variant带来的影响上。

从上面的耗时分析可以知道,Module和Variant数直接影响任务数量, 一次PR提交的场景是多样的,比如多Module多Variant都有修改,所以要考虑这些都修改的场景。先分析一个Module多Variant的场景,考虑到不同的Variant下源代码有一定差异,并且FindBugs扫描针对的是Class文件,不同的Variant都需要编译后才能扫描,直接对多Variant做处理比较复杂。我们可以简化问题,用以空间换时间的方式,在提交PR的时候根据Variant用不同的Jenkins Job来执行每一个Variant的扫描任务。所以接下来的问题就转变为如何优化在扫描单个Variant的时候多Module任务带来的耗时。

对于Module数而言,我们可以将其抽取成组件,拆分到独立仓库,将扫描任务拆分到各自仓库的变动时期,以aar的形式集成到主项目来减少Module带来的任务数。那对于剩下的Module如何优化呢?无论是哪一种工具,都是对其输入文件进行处理,CheckStyle对Java源代码文件处理,FindBugs对Java字节码文件处理,如果我们可以通过一次任务收集到所有Module的源码文件和编译后的字节码文件,我们就可以减少多Module的任务了。所以对于全量扫描,我们的主要目标是来解决如何一次性收集所有Module的目标文件

思考三:是否支持增量扫描?

上面的优化思路都是基于全量扫描的,解决的是多Module多Variant带来的任务数量耗时。前面提到,工具本身的扫描时间也跟扫描的文件数量有关,那么是否可以从扫描的文件数量来入手呢?考虑平时的开发场景,提交PR时只是部分文件修改,我们没必要把那些没修改过的存量文件再参与扫描,而只针对修改的增量文件扫描,这样能很大程度降低无效扫描带来的效率问题。有了思路,那么我们考虑以下几个问题:

根据上面的分析与思考路径,接下来我们详细介绍如何解决上述问题。

优化探索与实践

全量扫描优化

搜集所有Module目标文件集

获取所有Module目标文件集,首先要找出哪些Module参与了扫描。一个Module工程在Gradle构建系统中被描述为一个“Project”,那么我们只需要找出主工程依赖的所有Project即可。由于依赖配置的多样性,我们可以选择在某些Variant下依赖不同的Module,所以获取参与一次构建时与当前Variant相关的Project对象,我们可以用如下方式:

目前文件集分为两类,一类是源码文件,另一类是字节码文件,分别可以如下处理:

注:上面的Source是CheckStyle Task的属性,用其来指定扫描的文件集合;

注:收集到字节码文件集后,可以用通过FindBugsTask 的 Class 属性指定扫描,后文会详细介绍FindBugs Task相关属性。

对于Lint工具而言,相应的Lint Task并没有相关属性可以指定扫描文件,所以在全量扫描上,我们暂时没有针对Lint做优化。

全量扫描优化数据

通过对CheckStyle和FindBugs全量扫描的优化,我们将整体扫描时间由原来的9min降低到了5min左右。

find扫描软件的使用方法,哪种扫描软件最好用(5)

增量扫描优化

由前面的思考分析我们知道,并不是所有的文件每次都需要参与扫描,所以我们可以通过增量扫描的方式来提高扫描效率。

增量扫描技术调研

在做具体技术方案之前,我们先调研一下业界的现有方案,调研如下:

find扫描软件的使用方法,哪种扫描软件最好用(6)

针对Lint,我们可以借鉴现有实现思路,同时深入分析扫描原理,在3.x版本上寻找出增量扫描的解决方案。对于CheckStyle和FindBugs,我们需要了解工具的相关配置参数,为其指定特定的差异文件集合。

注:业界有一些增量扫描的案例,例如diff_cover,此工具主要是对单元测试整体覆盖率的检测,以增量代码覆盖率作为一个指标来衡量项目的质量,但是这跟我们的静态代码分析的需求不太符合。它有一个比较好的思路是找出差异的代码行来分析覆盖率,粒度比较细。但是对于静态代码扫描,仅仅的差异行不足以完成上下文的语义分析,尤其是针对FindBugs这类需要分析字节码的工具,获取的差异行还需要经过编译成Class文件才能进行分析,方案并不可取。

寻找增量修改文件

增量扫描的第一步是获取待扫描的目标文件。我们可以通过git diff命令来获取差异文件,值得注意的是对于删除的文件和重命名的文件需要忽略,我们更关心新增和修改的文件,并且只需要获取差异文件的路径就好了。举个例子:git diff --name-only --diff-filter=dr commitHash1 commitHash2,以上命令意思是对比两次提交记录的差异文件并获取路径,过滤删除和重命名的文件。对于寻找本地仓库的差异文件上面的命令已经足够了,但是对于PR的情况还有一些复杂,需要对比本地代码与远程仓库目标分支的差异。集团的代码管理工具在Jenkins上有相应的插件,该插件默认提供了几个参数,我们需要用到以下两个:

通过这两个参数执行以下一系列命令来获取与远程目标分支的差异文件。

1. 配置远程分支别名为UpStream,其中upstreamGitUrl可以在插件提供的配置属性中设置;

2. 获取远程目标分支的更新;

3. 比较分支差异获取文件路径。

通过以上方式,我们找到了增量修改文件集。

Lint扫描原理分析

在分析Lint增量扫描原理之前,先介绍一下Lint扫描的工作流程:

find扫描软件的使用方法,哪种扫描软件最好用(7)

App Source Files

项目中的源文件,包括Java、XML、资源文件、proGuard等。

lint.xml

用于配置希望排除的任何 Lint 检查以及自定义问题严重级别,一般各个项目都会根据自身项目情况自定义的lint.xml来排除一些检查项。

lint Tool

一套完整的扫描工具用于对Android的代码结构进行分析,可以通过命令行、IDEA、Gradle命令三种方式运行lint工具。

lint Output

Lint扫描的输出结果。

从上面可以看出,Lint Tool就像一个加工厂,对投入进来的原料(源代码)进行加工处理(各种检测器分析),得到最终的产品(扫描结果)。Lint Tool作为一个扫描工具集,有多种使用方式。Android为我们提供了三种运行方式,分别是命令行、IDEA、Gradle任务。这三种方式最终都殊途同归,通过LintDriver来实现扫描。如下图所示:

find扫描软件的使用方法,哪种扫描软件最好用(8)

上一页1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.