chore(docutils): remove cruft from `mkdocs` module and refactor
MODIFY
packages/docutils/lib/mkdocs.ts
packages/docutils/lib/mkdocs.ts
-import {exec, SubProcess} from 'teen_process';
+/**
+ * Functions for running `mkdocs`
+ *
+ * @module
+ */
+
+import {exec, SubProcess, TeenProcessExecOptions} from 'teen_process';
import {NAME_MKDOCS} from './constants';
import {guessMkDocsYmlPath} from './fs';
import logger from './logger';
-import {stopwatch} from './util';
+import {stopwatch, TupleToObject} from './util';
const log = logger.withTag('mkdocs');
/**
- * Run 'mkdocs build' on a project
- *
- * @param configPath - path to mkdocs config yml
- * @param outputDir - directory mkdocs should build into
- * @param theme - theme name
+ * Runs `mkdocs serve`
+ * @param mkdocsPath Path to `mkdocs` executable
+ * @param args Extra args to `mkdocs build`
+ * @param opts Extra options for `teen_process.Subprocess.start`
*/
-export async function mkdocsBuild(configPath: string, outputDir: string, theme = NAME_MKDOCS) {
- await exec(NAME_MKDOCS, ['build', '-f', configPath, '-t', theme, '-d', outputDir]);
+function doServe(
+ mkdocsPath: string = NAME_MKDOCS,
+ args: string[] = [],
+ {startDetector, detach, timeoutMs}: TeenProcessSubprocessStartOpts = {}
+) {
+ const proc = new SubProcess(mkdocsPath, ['serve', ...args]);
+ return proc.start(startDetector, detach, timeoutMs);
}
/**
- * Run 'mkdocs serve' on a project
- *
- * @param configPath - path to mkdocs config yml
+ * Runs `mkdocs build`
+ * @param mkdocsPath Path to `mkdocs` executable
+ * @param args Extra args to `mkdocs build`
+ * @param opts Extra options to `teen_process.exec`
*/
-export async function mkdocsServe(configPath: string) {
- const proc = new SubProcess(NAME_MKDOCS, ['serve', '-f', configPath]);
- await proc.start();
+function doBuild(
+ mkdocsPath: string = NAME_MKDOCS,
+ args: string[] = [],
+ opts: TeenProcessExecOptions = {}
+) {
+ return exec(mkdocsPath, ['build', ...args], opts);
}
+/**
+ * Runs `mkdocs build` or `mkdocs serve`
+ * @param opts
+ */
export async function buildMkDocs({
mkdocsYml: mkdocsYmlPath,
siteDir,
theme = NAME_MKDOCS,
cwd = process.cwd(),
packageJson: packageJsonPath,
+ serve = false,
+ serveOpts,
+ execOpts,
}: BuildMkDocsOpts = {}) {
const stop = stopwatch('build-mkdocs');
mkdocsYmlPath = mkdocsYmlPath ?? (await guessMkDocsYmlPath(cwd, packageJsonPath));
- const mkdocsArgs = ['build', '-f', mkdocsYmlPath, '-t', theme];
+ const mkdocsArgs = ['-f', mkdocsYmlPath, '-t', theme];
if (siteDir) {
mkdocsArgs.push('-d', siteDir);
}
+ if (serve) {
+ log.debug('Launching %s serve with args: %O', NAME_MKDOCS, mkdocsArgs);
+ // unsure about how SIGHUP is handled here
+ await doServe(NAME_MKDOCS, mkdocsArgs, serveOpts);
+ } else {
log.debug('Launching %s build with args: %O', NAME_MKDOCS, mkdocsArgs);
- await exec(NAME_MKDOCS, mkdocsArgs);
+ await doBuild(NAME_MKDOCS, mkdocsArgs, execOpts);
log.success('Built site with %s (%dms)', NAME_MKDOCS, stop());
}
+}
+/**
+ * Options for {@linkcode buildMkDocs}.
+ */
export interface BuildMkDocsOpts {
+ /**
+ * Path to `mkdocs.yml`
+ */
mkdocsYml?: string;
+
+ /**
+ * Path to output directory
+ */
siteDir?: string;
+
+ /**
+ * MkDocs theme to use
+ * @defaultValue 'mkdocs'
+ */
theme?: string;
+
+ /**
+ * Current working directory
+ * @defaultValue `process.cwd()`
+ */
cwd?: string;
+
+ /**
+ * Path to `package.json`
+ *
+ * Used to find `mkdocs.yml` if unspecified.
+ */
packageJson?: string;
+
+ /**
+ * If `true`, run `mkdocs serve` instead of `mkdocs build`
+ */
+ serve?: boolean;
+
+ /**
+ * Extra options for {@linkcode teen_process.exec}
+ */
+ execOpts?: TeenProcessExecOptions;
+
+ /**
+ * Extra options for {@linkcode teen_process.Subprocess.start}
+ */
+ serveOpts?: TeenProcessSubprocessStartOpts;
}
+
+/**
+ * Conversion of the parameters of {@linkcode Subprocess.start} to an object.
+ */
+export type TeenProcessSubprocessStartOpts = Partial<
+ TupleToObject<Parameters<SubProcess['start']>, ['startDetector', 'detach', 'timeoutMs']>
+>;

MODIFY
packages/docutils/lib/util.ts
packages/docutils/lib/util.ts
@@ -30,3 +30,8 @@ export function stopwatch(id: string) {
};
}
stopwatch.cache = new Map<string, number>();
+
+export type TupleToObject<
+ T extends readonly any[],
+ M extends Record<Exclude<keyof T, keyof any[]>, PropertyKey>
+> = {[K in Exclude<keyof T, keyof any[]> as M[K]]: T[K]};

chore(docutils): remove cruft from `mkdocs` module and refactor