Android打造专有hook第二篇,走进规范第一步

简介: 关于Git的Hooks,其实很常见,位置存在于 /.git/hooks 目录下,都是一些 shell 脚本,然后在对应的钩子中执行这些脚本就行了,比如下图中,这是一个还没有配置 Git Hooks 的仓库,默认会有很多.sample结尾的文件,这些都是示例文件,比如我们常见的,commit,push等。

在第一篇的概述中,对于本系列文章,我大概预估了一下,需要四篇文章来进行讲解,基本上就是,第一篇了解用法和实际当中的效果,第二篇和第三篇进入实战,最后一篇收尾及市场发布,让别人使用,尽量做到,细致入微,毫无保留的分享给大家,希望能给大家在规范的检测上带来一丝帮助,想了解最终规范检测功能的朋友,可以看第一篇的内容,里面有最后的实现效果,今天,我们分享第二篇。


本篇文章内容大概分为以下几个模块


1、Git Hook介绍

2、基本环境搭建

3、创建动态配置文件

4、代码初始化


一、Git Hook介绍


由第一篇的相关知识,我们可以知道,当下所做的这个检测功能,是在Git提交之前进行检测,也就是说,在Git触发commit时,就需要进行拦截,而在实际的使用当中,Git已经向我们提供了Hook,也就是钩子,便于我们进行指令的操作,关于Hook呢,分为两种,一种是客户端Hooks,诸如提交和合并这样的操作所调用,一种是服务端Hooks,作用于接收被推送的提交这样的联网操作,而现在我们要实现的是客户端Hooks。

关于Git的Hooks,其实很常见,位置存在于 /.git/hooks 目录下,都是一些 shell 脚本,然后在对应的钩子中执行这些脚本就行了,比如下图中,这是一个还没有配置 Git Hooks 的仓库,默认会有很多.sample结尾的文件,这些都是示例文件,比如我们常见的,commit,push等。


Git 支持的钩子类型有很多,比如,post-update,pre-commit等,我简单的举几个常见的,列个表格,大家感兴趣的可以作为参考。


Git hook

概述

pre-commit

钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify 来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。

pre-push

钩子会在 git push 运行期间, 更新了远程引用但尚未传送对象时被调用。 它接受远程分支的名字和位置作为参数,同时从标准输入中读取一系列待更新的引用。 你可以在推送开始之前,用它验证对引用的更新操作(一个非零的退出码将终止推送过程)。

post-update

仅在所有的ref被push之后执行一次。它与post-receive很像,但是不接收旧值与新值。主要用于通知。每个被push的repo都会生成一个参数,参数内容是ref的名称。

applypatch-msg

它接收单个参数:包含请求合并信息的临时文件的名字。 如果脚本返回非零值,Git 将放弃该补丁。 你可以用该脚本来确保提交信息符合格式,或直接用脚本修正格式错误。

commit-msg

钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 你可以结合提交模板来使用它,动态地插入信息。

pre-applypatch

实际上的调用时机是应用补丁之后、变更commit之前。如果以非0的状态退出,会导致变更成为uncommitted状态。可用于在实际进行commit之前检查代码树的状态或用它在提交前检查快照。 你可以用这个脚本运行测试或检查工作区。 如果有什么遗漏,或测试未能通过,脚本会以非零值退出,中断 git am 的运行,这样补丁就不会被提交。


而我们本次所使用的就是通过pre-commit类型,来进行拦截检测。


二、基本环境搭建


无论我们封装sdk,还是开发什么功能,在给他人使用的时候,一定是本着简单便捷的宗旨,要不然,辛辛苦苦操作了一番,比原有的还复杂,岂不是,既违背了宗旨,也很难普及使用,所以,Git的Hook,也要基于这个思想。


为了实现这样的一个简单便捷的规范检查,确实研究了一番,通过各项比较及实际的操作,最终还是使用Node.js来实现这样的一个功能,原因无非就是简单,这个在第一篇中已经给出了答案。


1、安装 Node.js


如果已经安装,可直接第2步


Node.js中允许使用 JavaScript 开发服务端以及命令行程序,我们可以去官网 https://nodejs.org 下载最新版本的安装程序,然后一步一步进行安装就可以了。


