Comparing version 1.1.2 to 2.0.0
56
cli.js
#!/usr/bin/env node | ||
const mri = require('mri') | ||
const opt = require('./lib/options') | ||
const { request, metrics } = require('./lib') | ||
const { replace, csv, date_ago } = require('./lib/util') | ||
const { query, report } = require('./lib') | ||
const { replace, csv, date_ago, format } = require('./lib/util') | ||
const flags = mri(process.argv.slice(2), { | ||
alias: { | ||
c: 'csv', | ||
k: 'keys', | ||
t: 'types', | ||
a: 'auto', | ||
d: 'done', | ||
t: 'todo', | ||
u: 'user', | ||
p: 'pass', | ||
j: 'jira', | ||
e: 'endpoint', | ||
q: 'query', | ||
h: 'help' | ||
}, | ||
default: opt | ||
}); | ||
const flags = mri(process.argv.slice(2), require('./lib/config')); | ||
validate(flags) | ||
run(flags) | ||
.then(console.log) | ||
.catch(handle_error); | ||
if (flags.help) { | ||
console.log(require('./lib/help')) | ||
process.exit(0); | ||
} | ||
async function run(opt) { | ||
const api = request(opt); | ||
const query = replace(opt.query, opt) | ||
const issues = await api(query) | ||
const res = metrics(opt, issues) | ||
if (flags.report) { | ||
report(flags) | ||
.then(format(flags)) | ||
.then(console.log) | ||
.catch(handle_error) | ||
} | ||
if (opt.csv) { | ||
return csv(res) | ||
} | ||
return res; | ||
if (!flags.report) { | ||
query(flags) | ||
.then(format(flags)) | ||
.then(console.log) | ||
.catch(handle_error) | ||
} | ||
@@ -47,7 +32,2 @@ | ||
if (flags.help) { | ||
console.log(require('./lib/help')) | ||
process.exit(0); | ||
} | ||
if (!opt.jira) { | ||
@@ -54,0 +34,0 @@ error = true |
const pkg = require('../package.json') | ||
const opt = require('./options') | ||
const opt = require('./config') | ||
@@ -25,2 +25,4 @@ const help =` | ||
-e, --endpoint JIRA JQL /search endpoint [${opt.endpoint}] | ||
--period Period of time to collect metrics, in days [${opt.period}] | ||
-i, --interval Interval to split metrics on, in days [${opt.interval}] | ||
@@ -35,14 +37,15 @@ All options can be overriden by setting appropiate environment variable, ie: | ||
> kbmeh | ||
Usage examples: | ||
Options: | ||
Collect metrics for the last 90 days using 15 days intervals | ||
-r, --range Range of time to collect metrics, in days [${opt.range}] | ||
-i, --interval Interval to split metrics on, in days [${opt.interval}] | ||
> kbme --report --interval 15 --period 90 >> metrics.csv | ||
Usage: | ||
> kbme -r 365 -i 15 --csv >> historical.csv | ||
Adds a new line to the previous report using data from last 15 days | ||
> kbme --auto 15 --csv >> metrics.csv | ||
` | ||
module.exports = help |
const got = require('got') | ||
const { pad, date_ago, days_between, num_reducer, replace } = require('./util') | ||
const { pad, date_ago, days_between, num_reducer, replace, generate_dates } = require('./util') | ||
@@ -10,2 +10,4 @@ module.exports = { | ||
date_to_status, | ||
query, | ||
report | ||
} | ||
@@ -19,3 +21,3 @@ | ||
return async (jql) => | ||
await req(replace(endpoint, {jira, jql}), { | ||
req(replace(endpoint, {jira, jql}), { | ||
json: true, | ||
@@ -139,1 +141,27 @@ auth: `${user}:${pass}` | ||
} | ||
/** | ||
* Runs the query and produces output | ||
* @param {Object} opt | ||
*/ | ||
async function query(opt, req = got) { | ||
const api = request(opt, req); | ||
const query = replace(opt.query, opt) | ||
const issues = await api(query) | ||
const res = metrics(opt, issues) | ||
return res; | ||
} | ||
/** | ||
* Runs the query for all specified dates | ||
* @param {Object} opt | ||
*/ | ||
async function report(opt, req = got) { | ||
const xtend = Object.assign | ||
const dates = generate_dates(opt.interval, opt.period) | ||
return Promise.all(dates | ||
.map(date => xtend({}, opt, date)) | ||
.map(opts => query(opts, req).then(data => data))) | ||
} |
module.exports = { | ||
pad, | ||
csv, | ||
toJSON, | ||
date_ago, | ||
@@ -8,2 +9,3 @@ days_between, | ||
replace, | ||
format, | ||
generate_dates | ||
@@ -24,7 +26,19 @@ } | ||
*/ | ||
function csv(res) { | ||
return Object.values(res).join(', ') | ||
function csv(data) { | ||
if (!Array.isArray(data)) { | ||
return Object.values(data).join(', ') | ||
} | ||
return data.map(csv).join('\n') | ||
} | ||
/** | ||
* Returns a prettified JSON string | ||
* @param {Array} data | ||
*/ | ||
function toJSON(data) { | ||
return JSON.stringify(data, null, 2) | ||
} | ||
/** | ||
* Returns the date for given days back | ||
@@ -95,1 +109,7 @@ * @param {number} days | ||
} | ||
function format(opt) { | ||
if (opt.csv) return data => csv(data) | ||
return data => toJSON(data) | ||
} |
{ | ||
"name": "kbme", | ||
"version": "1.1.2", | ||
"version": "2.0.0", | ||
"description": "Gather kanban metrics from your JIRA instance", | ||
"main": "lib/index.js", | ||
"bin": { | ||
"kbme": "cli.js", | ||
"kbmeh": "history.js" | ||
"kbme": "cli.js" | ||
}, | ||
@@ -10,0 +9,0 @@ "engines": { |
@@ -25,3 +25,2 @@ # kbme | ||
### `kbme` | ||
Use the `kbme` command to gather information for a particular period of time | ||
@@ -31,4 +30,15 @@ | ||
#### Options | ||
Collect metrics for the last 90 days using 15 days intervals | ||
> `kbme --report --interval 15 --period 90 >> metrics.csv` | ||
Adds a new line to the previous report using data from last 15 days | ||
> `kbme --auto 15 --csv >> metrics.csv` | ||
### Options | ||
-c, --csv Outputs comma separated values [false] | ||
@@ -47,19 +57,10 @@ -k, --keys Comma separated list of projects keys | ||
-e, --endpoint JIRA JQL /search endpoint [%jira/jira/rest/api/2/search?jql=%jql&expand=changelog&maxResults=1000] | ||
--period Period of time to collect metrics, in days [${opt.period}] | ||
-i, --interval Interval to split metrics on, in days [${opt.interval}] | ||
### `kbmeh` | ||
## Automatic environment variables detection | ||
Use the `kbmeh` command to generate an automated historical output for a given period and intervals, for example, collect metrics for last 365 days on intervals of 15 days: | ||
`kbmeh --range 365 --interval 15 --csv >> metrics.csv` | ||
#### Options | ||
-r, --range Range of time to collect metrics, in days [365] | ||
-i, --interval Interval to split metrics on, in days [15] | ||
### Automatic environment variables detection | ||
You can create a `.env` file from which `kbme` will read environment variables, use this to setup a project you want constant metrics from. | ||
#### Sample .env file | ||
### Sample .env file | ||
```` | ||
@@ -70,4 +71,5 @@ KBME_JIRA="http://server-url.com" | ||
KBME_AUTO=15 | ||
KBME_RANGE=365 | ||
KBME_PERIOD=365 | ||
KBME_INTERVAL=15 | ||
KBME_REPORT=true | ||
KBME_START="2017-01-01" | ||
@@ -74,0 +76,0 @@ KBME_FINISH="2017-06-01" |
const { got } = require('./mocks') | ||
const { date_ago } = require('../lib/util') | ||
const { issues } = require('./mocks/issues.json') | ||
const { request, lead, cycle, metrics, date_to_status } = require('../lib') | ||
const { request, lead, cycle, metrics, date_to_status, query, report } = require('../lib') | ||
let options = { | ||
auto: false, | ||
done: 'Done', | ||
todo: 'ToDo', | ||
start: '2017-08-01', | ||
finish: '2017-08-26', | ||
jira: 'test', | ||
user: 'user', | ||
pass: 'pass', | ||
endpoint: 'test', | ||
query: 'test', | ||
interval: 2, | ||
period: 4 | ||
} | ||
const makeOptions = (opts) => Object.assign({}, options, opts) | ||
describe('lib', () => { | ||
@@ -50,12 +67,3 @@ describe('#request', () => { | ||
describe('#metrics', () => { | ||
let options = { | ||
auto: false, | ||
done: 'Done', | ||
todo: 'ToDo', | ||
start: '2017-08-01', | ||
finish: '2017-08-26', | ||
} | ||
const makeOptions = (opts) => Object.assign({}, options, opts) | ||
describe('automatic period', () => { | ||
@@ -78,2 +86,20 @@ it('should not be used when false', () => { | ||
}) | ||
describe('#query', () => { | ||
describe('should collect metrics for specific interval', () => { | ||
it('should not be used when false', async () => { | ||
const res = await query(options, got) | ||
expect(res).toMatchObject({throughput: 0.16}) | ||
}) | ||
}) | ||
}) | ||
describe('#report', () => { | ||
describe('should collect metrics for specific period & interval', () => { | ||
it('should not be used when false', async () => { | ||
const res = await report(options, got) | ||
expect(res).toHaveLength(2) | ||
}) | ||
}) | ||
}) | ||
}) |
exports.issues = require('./issues.json') | ||
exports.got = async function() { | ||
return await new Promise((res, rej) => { | ||
res({ | ||
return new Promise((resolve, reject) => { | ||
resolve({ | ||
body: exports.issues | ||
@@ -6,0 +6,0 @@ }) |
@@ -1,4 +0,8 @@ | ||
const { pad, csv, date_ago, days_between, num_reducer, replace, generate_dates } = require('../lib/util') | ||
const { pad, csv, toJSON, date_ago, days_between, num_reducer, replace, generate_dates, format } = require('../lib/util') | ||
const pretty = `{ | ||
"a": "x", | ||
"b": "y", | ||
"c": "z" | ||
}` | ||
describe('util', () => { | ||
@@ -22,4 +26,15 @@ describe('#pad', () => { | ||
}) | ||
test('should handle arrays', () => { | ||
expect(csv([{}])).toBe('') | ||
expect(csv([{a:'x', b: 'y', c: 'z'}])).toBe('x, y, z') | ||
}) | ||
}) | ||
describe('#toJSON', () => { | ||
test('should output prettified json', () => { | ||
expect(toJSON({a:'x', b: 'y', c: 'z'})).toBe(pretty) | ||
}) | ||
}) | ||
describe('#date_ago', () => { | ||
@@ -93,2 +108,13 @@ const d = new Date() | ||
}) | ||
describe('#format', () => { | ||
test('should return correct output based on input', () => { | ||
const json = format({}) | ||
const comma = format({csv: true}) | ||
expect(typeof json).toBe('function') | ||
expect(typeof comma).toBe('function') | ||
expect(json({a:'x', b: 'y', c: 'z'})).toBe(pretty) | ||
expect(comma({a: 1, b: 2})).toBe('1, 2') | ||
}) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112547
1069
86
16
15