不会写shell的程序员还是是好前端——用Node.JS完成git hooks

git hooks想必很多攻城狮都不生疏,官方关于hooks有细致的文档,也有站内网友的文章Git Hooks (1):引见,GIt Hooks (2):剧本分类,说的异常细致了,这里就不多做引见,这里重要引见一下如何写一个hook。

一个基础的git hook长什么样?

对git-hooks有一个入门熟悉的朋侪都晓得,hooks存放在git堆栈的.git/hooks目次下,个中包含很多hooks,这些是在git 堆栈建立的时刻自动天生的,后缀名一致都是.sample,示意这些hooks都是默许不启用的,当把后缀名去掉以后,就变成了能够运用的hook。

举个栗子

《不会写shell的程序员还是是好前端——用Node.JS完成git hooks》

pre-commit这个hook是在git commit的时刻触发的hook,这个hook内里写了什么呢?代码我就不贴了,没啥劲,重要的几点就是:

  1. 这是一个shell剧本

  2. 这个剧本运转了一些东西然后退出了

  3. 退出的时刻退出的错误码不是肯定的

这就是一个hook的最基础的构成:在敕令行实行git操纵的时刻,自动实行hooks目次下响应的可实行剧本,然后依据剧本的退出状况决议此次操纵是不是胜利。当退出的错误码不为0的时刻,示意失利,操纵停止,不然操纵继承。

模仿场景

假如如今有如许一个场景,在你的git堆栈里,请求不允许提交dist目次,而且经由历程mocha的测试,不然不允许提交,用git hook 怎么做呢?

起首,这是在提交的时刻的一个限定,所以应当斟酌运用pre-commit这个hook,代码就不写了(不会写shell… Orz),悉数历程以下:

  1. 搜检是不是有dist目次,假如没有的话下一步,不然退出,错误码置为1。

  2. 实行mocha敕令举行测试,假如测试悉数经由历程的话,退出,错误码为0,不然错误码为1,一样退出。

如许,当上述任何一步没有经由历程的时刻,这个hook就会被停止,git-commit就没法经由历程,也就达到了限定提交的目标。

shell剧本的局限性——不会写

作为一位一般的前端,兼,一位不太及格的工程师,我关于shell剧本实在是不熟悉,连Linux敕令都玩不转,别说写出666的shell剧本了,囧~ 所以要另辟巧径做这件事。

前端仔们对js应当是异常闇练的,所以假如能用js写hooks,那不就爽了?而Node.JS恰好给了我们愿望,感激不尽的话就不多说了,相对感动到哭!

《不会写shell的程序员还是是好前端——用Node.JS完成git hooks》

Node.js写起剧原本也异常简朴,比方一个最简朴的剧本

#!/usr/bin/env node

console.log('Hello World!');

给剧本给予可实行权限以后就完全能够当作shell剧原本跑了,麻麻再也不必忧郁我不会shell了。一样的,在hooks中我们也能够如许用。再举个栗子

《不会写shell的程序员还是是好前端——用Node.JS完成git hooks》

照样适才的场景,不允许有dist目次,同时经由历程一切mocha测试,用Node就能够如许写(此次我能show出代码了)

#!/usr/bin/env node
var fs = require('fs'),
    spawnSync = require('child_process').spawnSync;
if(fs.existsSync('./dist')){
    console.log('Commit Abort!Please remove dist directory.');
    process.exit(1);
}
// 运用同步要领spawnSync实行mocha,测试的结果在result.status中,经由历程为0,不经由历程为1
var result = spawnSync('./node_modules/.bin/mocha',['test']); 
if(result.status){
    console.log('Commit Abort!Test failure.');
}
process.exit(result.status);

这就是一个用Node.JS完成的基础的git-hook。

Node.JS的局限性——不能动

client-side hook的一个题目就是没法在跟着堆栈更改,假如项目成员多的话,每个人都需要在本身当地增加一次,hooks有更改了更新也比较贫苦。

解决计划

我个人对这个题目有一个简朴解决计划,我做了一个堆栈git-hooks-node,每次写好git hooks以后经由历程本身写的东西举行build,天生一个类似于装置器的文件,然后提交到长途堆栈,如pre-commit.js是hook详细的内容,pre-commit.installer.js是天生的装置文件,也是一个剧本,github上的每个文件都有响应的raw地点,如这个装置文件的地点为raw pre-commit.installer.js,然后mac OS下的用户就能够运用curl猎取剧本并运转,以下:

curl https://raw.githubusercontent.com/y8n/git-hooks-node/master/xgfe-ma/pre-commit.installer.js | node

装置结果以下

《不会写shell的程序员还是是好前端——用Node.JS完成git hooks》

如许只需写好一个hook并宣布,项目成员只需晓得地点就能够一键安转(想一想还有点小冲动呢)。如许虽然没有解决hook不会跟着堆栈挪动的题目,但也供应了一种在项目组里通用一套hook的计划。

其他解决要领

husky是GitHub上一个开源项目,它的做法是在npm install这个模块的时刻自动在.git/hooks目次下建立很多hooks,然后再在package.json中指定每个hook的实行剧本,以下

"scripts": {
    "precommit": "npm test",
    "prepush": "npm test",
    "commit-msg": "./validate-commit-msg.js",
    "...": "..."
  }

如许就能够把hooks跟着项目更改,真正做到项目成员共用一个git hook,但题目就是必须在项目中依靠husky,不过想一想如许的要领也比上面我的要领高妙很多 -.-!

    原文作者:y8n
    原文地址: https://segmentfault.com/a/1190000004918996
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