1 | #!/usr/bin/env node
|
2 |
|
3 | const path = require('path');
|
4 | const fs = require('fs');
|
5 | const fsP = require('pify')(fs);
|
6 | const minimist = require('minimist');
|
7 | const ora = require('ora');
|
8 | const globby = require('globby');
|
9 | const chalk = require('chalk');
|
10 | const symbols = require('log-symbols');
|
11 | const reachableUrls = require('.');
|
12 |
|
13 | const format = (object, compact = false) => {
|
14 | let output = '\n';
|
15 |
|
16 | for (const file of Object.keys(object)) {
|
17 | output += ` ${chalk.underline(file)}\n\n`;
|
18 |
|
19 | const result = object[file];
|
20 | const urls = Object.keys(result);
|
21 | const filteredUrls = compact ? urls.filter(url => !result[url]) : urls;
|
22 |
|
23 | for (const url of filteredUrls) {
|
24 | const reachable = result[url];
|
25 | const symbol = reachable ? symbols.success : symbols.error;
|
26 | output += ` ${symbol} ${url}\n`;
|
27 | }
|
28 |
|
29 | if (filteredUrls.length !== 0) {
|
30 | output += '\n';
|
31 | }
|
32 | }
|
33 |
|
34 | return output;
|
35 | };
|
36 |
|
37 | const argv = minimist(process.argv.slice(2), {
|
38 | alias: {
|
39 | c: 'compact',
|
40 | h: 'help',
|
41 | v: 'version'
|
42 | },
|
43 | boolean: [
|
44 | 'compact',
|
45 | 'help',
|
46 | 'version'
|
47 | ]
|
48 | });
|
49 |
|
50 | if (argv.v || argv.version) {
|
51 | console.log(require('./package').version);
|
52 | } else if (argv.h || argv.help) {
|
53 | fs.createReadStream(`${__dirname}/usage.txt`)
|
54 | .pipe(process.stdout)
|
55 | .on('close', () => process.exit(1));
|
56 | } else {
|
57 | let count = 0;
|
58 | let files = [];
|
59 | const spinner = ora('Checking files').start();
|
60 |
|
61 | globby(argv._)
|
62 | .then(foundFiles => {
|
63 | return foundFiles.map(file => path.resolve(process.cwd(), file));
|
64 | })
|
65 | .then(foundFiles => {
|
66 | files = foundFiles;
|
67 |
|
68 | return Promise.all(foundFiles.map(file => {
|
69 | return fsP.readFile(file).then(b => b.toString());
|
70 | }));
|
71 | })
|
72 | .then(texts => {
|
73 | return Promise.all(texts.map(text => {
|
74 | return reachableUrls(text).then(result => {
|
75 | spinner.text = `Checking files [${++count} of ${files.length}]`;
|
76 |
|
77 | return result;
|
78 | });
|
79 | }));
|
80 | })
|
81 | .then(results => {
|
82 | const object = {};
|
83 | files.forEach((file, index) => {
|
84 | object[file] = results[index];
|
85 | });
|
86 |
|
87 | spinner.stop();
|
88 | console.log(format(object, argv.c || argv.compact));
|
89 | process.exit(0);
|
90 | });
|
91 | }
|