我报名参与金石计划1期应战——瓜分10万奖池,这是我的第5篇文章,点击查看活动概况

系列文章目录

Android打造专有hook,让不标准的代码扼杀在萌芽之中

Android打造专有hook第二篇,走进标准第一步

Android打造专有Hook第三篇,实战全量代码标准查看

Hello啊各位老铁,上篇的文章,咱们把全量代码标准查看做了一个整体的完成,唯一缺少了关于增量代码的查看,今日,这篇咱们就要点把增量这块,做一个简略的剖析。

在全量文件查看中,咱们只需求得到Git提交的文件,然后逐一针对文件内容,获取,做相关的逻辑查看即可,但是增量就不能这样搞了,咱们都知道,每次增量的提交,是没有规律可言的,也许增量中只有一行,也许有百行,而且增量的代码位置,有可能是在办法中,有可能是在资源中,所以针对增量代码的查看,是有必要要做出取舍的,由于,经过一行,或许几行,很难达到必定的标准标准,OK,废话不多说,咱们开搞!

今日的内容大约如下

1、增量代码简略阐明

2、增量中怎么取得代码

3、增量代码标准查看

4、弥补阐明

一、增量代码简略阐明

前边说过,增量代码相对于全量代码有着巨大的差异,在增量代码中,所提交的更改代码,有可能是没有包括咱们所拟定的标准的,比方下面的这段提交的增量代码:

+        val strings: List<String> = token.split(".")
+                if (strings.size != 3) {
+                    LogUtil.d("Incorrect token, strings size = ${strings.size}")
+                    return default
+                }
+

从上边的增量代码中,你能判别什么?办法命名标准?办法注释标准,变量命名标准?还是其他的标准,依据咱们的标准标准,其实啥也判别不了,所以,在增量代码的提交中,咱们需求侧重和咱们的标准标准进行相匹配,已然匹配,那么咱们就不得不做出一些取舍,也便是说,有些能标准查看的,咱们进行查看,不能做查看的,咱们只能放弃。

二、增量中怎么取得代码

增量代码查看的前提,有必要得到当时所提交的增量代码,怎么获取到增量代码呢?Git中给咱们供给了相关指令,如下,经过下述的指令,咱们就能够得到当时commit的一切提交文件的增量代码,并生成咱们指定的对应文件。

git diff >> androidCommit.diff

需求留意的是,增量代码的生成,是生成到一个文件下,而且有必要是在指令行的情况下才会收效,所以啊,各位老铁,运用增量代码查看时,必定要留意这个,并且在露出给开发者的时分,在配置文件里也必定要标示。

当指令履行后,所生成的增量内容大致如下(查看的代码都是用于测验的,咱们只关注增量提交的信息即可):

diff --git a/app/src/HomeActivity.kt b/app/src/HomeActivity.kt
index 29ef3c5..0cdc619 100644
--- a/app/src/HomeActivity.kt
+++ b/app/src/HomeActivity.kt
@@ -701,7 +701,8 @@ class HomeActivity : DataBindingBaseActivity<ActivityHomeBinding, HomeViewModel>
     }
-    override fun onResume() {
+
+override fun onResume() {
         super.onResume()
         mActivityStatus = ACTIVITY_ON_RESUME
     }
@@ -727,7 +728,9 @@ class HomeActivity : DataBindingBaseActivity<ActivityHomeBinding, HomeViewModel>
      }
