Compare commits

...

3 Commits

Author SHA1 Message Date
akashnimare
9e3cfbd887 echo commit range on travis. 2018-01-30 22:46:52 +05:30
cPhost
720f42ca80 ci: Add commit linter and clean up code. 2018-01-30 11:07:41 -05:00
cPhost
e18ba5dab6 gitlint: Setup commit linter.
This will setup a commit hook that will check the commit msg run
`npm run lint-commits` to check all the commits. Additionaly setup
git hooks by running `npm run setup-gitlint-hooks`.
2018-01-30 08:58:19 -05:00
7 changed files with 257 additions and 2 deletions

View File

@@ -28,7 +28,13 @@ cache:
- app/node_modules
script:
- npm run travis
- echo $TRAVIS_COMMIT_RANGE
- echo ${TRAVIS_COMMIT_RANGE/.../..}
- echo "test"
- git log -4
- node ./tools/gitlint --ci-mode
- npm run travis
notifications:
webhooks:
urls:

View File

@@ -6,7 +6,7 @@ os: Previous Visual Studio 2015
cache:
- node_modules
install:
- ps: Install-Product node 6 x64
- git reset --hard HEAD
@@ -20,5 +20,6 @@ install:
build: off
test_script:
- node ./tools/gitlint --ci-mode
- npm run test
- npm run test-e2e

View File

