@appium/docutils 0.1.6 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/build/lib/build/mkdocs.d.ts +58 -0
- package/build/lib/build/mkdocs.d.ts.map +1 -0
- package/build/lib/build/mkdocs.js +80 -0
- package/build/lib/build/mkdocs.js.map +1 -0
- package/build/lib/build/typedoc.d.ts +55 -0
- package/build/lib/build/typedoc.d.ts.map +1 -0
- package/build/lib/build/typedoc.js +120 -0
- package/build/lib/build/typedoc.js.map +1 -0
- package/build/lib/build-api.d.ts +18 -0
- package/build/lib/build-api.d.ts.map +1 -0
- package/build/lib/build-api.js +75 -0
- package/build/lib/build-api.js.map +1 -0
- package/build/lib/build.d.ts +21 -0
- package/build/lib/build.d.ts.map +1 -0
- package/build/lib/build.js +71 -0
- package/build/lib/build.js.map +1 -0
- package/build/lib/builder/deploy.d.ts +89 -0
- package/build/lib/builder/deploy.d.ts.map +1 -0
- package/build/lib/builder/deploy.js +105 -0
- package/build/lib/builder/deploy.js.map +1 -0
- package/build/lib/builder/index.d.ts +5 -0
- package/build/lib/builder/index.d.ts.map +1 -0
- package/build/lib/builder/index.js +21 -0
- package/build/lib/builder/index.js.map +1 -0
- package/build/lib/builder/nav.d.ts +81 -0
- package/build/lib/builder/nav.d.ts.map +1 -0
- package/build/lib/builder/nav.js +280 -0
- package/build/lib/builder/nav.js.map +1 -0
- package/build/lib/builder/reference.d.ts +57 -0
- package/build/lib/builder/reference.d.ts.map +1 -0
- package/build/lib/builder/reference.js +129 -0
- package/build/lib/builder/reference.js.map +1 -0
- package/build/lib/builder/site.d.ts +55 -0
- package/build/lib/builder/site.d.ts.map +1 -0
- package/build/lib/builder/site.js +81 -0
- package/build/lib/builder/site.js.map +1 -0
- package/build/lib/cli/command/build.d.ts +178 -0
- package/build/lib/cli/command/build.d.ts.map +1 -0
- package/build/lib/cli/command/build.js +223 -0
- package/build/lib/cli/command/build.js.map +1 -0
- package/build/lib/cli/command/deploy.d.ts +1 -0
- package/build/lib/cli/command/deploy.d.ts.map +1 -0
- package/build/lib/cli/command/deploy.js +2 -0
- package/build/lib/cli/command/deploy.js.map +1 -0
- package/build/lib/cli/command/index.d.ts +4 -0
- package/build/lib/cli/command/index.d.ts.map +1 -0
- package/build/lib/cli/command/index.js +13 -0
- package/build/lib/cli/command/index.js.map +1 -0
- package/build/lib/cli/command/init.d.ts +143 -0
- package/build/lib/cli/command/init.d.ts.map +1 -0
- package/build/lib/cli/command/init.js +164 -0
- package/build/lib/cli/command/init.js.map +1 -0
- package/build/lib/cli/command/validate.d.ts +76 -0
- package/build/lib/cli/command/validate.d.ts.map +1 -0
- package/build/lib/cli/command/validate.js +115 -0
- package/build/lib/cli/command/validate.js.map +1 -0
- package/build/lib/cli/command-init.d.ts +143 -0
- package/build/lib/cli/command-init.d.ts.map +1 -0
- package/build/lib/cli/command-init.js +164 -0
- package/build/lib/cli/command-init.js.map +1 -0
- package/build/lib/cli/command-validate.d.ts +52 -0
- package/build/lib/cli/command-validate.d.ts.map +1 -0
- package/build/lib/cli/command-validate.js +66 -0
- package/build/lib/cli/command-validate.js.map +1 -0
- package/build/lib/cli/config.d.ts +28 -0
- package/build/lib/cli/config.d.ts.map +1 -0
- package/build/lib/cli/config.js +114 -0
- package/build/lib/cli/config.js.map +1 -0
- package/build/lib/cli/index.d.ts +13 -0
- package/build/lib/cli/index.d.ts.map +1 -0
- package/build/lib/cli/index.js +91 -0
- package/build/lib/cli/index.js.map +1 -0
- package/build/lib/cli/init.d.ts +143 -0
- package/build/lib/cli/init.d.ts.map +1 -0
- package/build/lib/cli/init.js +164 -0
- package/build/lib/cli/init.js.map +1 -0
- package/build/lib/cli/options.d.ts +1 -0
- package/build/lib/cli/options.d.ts.map +1 -0
- package/build/lib/cli/options.js +2 -0
- package/build/lib/cli/options.js.map +1 -0
- package/build/lib/cli/validate.d.ts +1 -0
- package/build/lib/cli/validate.d.ts.map +1 -0
- package/build/lib/cli/validate.js +2 -0
- package/build/lib/cli/validate.js.map +1 -0
- package/build/lib/cli.d.ts +10 -0
- package/build/lib/cli.d.ts.map +1 -0
- package/build/lib/cli.js +328 -0
- package/build/lib/cli.js.map +1 -0
- package/build/lib/constants.d.ts +125 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +133 -0
- package/build/lib/constants.js.map +1 -0
- package/build/lib/error.d.ts +3 -0
- package/build/lib/error.d.ts.map +1 -0
- package/build/lib/error.js +7 -0
- package/build/lib/error.js.map +1 -0
- package/build/lib/fs.d.ts +142 -0
- package/build/lib/fs.d.ts.map +1 -0
- package/build/lib/fs.js +237 -0
- package/build/lib/fs.js.map +1 -0
- package/build/lib/index.d.ts +5 -2
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +4 -1
- package/build/lib/index.js.map +1 -1
- package/build/lib/init-task.d.ts +49 -0
- package/build/lib/init-task.d.ts.map +1 -0
- package/build/lib/init-task.js +95 -0
- package/build/lib/init-task.js.map +1 -0
- package/build/lib/init.d.ts +202 -0
- package/build/lib/init.d.ts.map +1 -0
- package/build/lib/init.js +225 -0
- package/build/lib/init.js.map +1 -0
- package/build/lib/io.d.ts +1 -0
- package/build/lib/io.d.ts.map +1 -0
- package/build/lib/io.js +2 -0
- package/build/lib/io.js.map +1 -0
- package/build/lib/logger.d.ts +17 -2
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +187 -2
- package/build/lib/logger.js.map +1 -1
- package/build/lib/mike.d.ts +3 -0
- package/build/lib/mike.d.ts.map +1 -1
- package/build/lib/mike.js +4 -0
- package/build/lib/mike.js.map +1 -1
- package/build/lib/mkdocs.d.ts +51 -12
- package/build/lib/mkdocs.d.ts.map +1 -1
- package/build/lib/mkdocs.js +64 -32
- package/build/lib/mkdocs.js.map +1 -1
- package/build/lib/model.d.ts +80 -0
- package/build/lib/model.d.ts.map +1 -0
- package/build/lib/model.js +8 -0
- package/build/lib/model.js.map +1 -0
- package/build/lib/nav.d.ts +47 -0
- package/build/lib/nav.d.ts.map +1 -0
- package/build/lib/nav.js +132 -0
- package/build/lib/nav.js.map +1 -0
- package/build/lib/scaffold.d.ts +95 -0
- package/build/lib/scaffold.d.ts.map +1 -0
- package/build/lib/scaffold.js +103 -0
- package/build/lib/scaffold.js.map +1 -0
- package/build/lib/test.d.ts +9 -0
- package/build/lib/test.d.ts.map +1 -0
- package/build/lib/test.js +2 -0
- package/build/lib/test.js.map +1 -0
- package/build/lib/typedoc.d.ts +55 -0
- package/build/lib/typedoc.d.ts.map +1 -0
- package/build/lib/typedoc.js +122 -0
- package/build/lib/typedoc.js.map +1 -0
- package/build/lib/types.d.ts +52 -0
- package/build/lib/types.d.ts.map +1 -0
- package/build/lib/types.js +7 -0
- package/build/lib/types.js.map +1 -0
- package/build/lib/util.d.ts +42 -0
- package/build/lib/util.d.ts.map +1 -0
- package/build/lib/util.js +56 -0
- package/build/lib/util.js.map +1 -0
- package/build/lib/validate.d.ts +218 -0
- package/build/lib/validate.d.ts.map +1 -0
- package/build/lib/validate.js +501 -0
- package/build/lib/validate.js.map +1 -0
- package/build/lib/validation/base-validator.d.ts +218 -0
- package/build/lib/validation/base-validator.d.ts.map +1 -0
- package/build/lib/validation/base-validator.js +453 -0
- package/build/lib/validation/base-validator.js.map +1 -0
- package/build/lib/validation/mkdocs-validator.d.ts +5 -0
- package/build/lib/validation/mkdocs-validator.d.ts.map +1 -0
- package/build/lib/validation/mkdocs-validator.js +54 -0
- package/build/lib/validation/mkdocs-validator.js.map +1 -0
- package/build/lib/validation/python-validator.d.ts +1 -0
- package/build/lib/validation/python-validator.d.ts.map +1 -0
- package/build/lib/validation/python-validator.js +2 -0
- package/build/lib/validation/python-validator.js.map +1 -0
- package/build/lib/validation/python.d.ts +1 -0
- package/build/lib/validation/python.d.ts.map +1 -0
- package/build/lib/validation/python.js +2 -0
- package/build/lib/validation/python.js.map +1 -0
- package/build/lib/validation/validate.d.ts +221 -0
- package/build/lib/validation/validate.d.ts.map +1 -0
- package/build/lib/validation/validate.js +508 -0
- package/build/lib/validation/validate.js.map +1 -0
- package/build/lib/validation/validator.d.ts +220 -0
- package/build/lib/validation/validator.d.ts.map +1 -0
- package/build/lib/validation/validator.js +470 -0
- package/build/lib/validation/validator.js.map +1 -0
- package/lib/builder/deploy.ts +223 -0
- package/lib/builder/index.ts +4 -0
- package/lib/builder/nav.ts +399 -0
- package/lib/builder/reference.ts +191 -0
- package/lib/builder/site.ts +143 -0
- package/lib/cli/command/build.ts +229 -0
- package/lib/cli/command/index.ts +3 -0
- package/lib/cli/command/init.ts +166 -0
- package/lib/cli/command/validate.ts +122 -0
- package/lib/cli/config.ts +89 -0
- package/lib/cli/index.ts +88 -0
- package/lib/constants.ts +150 -0
- package/lib/error.ts +1 -0
- package/lib/fs.ts +274 -0
- package/lib/index.ts +5 -0
- package/lib/init.ts +319 -0
- package/lib/logger.ts +198 -0
- package/lib/mike.js +4 -0
- package/lib/model.ts +92 -0
- package/lib/scaffold.ts +225 -0
- package/lib/util.ts +76 -0
- package/lib/validate.ts +728 -0
- package/package.json +38 -6
- package/requirements.txt +4 -0
- package/tsconfig.json +2 -1
- package/build/tsconfig.tsbuildinfo +0 -1
- package/lib/index.js +0 -2
- package/lib/logger.js +0 -3
- package/lib/mkdocs.js +0 -43
package/lib/fs.ts
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functions which touch the filesystem
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import findUp from 'find-up';
|
|
7
|
+
import YAML from 'yaml';
|
|
8
|
+
import readPkg, {NormalizedPackageJson, PackageJson} from 'read-pkg';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import {JsonValue} from 'type-fest';
|
|
11
|
+
import {fs} from '@appium/support';
|
|
12
|
+
import * as JSON5 from 'json5';
|
|
13
|
+
import _ from 'lodash';
|
|
14
|
+
import _pkgDir from 'pkg-dir';
|
|
15
|
+
import logger from './logger';
|
|
16
|
+
import {Application, TypeDocReader} from 'typedoc';
|
|
17
|
+
import {
|
|
18
|
+
NAME_TYPEDOC_JSON,
|
|
19
|
+
NAME_MKDOCS_YML,
|
|
20
|
+
NAME_PACKAGE_JSON,
|
|
21
|
+
NAME_MKDOCS,
|
|
22
|
+
NAME_NPM,
|
|
23
|
+
NAME_PYTHON,
|
|
24
|
+
NAME_MIKE,
|
|
25
|
+
} from './constants';
|
|
26
|
+
import {DocutilsError} from './error';
|
|
27
|
+
import {MkDocsYml} from './model';
|
|
28
|
+
|
|
29
|
+
const log = logger.withTag('fs');
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Finds path to closest `package.json`
|
|
33
|
+
*
|
|
34
|
+
* Caches result
|
|
35
|
+
*/
|
|
36
|
+
export const findPkgDir = _.memoize(_pkgDir);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Stringifies a thing into a YAML
|
|
40
|
+
* @param value Something to yamlify
|
|
41
|
+
* @returns Some nice YAML 4 u
|
|
42
|
+
*/
|
|
43
|
+
export const stringifyYaml: (value: JsonValue) => string = _.partialRight(
|
|
44
|
+
YAML.stringify,
|
|
45
|
+
{indent: 2},
|
|
46
|
+
undefined
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Stringifies something into JSON5. I think the only difference between this and `JSON.stringify`
|
|
51
|
+
* is that if an object has a `toJSON5()` method, it will be used.
|
|
52
|
+
* @param value Something to stringify
|
|
53
|
+
* @returns JSON5 string
|
|
54
|
+
*/
|
|
55
|
+
export const stringifyJson5: (value: JsonValue) => string = _.partialRight(JSON5.stringify, {
|
|
56
|
+
indent: 2,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Pretty-stringifies a JSON value
|
|
61
|
+
* @param value Something to stringify
|
|
62
|
+
* @returns JSON string
|
|
63
|
+
*/
|
|
64
|
+
export const stringifyJson: (value: JsonValue) => string = _.partialRight(
|
|
65
|
+
JSON.stringify,
|
|
66
|
+
2,
|
|
67
|
+
undefined
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Reads a YAML file, parses it and caches the result
|
|
72
|
+
*/
|
|
73
|
+
export const readYaml = _.memoize(async (filepath: string) =>
|
|
74
|
+
YAML.parse(await fs.readFile(filepath, 'utf8'), {
|
|
75
|
+
prettyErrors: false,
|
|
76
|
+
logLevel: 'silent',
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Finds a file from `cwd`. Searches up to the package root (dir containing `package.json`).
|
|
82
|
+
*
|
|
83
|
+
* @param filename Filename to look for
|
|
84
|
+
* @param cwd Dir it should be in
|
|
85
|
+
* @returns
|
|
86
|
+
*/
|
|
87
|
+
export async function findInPkgDir(
|
|
88
|
+
filename: string,
|
|
89
|
+
cwd = process.cwd()
|
|
90
|
+
): Promise<string | undefined> {
|
|
91
|
+
const pkgDir = await findPkgDir(cwd);
|
|
92
|
+
if (!pkgDir) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
return path.join(pkgDir, filename);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Finds a `typedoc.json`, expected to be a sibling of `package.json`
|
|
100
|
+
*
|
|
101
|
+
* Caches the result.
|
|
102
|
+
* @param cwd - Current working directory
|
|
103
|
+
* @returns Path to `typedoc.json`
|
|
104
|
+
*/
|
|
105
|
+
export const findTypeDocJsonPath = _.memoize(async (cwd = process.cwd()) => {
|
|
106
|
+
const filepath = await findUp(NAME_TYPEDOC_JSON, {cwd, type: 'file'});
|
|
107
|
+
log.debug('Found `typedoc.json` at %s', filepath);
|
|
108
|
+
return filepath;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Finds an `mkdocs.yml`, expected to be a sibling of `package.json`
|
|
113
|
+
*
|
|
114
|
+
* Caches the result.
|
|
115
|
+
* @param cwd - Current working directory
|
|
116
|
+
* @returns Path to `mkdocs.yml`
|
|
117
|
+
*/
|
|
118
|
+
export const findMkDocsYml = _.memoize(_.partial(findInPkgDir, NAME_MKDOCS_YML));
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Given a directory path, finds closest `package.json` and reads it.
|
|
122
|
+
* @param cwd - Current working directory
|
|
123
|
+
* @param normalize - Whether or not to normalize the result
|
|
124
|
+
* @returns A {@linkcode PackageJson} object if `normalize` is `false`, otherwise a {@linkcode NormalizedPackageJson} object
|
|
125
|
+
*/
|
|
126
|
+
async function _readPkgJson(
|
|
127
|
+
cwd: string,
|
|
128
|
+
normalize: true
|
|
129
|
+
): Promise<{pkgPath: string; pkg: NormalizedPackageJson}>;
|
|
130
|
+
async function _readPkgJson(cwd: string): Promise<{pkgPath: string; pkg: PackageJson}>;
|
|
131
|
+
async function _readPkgJson(
|
|
132
|
+
cwd: string,
|
|
133
|
+
normalize?: boolean
|
|
134
|
+
): Promise<{pkgPath: string; pkg: PackageJson | NormalizedPackageJson}> {
|
|
135
|
+
const pkgDir = await findPkgDir(cwd);
|
|
136
|
+
if (!pkgDir) {
|
|
137
|
+
throw new DocutilsError(
|
|
138
|
+
`Could not find a ${NAME_PACKAGE_JSON} near ${cwd}; please create it before using this utility`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
const pkgPath = path.join(pkgDir, NAME_PACKAGE_JSON);
|
|
142
|
+
log.debug('Found `package.json` at %s', pkgPath);
|
|
143
|
+
if (normalize) {
|
|
144
|
+
const pkg = await readPkg({cwd: pkgDir, normalize});
|
|
145
|
+
return {pkg, pkgPath};
|
|
146
|
+
} else {
|
|
147
|
+
const pkg = await readPkg({cwd: pkgDir});
|
|
148
|
+
return {pkg, pkgPath};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Given a directory to start from, reads a `package.json` file and returns its path and contents
|
|
154
|
+
*/
|
|
155
|
+
export const readPackageJson = _.memoize(_readPkgJson);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Reads a `typedoc.json` file and returns its parsed contents.
|
|
159
|
+
*
|
|
160
|
+
* TypeDoc expands the "extends" field, which is why we use its facilities. It, unfortunately, is a
|
|
161
|
+
* blocking operation.
|
|
162
|
+
*/
|
|
163
|
+
export const readTypedocJson = _.memoize((typedocJsonPath: string) => {
|
|
164
|
+
const app = new Application();
|
|
165
|
+
app.options.setValue('plugin', 'none');
|
|
166
|
+
app.options.setValue('logger', 'none');
|
|
167
|
+
app.options.addReader(new TypeDocReader());
|
|
168
|
+
app.bootstrap({options: path.dirname(typedocJsonPath)});
|
|
169
|
+
return app.options.getRawValues();
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Reads a JSON5 file and parses it
|
|
174
|
+
*/
|
|
175
|
+
export const readJson5 = _.memoize(
|
|
176
|
+
async <T extends JsonValue>(filepath: string): Promise<T> =>
|
|
177
|
+
JSON5.parse(await fs.readFile(filepath, 'utf8'))
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Reads a JSON file and parses it
|
|
182
|
+
*/
|
|
183
|
+
export const readJson = _.memoize(
|
|
184
|
+
async <T extends JsonValue>(filepath: string): Promise<T> =>
|
|
185
|
+
JSON.parse(await fs.readFile(filepath, 'utf8'))
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Writes a file, but will not overwrite an existing file unless `overwrite` is true
|
|
190
|
+
*
|
|
191
|
+
* Will stringify JSON objects
|
|
192
|
+
* @param filepath - Path to file
|
|
193
|
+
* @param content - File contents
|
|
194
|
+
* @param overwrite - If `true`, overwrite existing files
|
|
195
|
+
*/
|
|
196
|
+
export function safeWriteFile(filepath: string, content: JsonValue, overwrite = false) {
|
|
197
|
+
const data: string = _.isString(content) ? content : JSON.stringify(content, undefined, 2);
|
|
198
|
+
return fs.writeFile(filepath, data, {
|
|
199
|
+
encoding: 'utf8',
|
|
200
|
+
flag: overwrite ? 'w' : 'wx',
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* `which` with memoization
|
|
206
|
+
*/
|
|
207
|
+
export const cachedWhich = _.memoize(fs.which);
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Finds `mkdocs` executable
|
|
211
|
+
*/
|
|
212
|
+
export const whichMkDocs = _.partial(cachedWhich, NAME_MKDOCS);
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Finds `npm` executable
|
|
216
|
+
*/
|
|
217
|
+
export const whichNpm = _.partial(cachedWhich, NAME_NPM);
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Finds `python` executable
|
|
221
|
+
*/
|
|
222
|
+
export const whichPython = _.partial(cachedWhich, NAME_PYTHON);
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Finds `mike` executable
|
|
226
|
+
*/
|
|
227
|
+
export const whichMike = _.partial(cachedWhich, NAME_MIKE);
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Reads an `mkdocs.yml` file, merges inherited configs, and returns the result. The result is cached.
|
|
231
|
+
*
|
|
232
|
+
* **IMPORTANT**: The paths of `site_dir` and `docs_dir` are resolved to absolute paths, since they
|
|
233
|
+
* are expressed as relative paths, and each inherited config file can live in different paths.
|
|
234
|
+
* @param filepath Patgh to an `mkdocs.yml` file
|
|
235
|
+
* @returns Parsed `mkdocs.yml` file
|
|
236
|
+
*/
|
|
237
|
+
export const readMkDocsYml = _.memoize(
|
|
238
|
+
async (filepath: string, cwd = process.cwd()): Promise<MkDocsYml> => {
|
|
239
|
+
let mkDocsYml = <MkDocsYml>await readYaml(filepath);
|
|
240
|
+
if (mkDocsYml.site_dir) {
|
|
241
|
+
mkDocsYml.site_dir = path.resolve(cwd, path.dirname(filepath), mkDocsYml.site_dir);
|
|
242
|
+
}
|
|
243
|
+
if (mkDocsYml.INHERIT) {
|
|
244
|
+
let inheritPath: string | undefined = path.resolve(path.dirname(filepath), mkDocsYml.INHERIT);
|
|
245
|
+
while (inheritPath) {
|
|
246
|
+
const inheritYml = <MkDocsYml>await readYaml(inheritPath);
|
|
247
|
+
if (inheritYml.site_dir) {
|
|
248
|
+
inheritYml.site_dir = path.resolve(path.dirname(inheritPath), inheritYml.site_dir);
|
|
249
|
+
log.debug('Resolved site_dir to %s', inheritYml.site_dir);
|
|
250
|
+
}
|
|
251
|
+
if (inheritYml.docs_dir) {
|
|
252
|
+
inheritYml.docs_dir = path.resolve(path.dirname(inheritPath), inheritYml.docs_dir);
|
|
253
|
+
log.debug('Resolved docs_dir to %s', inheritYml.docs_dir);
|
|
254
|
+
}
|
|
255
|
+
mkDocsYml = _.defaultsDeep(mkDocsYml, inheritYml);
|
|
256
|
+
inheritPath = inheritYml.INHERIT
|
|
257
|
+
? path.resolve(path.dirname(inheritPath), inheritYml.INHERIT)
|
|
258
|
+
: undefined;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return mkDocsYml;
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Given an abs path to a directory, return a list of all abs paths of all directories in it
|
|
267
|
+
*/
|
|
268
|
+
export const findDirsIn = _.memoize(async (dirpath: string): Promise<string[]> => {
|
|
269
|
+
if (!path.isAbsolute(dirpath)) {
|
|
270
|
+
throw new DocutilsError(`Expected absolute path, got '${dirpath}'`);
|
|
271
|
+
}
|
|
272
|
+
const dirEnts = await fs.readdir(dirpath, {withFileTypes: true});
|
|
273
|
+
return dirEnts.filter((ent) => ent.isDirectory()).map((ent) => path.join(dirpath, ent.name));
|
|
274
|
+
});
|
package/lib/index.ts
ADDED
package/lib/init.ts
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffolding functions for CLI `init` command
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as JSON5 from 'json5';
|
|
8
|
+
import {
|
|
9
|
+
NAME_MKDOCS_YML,
|
|
10
|
+
NAME_TSCONFIG_JSON,
|
|
11
|
+
NAME_PYTHON,
|
|
12
|
+
REQUIREMENTS_TXT_PATH,
|
|
13
|
+
NAME_TYPEDOC_JSON,
|
|
14
|
+
} from './constants';
|
|
15
|
+
import YAML from 'yaml';
|
|
16
|
+
import {exec} from 'teen_process';
|
|
17
|
+
import {Simplify} from 'type-fest';
|
|
18
|
+
import {DocutilsError} from './error';
|
|
19
|
+
import {createScaffoldTask, ScaffoldTaskOptions} from './scaffold';
|
|
20
|
+
import logger from './logger';
|
|
21
|
+
import {MkDocsYml, TsConfigJson, TypeDocJson} from './model';
|
|
22
|
+
import _ from 'lodash';
|
|
23
|
+
import {stringifyJson5, stringifyYaml} from './fs';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Data for the base `mkdocs.yml` file
|
|
27
|
+
*/
|
|
28
|
+
const BASE_MKDOCS_YML: Readonly<MkDocsYml> = Object.freeze({
|
|
29
|
+
INHERIT: './node_modules/@appium/docutils/base-mkdocs.yml',
|
|
30
|
+
docs_dir: 'docs',
|
|
31
|
+
site_dir: 'site',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Data for the base `typedoc.json` file
|
|
36
|
+
*/
|
|
37
|
+
const BASE_TYPEDOC_JSON: Readonly<TypeDocJson> = Object.freeze({
|
|
38
|
+
$schema: 'https://typedoc.org/schema.json',
|
|
39
|
+
cleanOutputDir: true,
|
|
40
|
+
entryPointStrategy: 'packages',
|
|
41
|
+
theme: 'appium',
|
|
42
|
+
readme: 'none',
|
|
43
|
+
entryPoints: ['.'],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Data for the base `tsconfig.json` file
|
|
48
|
+
*/
|
|
49
|
+
const BASE_TSCONFIG_JSON: Readonly<TsConfigJson> = Object.freeze({
|
|
50
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
51
|
+
extends: '@appium/tsconfig/tsconfig.json',
|
|
52
|
+
compilerOptions: {
|
|
53
|
+
outDir: 'build',
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const log = logger.withTag('init');
|
|
58
|
+
const dryRunLog = log.withTag('dry-run');
|
|
59
|
+
|
|
60
|
+
const DEFAULT_INCLUDE = ['lib', 'test', 'index.js'];
|
|
61
|
+
/**
|
|
62
|
+
* Function which scaffolds a `tsconfig.json` file
|
|
63
|
+
*/
|
|
64
|
+
export const initTsConfigJson = createScaffoldTask<InitTsConfigOptions, TsConfigJson>(
|
|
65
|
+
NAME_TSCONFIG_JSON,
|
|
66
|
+
BASE_TSCONFIG_JSON,
|
|
67
|
+
'TypeScript configuration',
|
|
68
|
+
{
|
|
69
|
+
/**
|
|
70
|
+
* Merges the contents of the `include` property with any passed on the CLI. If neither exists,
|
|
71
|
+
* uses the default set of includes.
|
|
72
|
+
* @param content Parsed and/or scaffolded `tsconfig.json`
|
|
73
|
+
* @param opts Options specific to this task
|
|
74
|
+
* @returns `tsconfig.json` content with potentially-modified `include` prop
|
|
75
|
+
*/
|
|
76
|
+
transform: (content, {include}) => {
|
|
77
|
+
include = [...(content.include ?? include ?? [])];
|
|
78
|
+
if (_.isEmpty(include)) {
|
|
79
|
+
include = [...DEFAULT_INCLUDE];
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
...content,
|
|
83
|
+
include: _.uniq(include),
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
deserialize: JSON5.parse,
|
|
87
|
+
serialize: stringifyJson5,
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Function which scaffolds a `typedoc.json` file
|
|
93
|
+
*/
|
|
94
|
+
export const initTypeDocJson = createScaffoldTask<InitTypeDocOptions, TypeDocJson>(
|
|
95
|
+
NAME_TYPEDOC_JSON,
|
|
96
|
+
BASE_TYPEDOC_JSON,
|
|
97
|
+
'TypeDoc configuration'
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Function which scaffolds an `mkdocs.yml` file
|
|
102
|
+
*/
|
|
103
|
+
export const initMkDocs = createScaffoldTask<InitMkDocsOptions, MkDocsYml>(
|
|
104
|
+
NAME_MKDOCS_YML,
|
|
105
|
+
BASE_MKDOCS_YML,
|
|
106
|
+
'MkDocs configuration',
|
|
107
|
+
{
|
|
108
|
+
deserialize: YAML.parse,
|
|
109
|
+
serialize: stringifyYaml,
|
|
110
|
+
transform: (content, opts, pkg) => {
|
|
111
|
+
let siteName = opts.siteName ?? content.site_name;
|
|
112
|
+
if (!siteName) {
|
|
113
|
+
siteName = pkg.name ?? '(no name)';
|
|
114
|
+
if (siteName) {
|
|
115
|
+
log.info('Using site name from package.json: %s', siteName);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
let repoUrl: string | undefined = opts.repoUrl ?? content.repo_url;
|
|
119
|
+
if (!repoUrl) {
|
|
120
|
+
repoUrl = pkg.repository?.url;
|
|
121
|
+
if (repoUrl) {
|
|
122
|
+
log.info('Using repo URL from package.json: %s', repoUrl);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let repoName = opts.repoName ?? content.repo_name;
|
|
126
|
+
if (repoUrl && !repoName) {
|
|
127
|
+
let {pathname} = new URL(repoUrl);
|
|
128
|
+
pathname = pathname.slice(1);
|
|
129
|
+
let [owner, repo] = pathname.split('/');
|
|
130
|
+
repo = repo.replace(/\.git$/, '');
|
|
131
|
+
repoName = [owner, repo].join('/');
|
|
132
|
+
if (repoName) {
|
|
133
|
+
log.info('Using repo name from package.json: %s', repoName);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let siteDescription = opts.siteDescription ?? content.site_description;
|
|
137
|
+
if (!siteDescription) {
|
|
138
|
+
siteDescription = pkg.description;
|
|
139
|
+
if (siteDescription) {
|
|
140
|
+
log.info('Using site description URL from package.json: %s', siteDescription);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
...content,
|
|
145
|
+
site_name: siteName,
|
|
146
|
+
repo_url: repoUrl,
|
|
147
|
+
repo_name: repoName,
|
|
148
|
+
site_description: siteDescription,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Installs Python dependencies
|
|
156
|
+
* @param opts Options
|
|
157
|
+
*/
|
|
158
|
+
export async function initPython({
|
|
159
|
+
pythonPath = NAME_PYTHON,
|
|
160
|
+
dryRun = false,
|
|
161
|
+
}: InitPythonOptions = {}): Promise<void> {
|
|
162
|
+
const args = ['-m', 'pip', 'install', '-r', REQUIREMENTS_TXT_PATH];
|
|
163
|
+
if (dryRun) {
|
|
164
|
+
dryRunLog.info('Would execute command: %s %s', pythonPath, args.join(' '));
|
|
165
|
+
} else {
|
|
166
|
+
log.debug('Executing command: %s %s', pythonPath, args.join(' '));
|
|
167
|
+
log.info('Installing Python dependencies...');
|
|
168
|
+
try {
|
|
169
|
+
const result = await exec(pythonPath, args, {shell: true});
|
|
170
|
+
const {code, stdout} = result;
|
|
171
|
+
if (code !== 0) {
|
|
172
|
+
throw new DocutilsError(`Could not install Python dependencies. Reason: ${stdout}`);
|
|
173
|
+
}
|
|
174
|
+
} catch (err) {
|
|
175
|
+
throw new DocutilsError(
|
|
176
|
+
`Could not install Python dependencies. Reason: ${(err as Error).message}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
log.success('Installed Python dependencies (or dependencies already installed)');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Options for {@linkcode initMkDocs}
|
|
185
|
+
*/
|
|
186
|
+
export interface InitMkDocsOptions extends ScaffoldTaskOptions {
|
|
187
|
+
copyright?: string;
|
|
188
|
+
repoName?: string;
|
|
189
|
+
repoUrl?: string;
|
|
190
|
+
siteDescription?: string;
|
|
191
|
+
siteName?: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Main handler for `init` command.
|
|
196
|
+
*
|
|
197
|
+
* This runs tasks in serial; it _could_ run in parallel, but it has deleterious effects upon
|
|
198
|
+
* console output which would need mitigation.
|
|
199
|
+
*/
|
|
200
|
+
export async function init({
|
|
201
|
+
typescript,
|
|
202
|
+
typedoc,
|
|
203
|
+
python,
|
|
204
|
+
tsconfigJson: tsconfigJsonPath,
|
|
205
|
+
packageJson: packageJsonPath,
|
|
206
|
+
overwrite,
|
|
207
|
+
include,
|
|
208
|
+
mkdocs,
|
|
209
|
+
mkdocsYml: mkdocsYmlPath,
|
|
210
|
+
siteName,
|
|
211
|
+
repoName,
|
|
212
|
+
repoUrl,
|
|
213
|
+
copyright,
|
|
214
|
+
dryRun,
|
|
215
|
+
cwd,
|
|
216
|
+
pythonPath,
|
|
217
|
+
typedocJson: typeDocJsonPath,
|
|
218
|
+
}: InitOptions = {}): Promise<void> {
|
|
219
|
+
if (!typescript && typedoc) {
|
|
220
|
+
log.warn(
|
|
221
|
+
'Initialization of tsconfig.json disabled. TypeDoc requires a tsconfig.json; please ensure it exists'
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (typescript) {
|
|
226
|
+
await initTsConfigJson({
|
|
227
|
+
dest: tsconfigJsonPath,
|
|
228
|
+
packageJson: packageJsonPath,
|
|
229
|
+
overwrite,
|
|
230
|
+
include,
|
|
231
|
+
dryRun,
|
|
232
|
+
cwd,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (typedoc) {
|
|
237
|
+
await initTypeDocJson({
|
|
238
|
+
dest: typeDocJsonPath,
|
|
239
|
+
packageJson: packageJsonPath,
|
|
240
|
+
overwrite,
|
|
241
|
+
dryRun,
|
|
242
|
+
cwd,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (python) {
|
|
247
|
+
await initPython({pythonPath, dryRun});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (mkdocs) {
|
|
251
|
+
await initMkDocs({
|
|
252
|
+
dest: mkdocsYmlPath,
|
|
253
|
+
cwd,
|
|
254
|
+
siteName,
|
|
255
|
+
repoUrl,
|
|
256
|
+
repoName,
|
|
257
|
+
copyright,
|
|
258
|
+
packageJson: packageJsonPath,
|
|
259
|
+
overwrite,
|
|
260
|
+
dryRun,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface InitTypeDocOptions extends ScaffoldTaskOptions {}
|
|
266
|
+
export interface InitTsConfigOptions extends ScaffoldTaskOptions {
|
|
267
|
+
/**
|
|
268
|
+
* List of source files (globs supported); typically `src` or `lib`
|
|
269
|
+
*/
|
|
270
|
+
include?: string[];
|
|
271
|
+
}
|
|
272
|
+
export interface InitPythonOptions extends ScaffoldTaskOptions {
|
|
273
|
+
/**
|
|
274
|
+
* Path to `python` (v3.x) executable
|
|
275
|
+
*/
|
|
276
|
+
pythonPath?: string;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Options for `init` command handler
|
|
281
|
+
*
|
|
282
|
+
* The props of the various "path" options are rewritten as `dest` for the scaffold tasks functions.
|
|
283
|
+
*/
|
|
284
|
+
export type InitOptions = Simplify<
|
|
285
|
+
Omit<InitPythonOptions & InitTsConfigOptions & InitTypeDocOptions & InitMkDocsOptions, 'dest'> & {
|
|
286
|
+
/**
|
|
287
|
+
* If `true` will initialize a `tsconfig.json` file
|
|
288
|
+
*/
|
|
289
|
+
typescript?: boolean;
|
|
290
|
+
/**
|
|
291
|
+
* If `true` will initialize a `typedoc.json` file
|
|
292
|
+
*/
|
|
293
|
+
typedoc?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* If `true` will install Python deps
|
|
296
|
+
*/
|
|
297
|
+
python?: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* If `true` will initialize a `mkdocs.yml` file
|
|
300
|
+
*/
|
|
301
|
+
mkdocs?: boolean;
|
|
302
|
+
/**
|
|
303
|
+
* Path to new or existing `typedoc.json` file
|
|
304
|
+
*/
|
|
305
|
+
typedocJson?: string;
|
|
306
|
+
/**
|
|
307
|
+
* Path to new or existing `tsconfig.json` file
|
|
308
|
+
*/
|
|
309
|
+
tsconfigJson?: string;
|
|
310
|
+
/**
|
|
311
|
+
* Path to existing `package.json` file
|
|
312
|
+
*/
|
|
313
|
+
packageJson?: string;
|
|
314
|
+
/**
|
|
315
|
+
* Path to new or existing `mkdocs.yml` file
|
|
316
|
+
*/
|
|
317
|
+
mkdocsYml?: string;
|
|
318
|
+
}
|
|
319
|
+
>;
|