2、执行init命令


新建目录,在当前目录下执行如下命令,创建package.json文件


npm init -y


命令执行后,如下图所示:



里面的内容没什么好说的,包含基本的,作者,介绍,执行脚本信息等,这个之前的文章里讲述过,就不过多赘述了。


3、安装pre-commit


目的在提交信息前进行拦截检查。


npm install pre-commit --save-dev


安装成功后,当前目录下多出一个文件夹node_modules,此文件下用来存放下载安装的包文件夹,里面有我们要使用到的功能,其实和Android中lib目录很类似,都是一些提供功能的库。



4、创建执行程序文件


在当前目录下,新建一个js文件,名字自己定义,我这里创建了一个gitExec.js文件,如下图:


5、更改package.json文件


打开package.json文件,可按照下面的方式进行更改,最重要的是scripts脚本执行这里,lint指向你刚才创建的js文件。


{
  "name": "AndroidGitHook",
  "version": "1.0.0",
  "description": "Android端git规范检查",
  "scripts": {
    "lint": "node gitExec.js"
  },
  "author": "AbnerMing",
  "license": "ISC",
  "pre-commit": [
    "lint"
  ],
  "devDependencies": {
    "pre-commit": "^1.2.2"
  },
  "dependencies": {
    "pre-commit": "^1.2.2"
  }
}


经过上面的五步,我们的环境搭建就完成了,后续我们的逻辑处理,均在你创建的js文件里,这个需要重点强调一下。


三、创建动态配置文件


环境搭建之后,在写规范检查逻辑之前,需要创建可配置的动态文件,这个文件是十分重要的,是需要暴露给开发者的,也就是说,开发人员是根据这个配置文件,来进行操作规范检查的,具体需要包含什么字段,需要大家根据实际的业务,或者自己的拓展进行设置的,我自己创建的动态文件如下:



内容如下:


#git提交配置文件
#git提交前是否进行检测,true:检测,false:不检测
gitCommitSwitch=true
#是否进行增量更新(增量仅命令可用),true为增量,false为检查整个文件
gitIncrement=false
#git检测类型,0:全部,1:string文件Name,2:图片命名,3:layout,4:类命名,
#5:类注释,6:方法注释,7:方法命名,8:变量命名,9:try catch
gitCheckType=0
#git提交方式,true为工具,false为命令方式
gitCommand=true


大家可以看到我自己定义的文件格式为.android,这个大家可以自定义,.aa,.bb都行,什么格式都可以,是一个文件就行,毕竟,咱只关心里面的内容,所谓的格式没有区分。


至于里面的内容,看大家自己实际的需要,自己去编写,你想通过什么字段来控制,或者想要实现一个什么样的规范检查,都可以在这里动态配置,暴露给开发人员,当然,大家可以直接使用我的,或者在我的基础之上进行拓展都行。


四、代码初始化


万事具备,就差代码逻辑编写了,这里需要温馨提示一下,虽然是Android端的Hook规范检查,但所有的代码逻辑都是通过Js来实现的,不懂Js的老铁,建议看一下,对于我们有编程基础的人来说,很简单的。有的老铁问了,我不懂Js,能否搞出来呢?我的回答是,问题不大,我尽量把代码注释标注的很清楚,让大家一看便理解。


1、创建执行程序


当我们执行Git提交时,通过pre-commit映射到了我们自定义的js文件中,在这个js文件中,我们就需要进行相关逻辑编写,首先,定义了一个startTask函数,并且立即执行了startTask函数,也就是Git提交时会触发定义的这个startTask函数。


startTask函数里又调用了一个lint函数,接下来的所有的逻辑判断都是通过此函数,大家可以看到,调用了process的exit方法,之所以要调用,意味着,逻辑是由我们自己来处理,也就是在lint方法里,是执行还是退出,需要根据判断来生效。


/** * Author:AbnerMing * Time:2022-9-13 * Desc:git执行commit前判断 * *///规范检查函数,所有的逻辑判断都是通过此函数letlint=function (cb) {
};
//调用 lint 函数letstartTask=function () {
lint(function () {
//它可以是0或1,0表示没有任何类型的故障结束进程,而1表示由于某种故障而结束进程process.exit(1);
  })
}
// 调用startTask方法,进行执行检查startTask();


