Added config file which solves #1

This commit is contained in:
Ramon Gebben
2018-03-29 15:37:45 +02:00
parent 929db0470f
commit 256c5b2445
8 changed files with 249 additions and 77 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
node_modules
.config

View File

@@ -6,15 +6,14 @@ A very *very* simple cli to check merge requests on Gitlab.
## Install
```
yarn add @pindakaasman/mergify --global
yarn global add @pindakaasman/mergify
```
Add `GITLAB_USER_ID` and `GITLAB_PRIVATE_TOKEN` to your `.profile` or `.bashrc` and `source` it.
To complete setup you will need to run the `configure` command to provide access to the Gitlab API.
Documentation on how to get a private token can be [found at Gitlab](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html).
```
export GITLAB_PRIVATE_TOKEN=TOKEN_HERE
export GITLAB_ID=USER_ID
mergify --configure
```
## Usage

150
index.js
View File

@@ -4,23 +4,12 @@
const program = require('commander');
const R = require('ramda');
const chalk = require('chalk');
const inquirer = require('inquirer');
const pack = require('./package.json');
const { getMergeRequests } = require('./lib/getMergeRequests');
const {
GITLAB_USER_ID = 0,
GITLAB_PRIVATE_TOKEN,
} = process.env;
if (!GITLAB_PRIVATE_TOKEN || GITLAB_USER_ID === 0) {
throw new Error(
`It looks like \`mergify\` was not properly configured.
Please add \`GITLAB_USER_ID\` and \`GITLAB_PRIVATE_TOKEN\` to the environment`);
}
const currentUserId = parseInt(GITLAB_USER_ID);
const padRight = (str, n, fill = '0') => str.length < n ? padRight(str + fill, n, fill) : str;
const { printMergeRequest } = require('./lib/printMergeRequest');
const { writeConfig } = require('./lib/writeConfig');
const { readConfig } = require('./lib/readConfig');
const simplifyMergeRequest = R.pick([
'title',
@@ -33,62 +22,64 @@ const simplifyMergeRequest = R.pick([
'web_url'
]);
const states = {
merged: chalk.blue,
closed: chalk.red,
opened: chalk.green,
const getAll = async () => {
console.log('#getAll')
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.forEach(printMergeRequest);
};
const printMergeRequest = ({
title,
state,
author: { username: author },
assignee: { username: assignee },
source_branch,
web_url,
}) => {
console.log(
`${padRight(`[${states[state](state)}]`, 15, ' ')}
${title}
Branch: ${chalk.cyan(source_branch)}
Assignee: ${chalk.cyan(assignee)}
Author: ${chalk.cyan(author)}
${chalk.gray(web_url)}
`,
);
const getAllAssigned = async ({ userId }) => {
console.log('#getAllAssigned', userId)
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.filter(({ state, assignee: { id: assignee } }) => state !== 'merged' && assignee === userId)
.forEach(printMergeRequest);
}
const getAllSubmitted = async ({ userId }) => {
console.log('#getAllSubmitted', userId)
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.filter(({ state, author: { id: author } }) => author === userId && state !== 'merged')
.forEach(printMergeRequest);
}
const configure = async () => {
try {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'userId',
message: 'What is your Gitlab User ID?'
},
{
type: 'password',
name: 'privateToken',
message: 'What private token shall we use?',
},
{
type: 'input',
name: 'domain',
default: 'gitlab.com',
message: 'On what domain is your Gitlab instance?'
}
]);
return writeConfig(answers);
} catch (error) {
throw new Error(error);
process.exit(1);
}
}
program
.name('mergify')
.version(pack.version)
const getAll = async () => {
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.forEach(printMergeRequest);
};
const getAllAssigned = async () => {
if (currentUserId === 1) throw new Error('No user ID configured.');
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.filter(({ state, assignee: { id: assignee } }) => state !== 'merged' && assignee === currentUserId)
.forEach(printMergeRequest);
}
const getAllSubmitted = async () => {
if (currentUserId === 1) throw new Error('No user ID configured.');
const mergeRequests = await getMergeRequests();
const simplifiedMergeRequest = R.map(simplifyMergeRequest)(mergeRequests);
simplifiedMergeRequest
.filter(({ state, author: { id: author } }) => author === currentUserId && state !== 'merged')
.forEach(printMergeRequest);
}
const options = [
{
trigger: '-a --all',
@@ -105,11 +96,32 @@ const options = [
description: 'Get all open merge request submitted to you',
fn: getAllSubmitted
},
]
{
trigger: '-c --configure',
description: 'Setup or update required config',
fn: configure
},
];
options.forEach(({ trigger, description, fn }) => {
program.option(trigger, description, fn);
});
const run = async() => {
let config = await readConfig();
// Start
program.parse(process.argv);
const {
userId,
privateToken
} = config;
if (!userId || !privateToken) {
await configure();
config = await readConfig();
console.log('🎉 All set, your ready to mergify!');
}
options.forEach(({ trigger, description, fn }) => {
program.option(trigger, description, (...args) => fn(config, ...args));
});
return program
};
run().then(p => p.parse(process.argv));

View File

@@ -0,0 +1,30 @@
const chalk = require('chalk');
const states = {
merged: chalk.blue,
closed: chalk.red,
opened: chalk.green,
};
const printMergeRequest = ({
title,
state,
author: { username: author },
assignee: { username: assignee },
source_branch,
web_url,
}) => {
console.log(
`
${`[${states[state](state)}]`}
${title}
Branch: ${chalk.cyan(source_branch)}
Assignee: ${chalk.cyan(assignee)}
Author: ${chalk.cyan(author)}
${chalk.gray(web_url)}`,
);
}
module.exports = {
printMergeRequest
};

21
lib/readConfig/index.js Normal file
View File

@@ -0,0 +1,21 @@
const { readFile } = require('fs');
const { promisify } = require('util');
const readFileAsync = promisify(readFile);
async function readConfig() {
const configFileName = `${process.cwd()}/.config`;
try {
const config = await readFileAsync(configFileName, 'utf8');
return JSON.parse(config);
} catch(_) {
console.log(`
Oh no, \`mergify\` is not configured yet.
Let configure it
`);
return {};
}
}
module.exports = {
readConfig
};

15
lib/writeConfig/index.js Normal file
View File

@@ -0,0 +1,15 @@
const { writeFile } = require('fs');
const { promisify } = require('util');
const writeFileAsync = promisify(writeFile);
async function writeConfig(config) {
const configFileName = `${process.cwd()}/.config`;
config.userId = parseInt(config.userId);
const body = JSON.stringify(config, null, 2);
return writeFileAsync(configFileName, body, 'utf8');
}
module.exports = {
writeConfig
};

View File

@@ -2,6 +2,7 @@
"dependencies": {
"chalk": "^2.3.2",
"commander": "^2.15.1",
"inquirer": "^5.2.0",
"node-fetch": "^2.1.2",
"ramda": "^0.25.0"
},

101
yarn.lock
View File

@@ -499,6 +499,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
ci-info@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2"
@@ -512,6 +516,16 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -862,6 +876,14 @@ extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
external-editor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
dependencies:
chardet "^0.4.0"
iconv-lite "^0.4.17"
tmp "^0.0.33"
extglob@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
@@ -907,6 +929,12 @@ fb-watchman@^2.0.0:
dependencies:
bser "^2.0.0"
figures@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
dependencies:
escape-string-regexp "^1.0.5"
filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@@ -1231,7 +1259,7 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
iconv-lite@0.4.19:
iconv-lite@0.4.19, iconv-lite@^0.4.17:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@@ -1261,6 +1289,24 @@ ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
inquirer@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726"
dependencies:
ansi-escapes "^3.0.0"
chalk "^2.0.0"
cli-cursor "^2.1.0"
cli-width "^2.0.0"
external-editor "^2.1.0"
figures "^2.0.0"
lodash "^4.3.0"
mute-stream "0.0.7"
run-async "^2.2.0"
rxjs "^5.5.2"
string-width "^2.1.0"
strip-ansi "^4.0.0"
through "^2.3.6"
invariant@^2.2.2:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@@ -1425,6 +1471,10 @@ is-primitive@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
@@ -1957,7 +2007,7 @@ lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4:
lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.3.0:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
@@ -2095,6 +2145,10 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
nan@^2.3.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
@@ -2250,6 +2304,12 @@ once@^1.3.0, once@^1.3.3, once@^1.4.0:
dependencies:
wrappy "1"
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
dependencies:
mimic-fn "^1.0.0"
optimist@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
@@ -2280,7 +2340,7 @@ os-locale@^2.0.0:
lcid "^1.0.0"
mem "^1.1.0"
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -2625,6 +2685,13 @@ resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
dependencies:
onetime "^2.0.0"
signal-exit "^3.0.2"
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -2641,6 +2708,18 @@ rimraf@2, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1:
dependencies:
glob "^7.0.5"
run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
dependencies:
is-promise "^2.1.0"
rxjs@^5.5.2:
version "5.5.8"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.8.tgz#b2b0809a57614ad6254c03d7446dea0d83ca3791"
dependencies:
symbol-observable "1.0.1"
safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -2872,7 +2951,7 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
string-width@^2.0.0, string-width@^2.1.1:
string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
dependencies:
@@ -2935,6 +3014,10 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
symbol-observable@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
@@ -2974,6 +3057,16 @@ throat@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
dependencies:
os-tmpdir "~1.0.2"
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"