(main, { redact } = {})
| 150 | } |
| 151 | |
| 152 | const run = async (main, { redact } = {}) => { |
| 153 | const argv = {} |
| 154 | for (const [k, v] of Object.entries(nopt({}, {}, process.argv))) { |
| 155 | argv[k] = v |
| 156 | // create camelcase key too |
| 157 | argv[k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = v |
| 158 | } |
| 159 | |
| 160 | const defaultLevels = ['error', 'warn', 'info'] |
| 161 | process.on('log', (l, ...args) => { |
| 162 | if (argv.debug || process.env.CI || defaultLevels.includes(l)) { |
| 163 | for (const line of formatWithOptions({ colors: true }, ...args).split('\n')) { |
| 164 | const redacted = redact ? line.replaceAll(redact, '***') : line |
| 165 | // eslint-disable-next-line no-console |
| 166 | console.error(l.slice(0, 4).toUpperCase(), redacted) |
| 167 | } |
| 168 | } |
| 169 | }) |
| 170 | |
| 171 | log.silly('argv', argv) |
| 172 | |
| 173 | try { |
| 174 | const res = await main(argv) |
| 175 | if (res) { |
| 176 | // eslint-disable-next-line no-console |
| 177 | console.log(res) |
| 178 | } |
| 179 | } catch (err) { |
| 180 | process.exitCode = err.status || 1 |
| 181 | |
| 182 | const messages = [] |
| 183 | if (err.args) { |
| 184 | // its an error from promise-spawn |
| 185 | for (const [name, value] of Object.entries(err)) { |
| 186 | if (value) { |
| 187 | let msg = Array.isArray(value) ? value.join(' ') : value.toString() |
| 188 | let sep = ' ' |
| 189 | if (msg.includes('\n')) { |
| 190 | msg = ' ' + msg.split('\n').map(l => l.trim()).join('\n ').trim() |
| 191 | sep = '\n' |
| 192 | } |
| 193 | messages.push(`${name}:${sep}${msg}`) |
| 194 | } |
| 195 | // delete from error object so we can log them separately |
| 196 | delete err[name] |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | log.error(err) |
| 201 | if (messages.length) { |
| 202 | log.error(messages.join('\n')) |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | module.exports = { |
| 208 | CWD, |
no test coverage detected