• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hildjj / quence / 8992423935

07 May 2024 09:15PM UTC coverage: 95.84% (-0.2%) from 96.074%
8992423935

Pull #56

github

web-flow
Merge 526f4bfb4 into 105063f06
Pull Request #56: Update dependencies, including GHA

813 of 872 branches covered (93.23%)

Branch coverage included in aggregate %.

562 of 574 new or added lines in 11 files covered. (97.91%)

2 existing lines in 1 file now uncovered.

4232 of 4392 relevant lines covered (96.36%)

1365.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.77
/lib/cli.js
1
import {Command, Option} from 'commander';
8✔
2
import {SyntaxError, VALID_OUTPUTS, draw} from './index.js';
8✔
3
import {name, version} from '../package.js';
8✔
4
import fs from 'fs';
8✔
5
import path from 'path';
8✔
6

8✔
7
/**
8✔
8
 * @typedef {object} StdIO
8✔
9
 * @property {import('stream').Readable} stdin
8✔
10
 * @property {import('stream').Writable} stdout
8✔
11
 * @property {import('stream').Writable} stderr
8✔
12
 */
8✔
13

8✔
14
/**
8✔
15
 * @typedef {Partial<StdIO>} TestingOptions
8✔
16
 */
8✔
17

8✔
18
/**
8✔
19
 * Read all of stdin.
8✔
20
 *
8✔
21
 * @returns {Promise<string>}
8✔
22
 */
8✔
23
function stdin(stdio) {
4✔
24
  stdio.stdin.setEncoding('utf8');
4✔
25
  return new Promise((resolve, reject) => {
4✔
26
    let data = '';
4✔
27
    stdio.stdin.on('data', chunk => {
4✔
28
      data += chunk;
4✔
29
    });
4✔
30
    stdio.stdin.on('end', () => resolve(data));
4✔
31
    stdio.stdin.on('error', reject);
4✔
32
  });
4✔
33
}
4✔
34

8✔
35
/**
8✔
36
 * Read the given file, draw the diagram, and create the desired output file.
8✔
37
 *
8✔
38
 * @param {string} fileName
8✔
39
 * @param {import('commander').OptionValues} opts
8✔
40
 * @param {StdIO} [stdio=process]
8✔
41
 */
8✔
42
async function processFile(fileName, opts, stdio = process) {
20✔
43
  const outf = opts.out ?? path.join(
20✔
44
    path.dirname(fileName),
8✔
45
    `${path.basename(fileName, path.extname(fileName))}.${opts.output}`
8✔
46
  );
20✔
47
  const out = ((!opts.out && (fileName === '-')) || (opts.out === '-')) ?
20✔
48
    stdio.stdout :
20✔
49
    fs.createWriteStream(outf);
20✔
50

20✔
51
  out.on('error', er => {
20✔
NEW
52
    stdio.stderr.write(er.message);
×
NEW
53
    stdio.stderr.write('\n');
×
54
  });
20✔
55
  let text = null;
20✔
56
  try {
20✔
57
    text = (fileName === '-') ?
20✔
58
      await stdin(stdio) :
20✔
59
      await fs.promises.readFile(fileName, 'utf8');
20✔
60
    const {output, property} = opts;
16✔
61
    draw(text, {output, property, fileName}, out);
16✔
62
  } catch (er) {
16✔
63
    if (fileName !== '-') {
8✔
64
      try {
8✔
65
        await new Promise(resolve => {
8✔
66
          out.end(ignored => resolve());
8✔
67
        });
8✔
68
        await fs.promises.unlink(outf);
8✔
69
      } catch (ignored) {
4✔
70
        // Ignore. The file will often not be there yet.  We just want to
4✔
71
        // ensure nothing is left half-written
4✔
72
      }
4✔
73
    }
8✔
74
    if (er instanceof SyntaxError) {
8✔
75
      stdio.stderr.write(er.format([{source: fileName, text}]));
4✔
76
      stdio.stderr.write('\n');
4✔
77
    } else {
4✔
78
      stdio.stderr.write(`Processing "${fileName}": ${er}\n`);
4✔
79
    }
4✔
80
    throw er;
8✔
81
  }
8✔
82
}
20✔
83

8✔
84
/**
8✔
85
 * Main CLI entry point.
8✔
86
 *
8✔
87
 * @param {string[]} [args] Defaults to process.argv
8✔
88
 * @param {TestingOptions} [testing] stdio streams for testing
8✔
89
 * @returns {Promise<void[]>}
8✔
90
 */
8✔
91
export function main(args, testing) {
8✔
92
  const program = new Command();
32✔
93
  const stdio = {
32✔
94
    stdin: process.stdin,
32✔
95
    stdout: process.stdout,
32✔
96
    stderr: process.stderr,
32✔
97
    ...testing,
32✔
98
  };
32✔
99
  if (testing) {
32✔
100
    program.exitOverride();
28✔
101
    program.configureOutput({
28✔
102
      writeOut(s) {
28✔
103
        stdio.stdout.write(s);
4✔
104
      },
28✔
105
      writeErr(s) {
28✔
106
        stdio.stderr.write(s);
8✔
107
      },
28✔
108
    });
28✔
109
  }
28✔
110
  program
32✔
111
    .name(name)
32✔
112
    .argument('<FILE...>', 'file names to process, "-" for stdin')
32✔
113
    .addOption(
32✔
114
      new Option('-o, --output <type>', 'output type')
32✔
115
        .choices(VALID_OUTPUTS)
32✔
116
        .default('pdf')
32✔
117
    )
32✔
118
    .option('-O, --out <FILE>', 'output file name, "-" for stdout. Not valid with more than one input file.')
32✔
119
    .option(
32✔
120
      '-p, --property <key=value>',
32✔
121
      'diagram property in the form key=value.  May be specified multiple times.',
32✔
122
      (val, prev) => prev.concat([val]),
32✔
123
      []
32✔
124
    )
32✔
125
    .version(version)
32✔
126
    .parse(args);
32✔
127

32✔
128
  const opts = program.opts();
32✔
129

32✔
130
  if (opts.out && (program.args.length > 1)) {
32✔
131
    program.error('"-o, -out <FILE>" not valid with multiple inputs');
4✔
132
  }
4✔
133

20✔
134
  return Promise.all(program.args.map(f => processFile(f, opts, stdio)));
20✔
135
}
32✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc