Permalink
Browse files

Add verbose mode

  • Loading branch information...
Kikobeats committed May 5, 2018
1 parent 1ee03ae commit 27ddf73947e329923ff7bc8efa926396ec9f3ca2
Showing with 146 additions and 102 deletions.
  1. +8 −2 bin/cli/help.js
  2. +23 −13 bin/cli/index.js
  3. +1 −16 bin/view/colorize.js
  4. +20 −0 bin/view/constant.js
  5. +0 −33 bin/view/helpers.js
  6. +41 −9 bin/view/index.js
  7. +51 −28 bin/view/render.js
  8. +2 −1 package.json
@@ -9,12 +9,13 @@ module.exports = gray(`${gray(description)}
$ ${green('urlint')} <url> [<flags>]
Flags
-c, --concurrence Number of concurrent petitions (defaults to 30)
-c, --concurrence Number of concurrent petitions (defaults to 8)
-f, --followRedirect Redirect responses should be followed (defaults to true)
-h, --help Show the help information
-q, --quiet Show only the resume (defaults to false)
-r, --retries Number of request retries when network errors happens (defaults to 2)
-t, --timeout Milliseconds to wait before consider a timeout response
-v, --verbose Enable verbose output (defaults to false)
-v, --version Output the version number
-w, --whitelist Add one or multiple url pattern to ignore
@@ -26,4 +27,9 @@ module.exports = gray(`${gray(description)}
– Exclude a particular URL
$ ${green(
'urlint'
)} https://kikobeats.com --whitelist https://www.linkedin.com/in/kikobeats'`)
)} https://kikobeats.com --whitelist https://www.linkedin.com/in/kikobeats
– Exclude based in a matcher
$ ${green(
'urlint'
)} https://kikobeats.com --whitelist "https://github.com*`)
@@ -3,6 +3,7 @@
'use strict'
const { chain, size, concat, first, isEmpty } = require('lodash')
const AggregateError = require('aggregate-error')
const normalizeUrl = require('normalize-url')
const reachableUrl = require('reachable-url')
const { STATUS_CODES } = require('http')
@@ -21,19 +22,21 @@ const getUrl = async input => {
return url
}
const messageError = errors => {
const messageError = ({ errors, url: originalUrl }) => {
return chain(errors)
.first()
.thru(err => {
err = dnsErrors(err)
err = Object.assign({}, err, dnsErrors(err))
const url = err.url || originalUrl
const statusCode = err.statusCode || err.status
const httpMessage = STATUS_CODES[statusCode]
return { ...err, httpMessage, statusCode }
const httpMessage = STATUS_CODES[statusCode] || 'Error'
return { ...err, httpMessage, statusCode, url }
})
.thru(({ httpMessage, statusCode, method, url }) => {
const status = statusCode ? `(${red(statusCode)}) ` : ''
const message = status ? gray(httpMessage) : red(httpMessage)
return `${gray(`${message} ${status}${normalizeUrl(url)}`)}`
})
.thru(
({ httpMessage, statusCode, method, url }) =>
`${gray(`${httpMessage} (${red(statusCode)}) ${normalizeUrl(url)}`)}`
)
.value()
}
@@ -51,7 +54,12 @@ const cli = require('meow')(require('./help'), {
concurrence: {
alias: 'c',
type: 'number',
default: 30
default: 8
},
verbose: {
alias: 'v',
type: 'boolean',
default: false
},
quiet: {
alias: 'q',
@@ -86,9 +94,11 @@ if (isEmpty(cli.input)) {
process.exit()
}
let url
;(async () => {
try {
const url = await getUrl(first(cli.input))
url = first(cli.input)
url = await getUrl(url)
const opts = Object.assign({}, cli.flags, {
whitelist: cli.flags.whitelist && concat(cli.flags.whitelist)
@@ -98,9 +108,9 @@ if (isEmpty(cli.input)) {
const emitter = await urlint(urls, opts)
view({ total: size(urls), emitter, ...opts })
} catch (aggregatedError) {
const error = chain(Array.from(aggregatedError))
const message = messageError(error)
} catch (error) {
const errors = error instanceof AggregateError ? Array.from(error) : [error]
const message = messageError({ errors, url })
console.log(message)
process.exit(1)
}
@@ -4,22 +4,7 @@ const { mapValues } = require('lodash')
const chalk = require('chalk')
const THEME = {
red: '#ff5c57',
green: '#5af78e',
yellow: '#f3f99d',
blue: '#57c7ff',
magenta: '#ff6ac1',
cyan: '#9aedfe'
}
const STATUS_CODE_COLOR = {
'2': 'green',
'3': 'blue',
'4': 'yellow',
'5': 'red',
'9': 'red'
}
const { THEME, STATUS_CODE_COLOR } = require('./constant')
const statusCodeColors = mapValues(THEME, hex => chalk.hex(hex))
@@ -0,0 +1,20 @@
'use strict'
module.exports = {
SUCCESS_STATUS_CODES: ['2xx', '3xx'],
THEME: {
red: '#ff5c57',
green: '#5af78e',
yellow: '#f3f99d',
blue: '#57c7ff',
magenta: '#ff6ac1',
cyan: '#9aedfe'
},
STATUS_CODE_COLOR: {
'2': 'green',
'3': 'blue',
'4': 'yellow',
'5': 'red',
'9': 'red'
}
}

This file was deleted.

Oops, something went wrong.
@@ -1,43 +1,75 @@
'use strict'
const { isNil, includes, isEmpty, first, toNumber, chain } = require('lodash')
const neatLog = require('neat-log')
const { processExit, setState } = require('./helpers')
const { SUCCESS_STATUS_CODES } = require('./constant')
const render = require('./render')
module.exports = ({ total, emitter, quiet, logspeed, ...opts }) => {
const setState = (state, data) => {
const { statusCodeGroup } = data
const status = state.count[statusCodeGroup]
const linkStatus = state.links[statusCodeGroup]
const count = { [statusCodeGroup]: isNil(status) ? 1 : status + 1 }
const links = {
[statusCodeGroup]: isNil(linkStatus) ? [data] : linkStatus.concat(data)
}
return { count, links }
}
const sortByStatusCode = data =>
chain(data)
.toPairs()
.sortBy(pair => toNumber(first(pair).charAt(0)))
.fromPairs()
.value()
module.exports = ({ total, emitter, quiet, verbose, logspeed, ...opts }) => {
const state = {
quiet,
verbose,
total,
current: 0,
count: {},
links: {},
end: false,
fetchingUrl: '',
startTimestamp: Date.now(),
timestamp: {}
timestamp: {},
exitCode: null
}
const neat = neatLog(render, { ...opts, logspeed, state })
neat.use((state, bus) => {
emitter.on('status', data => {
const newState = setState(state, data)
state.count = { ...state.count, ...newState.count }
state.count = sortByStatusCode({ ...state.count, ...newState.count })
state.links = { ...state.links, ...newState.links }
})
emitter.on('fetching', ({ url }) => {
state.fetchingUrl = url
emitter.on('fetching', data => {
state.fetchingUrl = data.url
++state.current
})
emitter.on('end', data => {
state.end = true
neat.render()
processExit(data)
const errorCodes = chain(data)
.keys()
.remove(statusCode => !includes(SUCCESS_STATUS_CODES, statusCode))
.value()
state.exitCode = isEmpty(errorCodes) ? 0 : 1
})
setInterval(() => bus.emit('render'), logspeed)
setInterval(() => {
bus.emit('render')
if (state.exitCode) process.exit(state.exitCode)
}, logspeed)
})
}
@@ -1,40 +1,36 @@
'use strict'
const { size, concat, toNumber, first, chain, map, reduce } = require('lodash')
const { pick, omit, size, concat, map, reduce } = require('lodash')
const spinner = require('ora')({ text: '', color: 'gray' })
const prettyMs = require('pretty-ms')
const { EOL } = require('os')
const spinner = require('ora')({ text: '', color: 'gray' })
const colorize = require('./colorize')
const { green, blue, gray, byStatusCode, getRequestColor } = colorize
const { SUCCESS_STATUS_CODES } = require('./constant')
const { blue, gray, byStatusCode, getRequestColor } = colorize
const resumeCount = (count, statusCode) =>
byStatusCode(statusCode, `${statusCode} ${count}`)
const sortByStatusCode = data =>
chain(data)
.toPairs()
.sortBy(pair => {
const statusCode = first(pair)
return toNumber(statusCode.charAt(0))
})
.fromPairs()
.value()
const renderTotal = ({ startTimestamp, count }) => {
const total = reduce(count, (acc, count) => acc + count, 0)
const timestamp = prettyMs(Date.now() - startTimestamp)
return gray(`${total} links in ${timestamp}`)
}
const renderCount = state => {
const { count, fetchingUrl, startTimestamp, current, total } = state
const countByStatusCode = map(count, resumeCount).join(EOL) || green(0)
const spinnerFrame = spinner.frame()
const renderProgress = ({ fetchingUrl, current, total, startTimestamp }) => {
const timestamp = blue(prettyMs(Date.now() - startTimestamp))
const spinnerFrame = spinner.frame()
const url = gray(fetchingUrl)
const progress = gray(`${current} of ${total}`)
return `${EOL}${countByStatusCode}${EOL}${EOL}${timestamp} ${spinnerFrame}${progress} ${url}`
return `${timestamp} ${spinnerFrame}${progress} ${url}`
}
const renderResume = ({ startTimestamp, count, links }) => {
const info = map(sortByStatusCode(count), (count, statusCode) => {
const renderLinks = ({ count, links }, { omitErrors = false } = {}) => {
const status = omitErrors ? omit(count, SUCCESS_STATUS_CODES) : count
const info = map(status, (count, statusCode) => {
const countByStatusCode = resumeCount(count, statusCode)
const rows = map(
@@ -62,20 +58,47 @@ const renderResume = ({ startTimestamp, count, links }) => {
return `${colorizeStatusCode} ${nRedirects}${redirects} ${colorizeTimestamp}`
}
).join(EOL)
return countByStatusCode + EOL + rows + EOL
return `${countByStatusCode}${EOL}${rows}${EOL}`
}).join(EOL)
const total = reduce(count, (acc, count) => acc + count, 0)
const timestamp = prettyMs(Date.now() - startTimestamp)
return gray(info)
}
const renderCount = state => {
const { count, end } = state
const total = end ? renderTotal(state) : renderProgress(state)
const header = (() => {
if (!size(count)) return ''
const statusCodes = end ? pick(count, SUCCESS_STATUS_CODES) : count
const statusCodesByCount = map(statusCodes, resumeCount).join(EOL)
return `${EOL}${statusCodesByCount}${EOL}`
})()
return gray(`${EOL}${info}${EOL}${total} links in ${timestamp}`)
const footer = `${EOL}${total}`
const links = end ? `${EOL}${renderLinks(state, { omitErrors: true })}` : ''
return `${header}${links}${footer}`
}
const renderResume = state => {
const links = renderLinks(state)
const total = renderTotal(state)
return gray(`${EOL}${links}${EOL}${total}`)
}
module.exports = state => {
if (state.end) return renderResume(state)
if (state.quiet) return ''
return renderCount(state)
const { verbose, quiet, end } = state
if (!verbose) {
if (quiet) return end ? renderCount(state) : ''
return renderCount(state)
}
if (quiet) return end ? renderResume(state) : ''
return end ? renderResume(state) : renderCount(state)
}
module.exports.count = renderCount
@@ -33,14 +33,15 @@
],
"dependencies": {
"@metascraper/helpers": "~3.10.7",
"aggregate-error": "~1.0.0",
"chalk": "~2.4.1",
"dnserrors": "~2.0.3",
"got": "~8.3.0",
"html-urls": "~1.0.5",
"is-ci": "~1.1.0",
"lodash": "~4.17.10",
"meow": "~5.0.0",
"neat-log": "~2.2.0",
"neat-log": "~2.3.0",
"normalize-url": "~2.0.1",
"ora": "~2.1.0",
"pretty-ms": "~3.1.0",

0 comments on commit 27ddf73

Please sign in to comment.