-     fun on_sHttp(){
+
+
+      fun on_sHttp(){
      }
diff --git a/app/src/HomeViewModel.kt b/app/src/HomeViewModel.kt
index 477da32..c43897e 100644
--- a/app/src/HomeViewModel.kt
+++ b/app/src/HomeViewModel.kt
@@ -59,6 +59,7 @@ import org.json.JSONObject
 class HomeViewModel(app: Application) : AppBarBaseViewModel<PickupMessageRepository, IAppBarProcessor>(app) {
     val mText: MutableLiveData<String> = MutableLiveData()
+
     var badgeByTypeBean = MutableLiveData<List<BadgeByType>>()
     init {
@@ -147,6 +148,12 @@ class HomeViewModel(app: Application) : AppBarBaseViewModel<PickupMessageReposit
             return default
         }
+        val strings: List<String> = token.split(".")
+                if (strings.size != 3) {
+                    LogUtil.d("Incorrect token, strings size = ${strings.size}")
+                    return default
+                }
+
         return try {
             val decoded = String(Base64.decode(strings[1], Base64.DEFAULT), charset("UTF-8"))
             val jsonObject = JSONObject(decoded)
diff --git a/gitExec.js b/gitExec.js
index dd9288b..21d452d 100644
--- a/gitExec.js
+++ b/gitExec.js
@@ -95,8 +95,6 @@ let lint = function (cb) {
         }
         cb(1);
     }
-
-
 };
 let taskList = [lint];

各位老铁看后,感觉怎么样,怎么从这些增量内容中,查看相关代码是否契合标准呢?是不是很乱,是不是毫无头绪?其实我刚一看到后,也是一脸懵逼,类命名标准,办法命名标准,注释查看等,从何搞起呢?静下心来渐渐剖析后,其实也就那么回事。

从增量提交的内容来看,但凡进行过更改的文件,前缀都有一个”+++ b“,咱们能够实际的调查下,已然每个更改的文件都有这样的一个标识,咱们是不是能够经过它,来截取到所提交的文件,这种办法是可行的,当然了,除了这种办法之外,咱们也能够依照全量代码查看中的,文件列表获取,来判别相关的文件命名是否标准。

文件的命名标准,比方类,layout,图片等,能够依照上述所说的规矩,那么针对string的Name是否标准呢?其实也简略,经过”+++ b“切割后,遍历判别每一个元素是否包括string.xml,假如包括,直接遍历每一行的内容,下面的逻辑判别和全量中的基本上类似了。

增量中,还有一个需求解决的是,办法命名标准和变量命名标准怎么完成,同样的,也是需求在增量代码中进行寻觅规矩,以”+++ b“切割后,经过遍历,找到有相关内容,并且是类的提交规矩,比方是否包括了”@@“和”+ “,然后再进行文件名子的截取,是否包括”kt“和”java“之后,就能够进行这两个功用的判别了。

三、增量代码标准查看

关于增量代码查看,我这儿分为了两步,一步是和全量相同,拿到提交的文件,针对提交上来的文件做命名标准查看,另一步则是针对增量内容进行拆解,查看string的Name和类中的办法名和变量是否标准。

比方图片和layout 标准查看、类的姓名是否标准查看,这个在上篇文章全量查看中现已剖析过了,这儿就不重复了,关于这两块,其实便是截取,然后进行规矩判别,咱们看上一篇即可。

/**
 * 增量文件查看
 * */
function checkDiffFile(cb, stdout, dirname) {
    //经过切割换行,拿到文件列表
    let array = stdout.split('\n');
    // 去掉最后一个换行符号
    array.pop();
    log('【针对以上提交文件查看结果如下:】\n', 1);
    //遍历文件,查看相关标准是否契合
    array.forEach(function (value) {
        if (((value.indexOf("png") !== -1
                || value.indexOf("jpg") !== -1
                || value.indexOf("gif") !== -1
                || value.indexOf("webp") !== -1) ||
            (value.indexOf("layout") !== -1 &&
                value.indexOf("xml") !== -1)) && (
            mCommitType.indexOf("0") !== -1 ||
            mCommitType.indexOf("2") !== -1 ||
            mCommitType.indexOf("3") !== -1
        )) {
            //图片或许layout 标准查看
            checkImageOrLayout(value);
        } else if (value.indexOf("kt") !== -1 || value.indexOf("java") !== -1) {
            //Kotlin或许Java,标准查看
            let lastPosition = value.lastIndexOf("/");
            let className = value.substring(lastPosition + 1, value.length);
            //查看类的姓名是否标准
            checkClassName(className, value);
        }
    });
    //生成增量文件,并运用指令,写入增量代码
    fs.writeFile(dirname + "/androidCommit.diff", "", function (err) {
        if (err) {
            log('增量查看中断', 0);
            return;
        }
        exec('git diff >> androidCommit.diff', function (error, stdout, stderr) {
            //增量代码写入后,进行读取diff文件
            checkDiff(cb, dirname);
        });
    });
    setTimeout(function () {
        console.log("\n");
        if (isCheck) {
            cb(1);
        } else {
            log("增量查看结束,暂未发现问题,真棒!!!\n", 2);
            cb(0);
        }
    }, 1500);
}

string文件Name是否契合标准,以及类文件中的办法命名和办法注释是否标准,这几种标准查看是经过增量内容进行判别的,详细的判别如下:

1、履行增量文件生成指令

增量查看和全量最大不同便是,增量需求履行指令,生成增量文件,所以在露出给开发者的时分,配置文件中,这一项假如翻开,那么就需求选择指令行办法进行查看,这个在实际的研制中现已验证,工具的办法无法生成增量文件。

        exec('git diff >> androidCommit.diff', function (error, stdout, stderr) {
            //增量代码写入后,进行读取diff文件
            checkDiff(cb, dirname);
        });

2、string的Name标准查看

string的Name查看,在增量中并不复杂,首要经过”+++ b“进行切割,在遍历的时分,针对每个元素进行判别,看是否包括”string.xml“和”“关键字。

 //读取增量文件代码
    let data = fs.readFileSync(dirname + "/androidCommit.diff", 'utf-8');
    if (data === "" || data == null) {
        log("\n【增量代码无法查看】,这种情况下请您Github上Issues反应\n", 0);
        return;
    }
    log('\n增量代码文件生成中\n', 1);
    //获取到一切的问题内容后
    let diffArray = data.split("+++ b");
    if (mCommitType.indexOf("0") !== 0 ||
        mCommitType.indexOf("1") !== 0) {
        diffArray.forEach(function (value) {
            //判别string
            if (value.indexOf("function") === -1 &&
                value.indexOf("string.xml") !== -1
                && value.indexOf("</string>") !== -1) {
                //string文件
                var mName;
                value.split(/\r?\n/).forEach((line, position) => {
                    if (position === 0) {
                        let moduleName = line.trim().substring(1, line.length);
                        let moduleIndex = moduleName.indexOf("/");
                        mName = moduleName.substring(0, moduleIndex);
                    }
                    if (line.indexOf("</string>") !== -1) {
                        //判别string name
                        if (mName.indexOf("app") === -1 && mName.indexOf("libBase") === -1) {
                            let stringArr = line.split("name="");
                            stringArr.forEach(function (item, position) {
                                let i = item.indexOf(""");
                                let endString = item.substring(0, i);
                                if (endString !== "" && !endString.startsWith(mName)) {
                                    //最初不是
                                    isCheck = true;
                                    log("【" + mName + "模块中string文件,name为" + endString + "】,命名不标准", 0);
                                }
                            });
                        }
                    }
                });
            }
        });
    }

3、办法命名标准和变量命名标准查看

办法的查看,我是经过是否包括“@@”和“+ ”后,在遍历每一行的信息,kotlin判别是否包括“fun”,java的话是经过“) {”来截取判别,当然了,现在的判别中还是有瑕疵的,但匹配度完全能够。变量的话,针对Kotlin的var和val变量来采纳判别,咱们能够看下面的逻辑判别。

/**
 * 增量代码进行查看是否标准
 * */
function checkDiff(cb, dirname) {
    //判别类
    setTimeout(function () {
        diffArray.forEach(function (value) {
            if (value.indexOf("@@") !== -1 && value.indexOf("+  ") !== -1) {
                var mFileName = "";
                value.split(/\r?\n/).forEach((line, position) => {
                    if (position === 0 && line.startsWith("/")) {
                        //文件名
                        mFileName = line.trim();
                    }
                    //java和kt
                    if (mFileName.indexOf("kt") !== -1 || mFileName.indexOf("java") !== -1) {
                        //增量代码就得另类考虑和判别了
                        //1 先判别办法姓名
                        if (line.indexOf("fun") !== -1 && (
                            mCommitType.indexOf("0") !== -1 ||
                            mCommitType.indexOf("7") !== -1
                        )) {
                            //kotlin办法
                            let funIndex = line.indexOf("fun");
                            let funString = line.substring(funIndex + 3, line.length).trim();
                            let funEnd = funString.split("(")[0];
                            //判别办法姓名
                            if (checkCase(funEnd.substring(0, 1)) || funEnd.indexOf("_") !== -1) {
                                isCheck = true;
                                log("【" + mFileName + "】中的办法" + funEnd + ",不契合标准,请您整改", 0);
                            }
                        }
                        if ((line.indexOf(") {") !== -1 || line.indexOf("Exception {") !== -1) && (
                            mCommitType.indexOf("0") !== -1 ||
                            mCommitType.indexOf("7") !== -1
                        )) {
                            //java办法
                            let javaIndex = line.indexOf("(");
                            let javaMethods = line.substring(0, javaIndex);
                            let javaMArray = javaMethods.split(" ");
                            let methodName = javaMArray[javaMArray.length - 1];
                            if ((checkCase(methodName.substring(0, 1)) || methodName.indexOf("_") !== -1)
                                && methodName !== "") {
                                isCheck = true;
                                log("【" + mFileName + "】中的办法" + methodName + ",不契合标准,请您整改", 0);
                            }
                        }
                        //2判别变量
                        if ((line.indexOf("var") !== -1 || line.indexOf("val") !== -1) &&
                            line.indexOf("+") !== -1
                        ) {
                            // kotlin变量
                            //1、包括=  2包括 :
                            var kotlinArr = [];
                            if (line.indexOf(":") !== -1) {
                                kotlinArr = line.split(":");
                            } else {
                                kotlinArr = line.split("=");
                            }
                            let varA = kotlinArr[0].trim();
                            let varEndArr = varA.split(" ");
                            let varEnd = varEndArr[varEndArr.length - 1];
                            //判别变量的姓名
                            if ((checkCase(varEnd.substring(0, 1))
                                || varEnd.indexOf("_") !== -1)) {
                                const p = /^[A-Z_]*$/g;
                                if (!p.test(varEnd)) {
                                    isCheck = true;
                                    log("【" + mFileName + "】中的变量" + varEnd + ",不契合标准,请您整改", 0)
                                }
                            }
                        }
                    }
                });
            }
        });
    }, 300);
}

四、弥补阐明

增量代码查看,现在可完成的功用没有全量的多,而且在相关的判别中,许多暂时无法百分百的进行查看,究竟脱离了Android的环境,不能准确的获取到相关类,相关资源,相关办法,只能经过共性,来完成咱们的标准查看,话又说回来,尽管不能百分百,但经过类似的比较之后,也能够满意大部分的查看需求。

好了老铁们,关于Android端的GitHook标准查看,咱们基本上论述结束了,假如咱们仅仅运用的话,看第1篇即可,假如想亲手搞一个的话,能够看2至4篇,有些代码写的不够清晰,也比较繁琐,究竟咱也不是专职搞Web的,咱们多包容点看,待我后续作业不忙后,再仔细的优化一下,也能够直接去Github上下载后,直接改即可,上篇现已贴了地址,这儿在贴一下:

github.com/AbnerMing88…

代码有了,功用也有了,怎么打包让他人运用呢?这个总结到下篇文章吧,其实便是把现在的代码上传到npm官网,让他人能够经过指令安装,详细的作用咱们能够看第1篇文章。

这篇就到这儿吧,提早祝咱们国庆愉快,疫情期间,多看少动,留意防范,咱们国庆后见!