2、读取配置文件


引入fs,文件操作模块,因为我们要读取配置文件,这个fs模块是必不可少的。


letfs=require('fs');


声明成员变量,便于下面的程序判断


/**git检测类型,0:全部,1:string文件Name,2:图片命名,3:layout,4:类命名,*5:类注释,6:方法注释,7:方法命名,8:变量命名,9:try catch* */varmCommitType;
//git检测开关,true:开,false:关varmCommitOpen;
//是否进行增量更新(增量仅命令可用),true为增量,false为检查整个文件varmCommitIncrement;
//git提交方式,true为工具,false为命令方式varmGitCommand;


读取配置文件,取出参数值并赋值给成员变量


//规范检查函数,所有的逻辑判断都是通过此函数letlint=function (cb) {
//读取文件信息letpath=require('path');
letdirname=path.join(__dirname);
try {
//读取配置文件,查找对应的配置信息letdata=fs.readFileSync(dirname+"/gitCommitConfig.android", 'utf-8');
data.split(/\r?\n/).forEach((line, position) => {
if (position===2) {
letopen=line.split("=")[1];
mCommitOpen=open.toString();//git检测开关            }
if (position===4) {
letincrement=line.split("=")[1];
mCommitIncrement=increment.toString();//是否进行增量更新            }
if (position===7) {
lettype=line.split("=")[1];
mCommitType=type.toString();//git检测类型            }
if (position===9) {
lettype=line.split("=")[1];
mGitCommand=type.toString();//git提交方式            }
//根据配置文件进行逻辑判断        });
    } catch (e) {
if (e.message.indexOf("gitCommitConfig.android") !==-1) {
//没有文件,向使用者展示错误信息console.log("\n");
log("\n缺少配置文件[gitCommitConfig.android],请核对后再提交\n", 0);
log("请在项目根目录下创建[gitCommitConfig.android]文件\n", 0);
log("内容如下\n", 0);
log("#git提交配置文件\n"+"#git提交前是否进行检测,true:检测,false:不检测\n"+"gitCommitSwitch=true\n"+"#是否进行增量更新(增量仅命令可用),true为增量,false为检查整个文件\n"+"gitIncrement=false\n"+"#git检测类型,0:全部,1:string文件Name,2:图片命名,3:layout,4:类命名,\n"+"#5:类注释,6:方法注释,7:方法命名,8:变量命名,9:try catch\n"+"gitCheckType=0\n"+"#git提交方式,true为工具,false为命令方式\n"+"gitCommand=true\n", 3);
        }
cb(1);//故障而结束进程    }
};


大家可以看到,我在读取配置文件的时候,进行了一个异常判断,判断的目的在于,可能使用者由于大意,没有执行相关命令生成配置文件,或者配置删除了,那么我们就要捕获异常,给使用者抛出提示,让使用者按照要求再生成一份。


log呢,是一个函数,里面封装了一层,目的就是为了区分工具提交还是命令行方式提交,如果命令行方式提交,就可以进行彩色区分。


//log日志展示,其实就是提交信息展示,命令提交进行特殊符合处理functionlog(message, type) {
//工具提交if (mGitCommand==="true") {
console.log(message);
    } else {
//命令行方式if (type===2) {
console.log("\x1B[32m%s\x1B[39m", message);//颜色:green        } elseif (type===1) {
console.log('\x1B[36m%s\x1B[39m', message);//颜色:cyan        } elseif (type===0) {
console.log('\x1B[31m%s\x1B[39m', message);//颜色:red        } elseif (type===3) {
console.log('\x1B[33m%s\x1B[39m', message);//颜色:yellow        }
    }
}


更多颜色值如下

 

'bold'          : ['\x1B[1m%s\x1B[22m'],
'italic'        : ['\x1B[3m%s\x1B[23m'],
'underline'     : ['\x1B[4m%s\x1B[24m'],
'inverse'       : ['\x1B[7m%s\x1B[27m'],
'strikethrough' : ['\x1B[9m%s\x1B[29m'],
'white'         : ['\x1B[37m%s\x1B[39m'],
'grey'          : ['\x1B[90m%s\x1B[39m'],
'black'         : ['\x1B[30m%s\x1B[39m'],
'blue'          : ['\x1B[34m%s\x1B[39m'],
'cyan'          : ['\x1B[36m%s\x1B[39m'],
'green'         : ['\x1B[32m%s\x1B[39m'],
'magenta'       : ['\x1B[35m%s\x1B[39m'],
'red'           : ['\x1B[31m%s\x1B[39m'],
'yellow'        : ['\x1B[33m%s\x1B[39m'],
'whiteBG'       : ['\x1B[47m%s\x1B[49m'],
'greyBG'        : ['\x1B[100m%s\x1B[49m'],
'blackBG'       : ['\x1B[40m%s\x1B[49m'],
'blueBG'        : ['\x1B[44m%s\x1B[49m'],
'cyanBG'        : ['\x1B[46m%s\x1B[49m'],
'greenBG'       : ['\x1B[42m%s\x1B[49m'],
'magentaBG'     : ['\x1B[45m%s\x1B[49m'],
'redBG'         : ['\x1B[41m%s\x1B[49m'],
'yellowBG'      : ['\x1B[43m%s\x1B[49m']


代码初始化完成之后,后面的就是根据动态配置文件的参数,来实际的操作规范检查了,行,老铁们,这篇先到这里,下篇我们继续。

相关文章
|
4月前
|
监控 开发工具 Android开发
结合GB/T28181规范探讨Android平台设备接入模块心跳实现
本文介绍了GB28181标准中的状态信息报送机制,即心跳机制,用于监控设备与服务器间的连接状态。根据国标GB/T28181-2016,设备在异常时需立即发送状态信息,在正常状态下则按固定间隔(默认60秒)定期发送。若连续三次(默认值)未收到心跳,则视为离线。文章展示了在Android平台的GB28181设备接入模块(SmartGBD)中,如何调整心跳间隔为20秒及超时次数为3次,并给出了心跳消息的示例和异常处理代码片段。对于希望深入了解或遇到问题的开发者,作者提供了进一步交流的机会。
|
6月前
|
Java Linux API
微信API:探究Android平台下Hook技术的比较与应用场景分析
微信API:探究Android平台下Hook技术的比较与应用场景分析
|
7月前
|
缓存 Android开发
Android插件化——高手必备的Hook技术,零基础开发android
Android插件化——高手必备的Hook技术,零基础开发android
|
7月前
|
安全 数据处理 Android开发
安卓隐私权政策和Google Play规范更新
【4月更文挑战第14天】谷歌针对安卓平台的隐私权政策和Google Play规范进行重要更新,强化用户隐私保护和安全标准。新政策强调最小化数据收集,要求开发者明确告知用户敏感数据用途,并限制不必要的后台数据处理。Google Play规范更新要求应用详述数据收集方式,增加安全审查机制,确保无恶意代码。开发者面临调整,但有机会提升应用安全标准,赢得用户信任。用户数据安全得到提升,移动生态系统将更健康、可持续。
140 1
|
7月前
|
Android开发
安卓逆向 -- Hook多个dex文件
安卓逆向 -- Hook多个dex文件
67 1
|
7月前
|
算法 安全 Android开发
安卓逆向 -- Frida Hook某车_sign算法分析
安卓逆向 -- Frida Hook某车_sign算法分析
127 0
|
7月前
|
Shell Android开发 数据安全/隐私保护
安卓逆向 -- Frida环境搭建(HOOK实例)
安卓逆向 -- Frida环境搭建(HOOK实例)
160 0
|
7月前
|
XML 数据库 数据安全/隐私保护
Android App规范处理中版本设置、发布模式、给数据集SQLite加密的讲解及使用(附源码 超详细必看)
Android App规范处理中版本设置、发布模式、给数据集SQLite加密的讲解及使用(附源码 超详细必看)
79 0
|
算法 安全 Android开发
安卓逆向 -- Frida Hook某车_sign算法分析
安卓逆向 -- Frida Hook某车_sign算法分析
95 0
|
Shell Android开发 数据安全/隐私保护
安卓逆向 -- Frida环境搭建(HOOK实例)
安卓逆向 -- Frida环境搭建(HOOK实例)
320 0