UNPKG

4.64 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3//> This file is the entry point for the command-line utility,
4// and is focused on handling and processing CLI arguments and
5// figuring out the right options to pass to the docs generator.
6
7//> We use `minimist` to parse command line arguments (`process.argv`)
8const path = require('path');
9const minimist = require('minimist');
10const glob = require('glob');
11const DEFAULTS = require('./defaults.js');
12const { generateLitteratePages } = require('./generate.js');
13
14//> Read + parse command line arguments into a dictionary (object)
15const ARGS = minimist(process.argv.slice(2));
16
17if (ARGS.help || ARGS.h) {
18 const helpMessage = `
19 litterate - generate beautiful literate programming-style code annotations
20 Read the full documentation at https://github.com/thesephist/litterate
21
22 Basic usage
23 ---
24 litterate --config your-litterate-config.js
25 litterate [options] [files]
26 (if no files are specified, litterate runs on src/**/*.js)
27
28 Command-line options
29 (these can be customized in a configuration file as well)
30 ---
31 --config Specify a JS or JSON file for configuration
32
33 -n, --name Name of your project, shown in the generated site.
34
35 -d, --description
36 Description text for your project, shown in the generated site.
37
38 -w, --wrap If 0, long lines of source code will never be wrapped.
39 If any other number, litterate will wrap long lines to the given
40 number of characters per line.
41
42 -b, --baseURL
43 By default, the generated website assumes the root URL of the site
44 is '/', but for GitHub Pages and other sites, you may want to set
45 a different base URL for the site. This allows you to set a different
46 site base URL.
47
48 -v, --verbose
49 Verbose output while litterate runs, useful for debugging.
50
51 -o, --output
52 Specify a different destination directory for the generated docs site.
53 By default, litterate writes to ./docs/.
54`;
55 console.log(helpMessage);
56 process.exit();
57}
58
59const userConfigPath = ARGS['config'];
60const USER_CONFIG = userConfigPath ? require(path.resolve(process.cwd(), userConfigPath)) : {};
61//> This is an easy way to merge two configuration options, with `USER_CONFIG` overriding anything
62// specified in defaults.
63const CONFIG = Object.assign(
64 {},
65 DEFAULTS,
66 USER_CONFIG
67);
68
69//> Reconcile `ARGS`, the command-line arguments, and `CONFIG` together; `ARGS` overrides
70// any `CONFIG` file option.
71for (const [optionName, optionValue] of Object.entries(ARGS)) {
72 switch (optionName) {
73 case 'config':
74 // do nothing -- ignore
75 break;
76 case '_':
77 if (optionValue.length > 0) {
78 CONFIG.files = optionValue;
79 }
80 break;
81 case 'n':
82 case 'name':
83 CONFIG.name = optionValue;
84 break;
85 case 'd':
86 case 'description':
87 CONFIG.description = optionValue;
88 break;
89 case 'w':
90 case 'wrap':
91 CONFIG.wrap = parseInt(optionValue);
92 break;
93 case 'b':
94 case 'baseURL':
95 CONFIG.baseURL = optionValue;
96 break;
97 case 'v':
98 case 'verbose':
99 CONFIG.verbose = optionValue;
100 break;
101 case 'o':
102 case 'output':
103 CONFIG.outputDirectory = optionValue;
104 break;
105 default:
106 throw new Error(`${optionName} is not a valid option, but was set to ${optionValue}`);
107 }
108}
109
110//> File names are given as glob patterns, which we should expand out.
111let sourceFiles = [];
112for (const globPattern of CONFIG.files) {
113 try {
114 //> Calling the synchronous API here is find, since this is a CLI with one event
115 // in the loop, but it may be faster to switch to the async version later.
116 const files = glob.sync(globPattern, {
117 //> This option excludes any directories from the returned match, which we want.
118 nodir: true,
119 //> Ignore node modules in matches
120 ignore: [
121 '**/node_modules/'
122 ],
123 });
124 sourceFiles = sourceFiles.concat(files);
125 } catch (err) {
126 console.log(`Error encountered while looking for matching source files: ${err}`);
127 }
128}
129
130//> Ensure that the base URL ends with a `/`
131CONFIG.baseURL = path.join(CONFIG.baseURL, '/');
132
133if (CONFIG.verbose) {
134 console.log('Using configuration: ', CONFIG);
135}
136
137generateLitteratePages(sourceFiles, CONFIG);