1 | #! /usr/bin/env node
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | "use strict"
|
9 | const yargs = require("yargs");
|
10 | var path = require("path");
|
11 | var child_process = require("child_process");
|
12 |
|
13 | yargs.strict(true)
|
14 | .wrap(Math.min(150, yargs.terminalWidth()))
|
15 | .version("2.0.0")
|
16 | .usage("Bentley Scripts Utility\n\n These scripts consist of several standard npm tasks an app may want to make use of.")
|
17 | .command("test", "Run mocha tests on the current repository",
|
18 | function (yargs) {
|
19 | return yargs.options({
|
20 | "packageRoot": {
|
21 | describe: "The root of the package to locate the Mocha bin. Default is 'process.cwd()'."
|
22 | },
|
23 | "testDir": {
|
24 | describe: "The location of the test directory containing .js files. Default is './lib/test'."
|
25 | },
|
26 | "mochaOpts": {
|
27 | describe: "Adds the provided options file to mocha using --opts. See mocha docs for priority order, https://mochajs.org/api/module-lib_cli_options.html#.loadMochaOpts."
|
28 | },
|
29 | "timeout": {
|
30 | describe: "Overrides the default timeout passed to Mocha. Default is 999999."
|
31 | },
|
32 | "grep": {
|
33 | describe: "Add the grep pattern to Mocha."
|
34 | },
|
35 | "offline": {
|
36 | describe: "If set to 'mock', "
|
37 | },
|
38 | "watch": {
|
39 | describe: "Adds the --watch and --inline-diffs parameters to the Mocha command."
|
40 | },
|
41 | "debug": {
|
42 | describe: "Adds the --inspect=9229 and --debug-brk parameters to the Mocha command."
|
43 | },
|
44 | "defineWindow": {
|
45 | describe: "Adds the `--require jsdom-global/register` to the Mocha command. Use if a window is needed for compilation."
|
46 | },
|
47 | "invert": {
|
48 | describe: "Adds the --invert option to Mocha, only if '--grep' is provided too."
|
49 | }
|
50 | })
|
51 | },
|
52 | (argv) => { testCommand(argv) })
|
53 | .command("test-tsnode", "Run the ts-node version of the Mocha tests (NOTE: This may fail when running code coverage due to a behavior within Istanbul. If this occurs, you should run the script directly with Node)",
|
54 | function (yargs) {
|
55 | return yargs.options({
|
56 | "packageRoot": {
|
57 | describe: "The root of the package to locate the Mocha bin"
|
58 | },
|
59 | "testDir": {
|
60 | describe: "The location of the test directory"
|
61 | },
|
62 | "watch": {
|
63 | describe: "Adds the --watch and --inline-diffs parameters to the Mocha command"
|
64 | },
|
65 | "debug": {
|
66 | describe: "Adds the --inspect=9229 and --debug-brk parameters to the Mocha command"
|
67 | },
|
68 | "tscPaths": {
|
69 | describe: "Adds the --require tsconfig-paths/register arguments to the Mocha command"
|
70 | }
|
71 | })
|
72 | },
|
73 | (argv) => { testTsNodeCommand(argv) })
|
74 | .command("docs", "Generate TypeDoc documentation by using the provided parameters to pass to TypeDoc. Supports generating html TypeScript documentation as well as a json representation of the documentation.",
|
75 | function (yargs) {
|
76 | return yargs.options({
|
77 | "source": {
|
78 | describe: "Specify the TypeScript source directory"
|
79 | },
|
80 | "out": {
|
81 | describe: "Specify the directory of the html output"
|
82 | },
|
83 | "json": {
|
84 | describe: "Specify the directory and filename of the json output"
|
85 | },
|
86 | "baseUrl": {
|
87 | describe: "Specify a baseUrl to resolve modules"
|
88 | },
|
89 | "includes": {
|
90 | describe: "Specify a baseUrl to resolve modules"
|
91 | },
|
92 | "excludes": {
|
93 | describe: "Specify a directory, filename, or pattern to be excluded"
|
94 | },
|
95 | "excludeGlob": {
|
96 | describe: "Specify a directory, filename, or pattern to be excluded"
|
97 | },
|
98 | "tsIndexFile": {
|
99 | describe: "The barrel file containing the module documentation. This file is copied to the output folder for parsing."
|
100 | },
|
101 | "onlyJson": {
|
102 | describe: "Specify a baseUrl to resolve modules"
|
103 | }
|
104 | })
|
105 | },
|
106 | (argv) => { docsCommand(argv) })
|
107 | .command("extract", "Extract sample code from test files in a specific directory",
|
108 | function (yargs) {
|
109 | return yargs.options({
|
110 | "extractFrom": {
|
111 | describe: "The path at which the sample code files are located"
|
112 | },
|
113 | "out": {
|
114 | describe: "The path at which to output the selected code"
|
115 | },
|
116 | "fileExt": {
|
117 | describe: "The extension of the files to include"
|
118 | },
|
119 | "recursive": {
|
120 | alias: "r",
|
121 | describe: "Recursively search subdirectories from"
|
122 | }
|
123 | })
|
124 | },
|
125 | (argv) => { extractCommand(argv) })
|
126 | .command("extract-api", "Extracts the API of the Typescript library starting from an entry file with a default presets. Powered by @microsoft/api-extractor (https://api-extractor.com)",
|
127 | function (yargs) {
|
128 | return yargs.options({
|
129 | "entry": {
|
130 | describe: "The main Typescript entry point for the library which is compiled to the 'main' field in the package.json"
|
131 | },
|
132 | "ignoreMissingTags": {
|
133 | describe: "Turns off the 'ae-missing-release-tag' option which returns an error when a missing release tag is detected"
|
134 | }
|
135 | })
|
136 | },
|
137 | (argv) => { extractApiCommand(argv) })
|
138 | .command("pseudolocalize", "Pseudo-localizes an english localization JSON file.",
|
139 | function (yargs) {
|
140 | return yargs.options({
|
141 | "englishDir": {
|
142 | describe: "The path to the English localization folder. Default is `./public/locales/en`"
|
143 | },
|
144 | "out": {
|
145 | describe: "The output path to put the pseudo-localized files. Default is `./public/locales/en-pseudo`"
|
146 | }
|
147 | })
|
148 | },
|
149 | (argv) => { pseudolocalizeCommand(argv) })
|
150 | .help()
|
151 | .argv;
|
152 |
|
153 | function testCommand(options) {
|
154 | const rootOpt = options.packageRoot ? ["--packageRoot", options.packageRoot] : [];
|
155 | const testDirOpt = options.testDir ? ["--testDir", options.testDir] : [];
|
156 |
|
157 | const optionsOpt = options.mochaOpts ? ["--opts", options.mochaOpts] : [];
|
158 | const timeoutOpt = options.timeout ? ["--timeout", options.timeout] : [];
|
159 | const grepOpt = options.grep ? ["--grep", `\"${options.grep}\"`] : [];
|
160 | const offlineOpt = options.offline ? ["--offline", options.offline] : [];
|
161 | const watchOpt = options.watch ? ["--watch"] : [];
|
162 | const debugOpt = options.debug ? ["--debug"] : [];
|
163 | const windowOpt = options.defineWindow ? ["--defineWindow"] : [];
|
164 | const invertOpt = options.invert ? ["--invert"] : [];
|
165 |
|
166 | exec(["node", path.resolve(__dirname, "../scripts/test.js"),
|
167 | ...rootOpt, ...testDirOpt, ...optionsOpt, ...timeoutOpt, ...grepOpt,
|
168 | ...offlineOpt, ...watchOpt, ...debugOpt, ...windowOpt, ...invertOpt]);
|
169 | }
|
170 |
|
171 | function testTsNodeCommand(options) {
|
172 | const rootOpt = options.packageRoot ? ["--packageRoot", options.packageRoot] : [];
|
173 | const testDirOpt = options.testDir ? ["--testDir", options.testDir] : [];
|
174 | const watchOpt = options.watch ? ["--watch"] : [];
|
175 | const debugOpt = options.debug ? ["--debug"] : [];
|
176 | const tscPathsOpt = options.tscPaths ? ["--tscPaths"] : [];
|
177 | exec(["node", path.resolve(__dirname, "../scripts/test-tsnode.js"), ...rootOpt, ...testDirOpt, ...watchOpt, ...debugOpt, ...tscPathsOpt]);
|
178 | }
|
179 |
|
180 | function docsCommand(options) {
|
181 | const sourceOpt = options.source ? ["--source", options.source] : [];
|
182 | const outOpt = options.out ? ["--out", options.out] : [];
|
183 | const jsonOpt = options.json ? ["--json", options.json] : [];
|
184 | const baseUrlOpt = options.baseUrl ? ["--baseUrl", options.baseUrl] : [];
|
185 | const includesOpt = options.includes ? ["--includes", options.includes] : [];
|
186 | const excludesOpt = options.excludes ? ["--excludes", options.excludes] : [];
|
187 | const excludesGlobOpt = options.excludeGlob ? ["--excludeGlob", options.excludeGlob] : [];
|
188 | const indexFileOpt = options.tsIndexFile ? ["--tsIndexFile", options.tsIndexFile] : [];
|
189 | const onlyJsonOpt = options.onlyJson ? ["--onlyJson"] : [];
|
190 | exec(["node", path.resolve(__dirname, "../scripts/docs.js"),
|
191 | ...sourceOpt, ...outOpt, ...jsonOpt, ...baseUrlOpt, ...includesOpt,
|
192 | ...excludesOpt, ...excludesGlobOpt, ...indexFileOpt, ...onlyJsonOpt]);
|
193 | }
|
194 |
|
195 | function extractCommand(options) {
|
196 | const extractOpt = options.extractFrom ? ["--extractFrom", options.extractFrom] : [];
|
197 | const outOpt = options.out ? ["--out", options.out] : [];
|
198 | const fileExt = options.fileExt ? ["--fileExt", options.fileExt] : [];
|
199 | const recursive = options.recursive ? ["--recursive"] : [];
|
200 | exec(["node", path.resolve(__dirname, "../scripts/extract.js"), ...extractOpt, ...outOpt, ...fileExt, ...recursive]);
|
201 | }
|
202 |
|
203 | function extractApiCommand(options) {
|
204 | const entryOpt = options.entry ? ["--entry", options.entry] : [];
|
205 | const ignoreTagsOpt = options.ignoreMissingTags ? ["--ignoreMissingTags"] : [];
|
206 | exec(["node", path.resolve(__dirname, "../scripts/extract-api.js"), ...entryOpt, ...ignoreTagsOpt]);
|
207 | }
|
208 |
|
209 | function pseudolocalizeCommand(options) {
|
210 | const englishDir = options.englishDir ? ["--englishDir", options.englishDir] : [];
|
211 | const outOpt = options.out ? ["--out", options.out] : [];
|
212 | exec(["node", path.resolve(__dirname, "../scripts/pseudolocalize"), ...englishDir, ...outOpt]);
|
213 | }
|
214 |
|
215 | function exec(cmd) {
|
216 | console.log("Running command:");
|
217 | console.log(cmd.join(" "));
|
218 | return child_process.execSync(cmd.join(" "), { encoding: "utf8", stdio: 'inherit' });
|
219 | }
|