@@ -27,6 +27,8 @@
"pack": "electron-builder --dir",
"dist": "electron-builder",
"mas": "electron-builder --mac mas",
"setup-gitlint-hooks": "node ./tools/gitlint/setup-gitlint-hook",
"lint-commits": "node ./tools/gitlint --all-commits",
"travis": "cd ./scripts && ./travis-build-test.sh"
},
"pre-commit": [
@@ -107,6 +109,7 @@
],
"devDependencies": {
"assert": "1.4.1",
"chalk": "^2.3.0",
"cp-file": "^5.0.0",
"devtron": "1.4.0",
"electron": "1.7.10",
@@ -151,6 +154,12 @@
"import/no-extraneous-dependencies": 0,
"no-prototype-builtins": 0
}
},
{
"files": "scripts/gitlint/*.js",
"rules": {
"unicorn/no-process-exit": 1
}
}
],
"ignore": [

31
tools/gitlint/ci.js Normal file
View File

@@ -0,0 +1,31 @@
const {run} = require('./helpers');
module.exports = () => {
if (process.argv.TRAVIS !== undefined) {
return travis();
}
return appveyor();
};
function travis() {
if (!process.env.TRAVIS_PULL_REQUEST) {
// Building against master last commit
return run('git log -1 HEAD');
}
const cmd = `git log ${process.env.TRAVIS_COMMIT_RANGE}`;
const commitRange = run(`git diff --name-only ${process.env.TRAVIS_COMMIT_RANGE}`);
process.stdout.write(`COMMIT_RANGE: ${commitRange}`, 'utf8');
return run(cmd);
}
function appveyor() {
if (!process.env.APPVEYOR_PULL_REQUEST_NUMBER) {
return run('git log -1 HEAD');
}
const cmd =
`git log origin/master...${process.env.APPVEYOR_PULL_REQUEST_HEAD_COMMIT}`;
return run(cmd);
}

91
tools/gitlint/helpers.js Normal file
View File

@@ -0,0 +1,91 @@
const {spawnSync} = require('child_process');
const chalk = require('chalk');
const commitMsgRegex = /[A-Z]+.*\.$/;
const isFullCommitRegex = /(\w|\W){1,}:\s{1}/;
const fullCommitRegex = /(\w|\W){1,}:\s{1}[A-Z]+.*\.$/;
function run(script) {
script = script.split(' ');
const cmd = script.splice(0, 1)[0];
const args = script;
const output = spawnSync(cmd, args, {
cwd: process.cwd(),
encoding: 'utf8',
windowsHide: true
}).stdout;
return output;
}
function garbageCollect(a) {
a.forEach((content, index) => {
if (content === '' || content === undefined) {
a.splice(index, 1);
}
});
return a;
}
function getAllCommits(output) {
output = output.split('\ncommits');
if (!output.length > 1) {
exports.error('There are no commits to lint.');
process.exit(1);
}
output = garbageCollect(output);
output.forEach((commit, index) => {
output[index] = 'commit' + commit;
});
return output;
}
function parseCommit(output) {
output = output.split('\n\n');
let commit = output[0].replace('commit ', '');
commit = commit.replace(/\n.*/g, '');
let commitHash = commit.split('');
commitHash = commitHash.slice(commitHash.length - 7);
commitHash = commitHash.join('');
const fullCommit = output[1].split('\n');
const commitMsg = fullCommit[0];
let lintingStatus = commitMsgRegex.test(commitMsg);
lintingStatus = (commitMsg.length <= 72);
if (lintingStatus && isFullCommitRegex(commitMsg)) {
lintingStatus = fullCommitRegex.test(commitMsg);
}
const result = {
failed: !lintingStatus,
commitHash
};
return result;
}
function logSuccess() {
console.log(chalk`{green commit linter:} commit linter passed.`);
process.exit(0);
}
function error(...args) {
args.unshift(chalk.red('ERROR! '));
console.error.apply(this, args);
}
function warn() {
// console.error(chalk`{yellow ${msg}}`);
}
module.exports = {
run,
getAllCommits,
parseCommit,
logSuccess,
error,
warn
};

44
tools/gitlint/index.js Normal file
View File

@@ -0,0 +1,44 @@
const helpers = require('./helpers');
const getCICmd = require('./ci');
let checkAllCommits = false;
let ciMode = false;
if (process.argv[2]) {
checkAllCommits = process.argv[2].includes('-a');
ciMode = process.argv[2] === '--ci-mode';
}
let cmd;
if (ciMode) {
cmd = getCICmd();
} else {
cmd =
checkAllCommits ? 'git log upstream/master...HEAD' : 'git log -1 HEAD';
}
const commits = helpers.run(cmd);
const commitsArray = helpers.getAllCommits(commits);
let lintFailed = false;
commitsArray.forEach(commit => {
const res = helpers.parseCommit(commit);
if (res.failed) {
const {commitHash} = res;
helpers.error(`commit ${commitHash} does not pass our commit style.`);
lintFailed = true;
} else {
helpers.logSuccess('Commit[s] follow the zulip-electron commit rules.');
}
});
if (lintFailed) {
helpers.warn(`
commit msg linting failed
-------------------------------
Reasons it does not have:
a) capitial latter at start of message
b) period at the end of commit or
c) Commit msg length is more than 72 charaters
`);
helpers.warn('Run with --no-verify flag to skip the commit-linter');
process.exit(1);
}

View File

@@ -0,0 +1,73 @@
// This script sets up the pre-push
// git hook which will be used to lint
// commits
const fs = require('fs');
const path = require('path');
const gitHooks = '../../.git/hooks';
const postCommitPath = path.resolve(__dirname, `${gitHooks}/post-commit`);
const prePushPath = path.resolve(__dirname, `${gitHooks}/pre-push`);
function scriptTemplate(cmds) {
cmds = cmds.join('');
const script = [
'#!/bin/sh',
'set -e',
'echo running gitlint...',
cmds,
'exit $?'
];
return script.join('\n');
}
const postCommitFile = scriptTemplate`node scripts/gitlint`;
const prePushFile = scriptTemplate`node scripts/gitlint --all-commits`;
function writeAndChmod(file, data) {
fs.writeFile(file, data, err => {
if (err) {
throw err;
}
fs.chmod(file, '777', err => {
if (err) {
const msg =
'chmod post-commit, pre-push hooks, at .git/hooks 0777 so they work!';
console.error(msg);
}
});
});
}
[postCommitPath, prePushPath].forEach((file, index) => {
fs.open(file, 'w+', err => {
if (err && err.code !== 'EEXIST') {
throw err;
}
const data = index === 0 ? postCommitFile : prePushFile;
writeAndChmod(file, data);
});
});
// Remove .sample files since
// sometimes the hooks do not work
const postCommitSampleFile = `${postCommitPath}.sample`;
const prePushSampleFile = `${prePushPath}.sample`;
function removeSampleFile(file) {
fs.unlink(file, err => {
if (err) {
throw err;
}
});
}
[postCommitSampleFile, prePushSampleFile].forEach(file => {
fs.exists(file, exists => {
if (exists) {
removeSampleFile(file);
}
});
});