Skip to content

Commit 3661919

Browse files
feat(generate_docs): Generate docs from the current directory, and without using symlinks for node_modules
Now checks out dependent projects to a temporary directory in the project's root directory instead of moving a bunch of stuff to a temp dir
1 parent a35785f commit 3661919

File tree

2 files changed

+68
-81
lines changed

2 files changed

+68
-81
lines changed

findSemverPackage.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const { _exec } = require("./util");
2+
3+
// Finds the newest version of a package published to NPM that matches the desired semver range
4+
module.exports = function findSemverPackage(packageName, semver) {
5+
const stdout = _exec(`npm info ${packageName}@${semver} version`).stdout;
6+
const lines = stdout.split(/\n/).filter(x => x.length);
7+
if (lines.length === 0) {
8+
throw new Error(`No published package matched ${packageName}@${semver}`)
9+
} else if (lines.length === 1) {
10+
return lines[ 0 ];
11+
} else {
12+
const line = stdout.split(/\n/).pop().trim();
13+
const [, version] = /.* '(.*)'$/.exec(line) || [];
14+
if (!version) {
15+
console.log({ stdout, line });
16+
throw new Error(`Couldn't find version matching ${packageName}@${semver} in npm registry`)
17+
}
18+
return version;
19+
}
20+
}

generate_docs.js

Lines changed: 48 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,83 @@
11
#!/usr/bin/env node
2+
23
const publishYalcPackage = require('./publish_yalc_package');
4+
const findSemverPackage = require('./findSemverPackage');
35
const shelljs = require('shelljs');
46
const nodeCleanup = require('node-cleanup');
5-
const tmp = require('tmp');
67
const fs = require('fs');
78
const path = require('path');
89
const has = require('lodash').has;
910
const util = require('./util');
1011
const _exec = util._exec;
1112

1213
util.packageDir();
13-
14-
const kebob = (string) => string
15-
.split(/[@_/-]/)
16-
.filter(x => !!x)
17-
.map(x => x.toLowerCase() === 'uirouter' ? 'ui-router' : x)
18-
.join('-');
19-
20-
const PACKAGE_JSON = JSON.parse(fs.readFileSync('./package.json'));
14+
const TYPEDOC_CONFIG = getTypedocConfig();
2115
const TS_CONFIG = JSON.parse(fs.readFileSync('./tsconfig.json'));
22-
const TYPEDOC_CONFIG_FILENAME = getTypedocConfigFilename();
23-
const TYPEDOC_CONFIG = JSON.parse(fs.readFileSync(TYPEDOC_CONFIG_FILENAME));
2416
const PACKAGE_DIR = process.cwd();
25-
const DOWNSTREAM_CACHE = path.join(PACKAGE_DIR, '.downstream_cache');
26-
const DOCGEN_DIR = tmp.dirSync().name;
27-
const DOCGEN_PACKAGE_DIR = path.join(DOCGEN_DIR, kebob(PACKAGE_JSON.name));
28-
29-
function getTypedocConfigFilename() {
30-
return ['./typedoc.json', 'tsconfig.typedoc.json'].find(filename => fs.existsSync(filename));
31-
}
32-
33-
const requiredKeys = [ 'typedoc', 'typedoc.generateOptions' ];
34-
const missing = requiredKeys.find(key => !has(TYPEDOC_CONFIG, key));
35-
if (missing) {
36-
console.error(`${TYPEDOC_CONFIG_FILENAME} does not contain configuration key: "${missing}"`);
37-
process.exit(1);
17+
const PACKAGE_JSON = JSON.parse(fs.readFileSync('package.json'));
18+
19+
function getTypedocConfig() {
20+
const file = ['./typedoc.json', 'tsconfig.typedoc.json'].find((filename) =>
21+
fs.existsSync(filename)
22+
);
23+
const config = JSON.parse(fs.readFileSync(file));
24+
const requiredKeys = ['typedoc', 'typedoc.generateOptions'];
25+
const missing = requiredKeys.find((key) => !has(config, key));
26+
if (missing) {
27+
console.error(`${file} does not contain configuration key: '${missing}'`);
28+
process.exit(1);
29+
}
30+
return config;
3831
}
3932

40-
// Create directory in temp dir for the current package
41-
shelljs.mkdir('-p', DOCGEN_PACKAGE_DIR);
42-
// Register hook to cleanup temp dir
33+
// Register hook to cleanup temp directories
4334
nodeCleanup(() => {
44-
const symlinks = fs.readdirSync(DOCGEN_DIR)
45-
.filter(file => fs.lstatSync(file).isSymbolicLink());
46-
symlinks.forEach(file => fs.unlinkSync(file));
47-
shelljs.rm('-rf', DOCGEN_DIR);
35+
util.packageDir();
36+
process
37+
.exit(0)(TYPEDOC_CONFIG.typedoc.include || [])
38+
.forEach((include) => {
39+
const pkg = include.package.split('/').shift();
40+
console.log(`(not) removing temporary directory ./${pkg}...`);
41+
shelljs.rm('-rf', package);
42+
});
4843
});
4944

50-
// Fetch all included packages (i.e., core module) to .downstream_cache
51-
// Symlink each package into the temp dir
45+
// Fetch all included packages (i.e., core module)
5246
const includes = TYPEDOC_CONFIG.typedoc.include || [];
53-
includes.forEach(include => {
54-
const { branch, package, repo } = include;
55-
const flags = { noBuild: true, noPublish: true, noInstall: true, branch: branch };
47+
includes.forEach((include) => {
48+
const { branch, package: pkg, repo } = include;
49+
const flags = {
50+
noBuild: true,
51+
noPublish: true,
52+
noInstall: true,
53+
branch: branch,
54+
};
5655

5756
if (!branch) {
58-
const versionline = _exec(`yarn list --pattern ${package}`).stdout
59-
.split(/[\r\n]+/).find(line => line.includes(package));
60-
const match = /.*\@(([^@]*?)(-[a-zA-Z0-9]{8})?$)/.exec(versionline);
61-
const version = match[ 2 ];
62-
console.log({ versionline });
63-
console.log({ match });
64-
console.log({ version });
57+
const semver = ['dependencies', 'peerDependencies', 'devDependencies']
58+
.map((key) => (PACKAGE_JSON[key] || {})[pkg])
59+
.find((x) => !!x);
60+
const version = findSemverPackage(pkg, semver);
6561
flags.branch = version ? version : flags.branch;
6662
}
6763

68-
publishYalcPackage(path.join(DOCGEN_DIR, kebob(package)), repo, flags);
64+
console.log(`fetching ${repo} to temporary directory ${pkg}`);
65+
_exec(`mkdir -p ${pkg}`);
66+
publishYalcPackage(pkg, repo, flags);
6967
});
7068

71-
// symlink node_modules, package.json, tsconfig.typedoc.json into temp dir
72-
shelljs.ln('-s', path.join(PACKAGE_DIR, 'package.json'), path.join(DOCGEN_DIR, 'package.json'));
73-
shelljs.ln('-s', path.join(PACKAGE_DIR, TYPEDOC_CONFIG_FILENAME), path.join(DOCGEN_DIR, TYPEDOC_CONFIG_FILENAME));
74-
shelljs.mkdir(path.join(DOCGEN_DIR, 'node_modules'));
75-
fs.readdirSync(path.join(PACKAGE_DIR, 'node_modules')).forEach(module => {
76-
const source = path.join(PACKAGE_DIR, 'node_modules', module);
77-
const dest = path.join(DOCGEN_DIR, 'node_modules', module);
78-
shelljs.ln('-s', source, dest);
79-
});
80-
// re-hydrate current package using .git dir
81-
shelljs.cp('-r', path.join(PACKAGE_DIR, '.git'), DOCGEN_PACKAGE_DIR);
82-
process.chdir(DOCGEN_PACKAGE_DIR);
83-
shelljs.exec("git checkout .");
84-
8569
// create command line
8670
const typedocOptions = TYPEDOC_CONFIG.typedoc.generateOptions || {};
87-
typedocOptions.out = path.join(PACKAGE_DIR, typedocOptions.out || "_doc");
71+
typedocOptions.out = path.join(PACKAGE_DIR, typedocOptions.out || '_doc');
8872

8973
const cmdLineOpts = Object.keys(typedocOptions)
90-
.map(key => `--${key} ${typedocOptions[ key ]}`)
91-
.join(" ");
92-
93-
process.chdir(DOCGEN_DIR);
94-
95-
const possibleEs6LibPaths = [
96-
'node_modules/typedoc/node_modules/typescript/lib/lib.es6.d.ts',
97-
'node_modules/typescript/lib/lib.es6.d.ts',
98-
].map(libPath => path.join(PACKAGE_DIR, libPath));
99-
100-
const es6LibPath = possibleEs6LibPaths.find(libPath => fs.existsSync(libPath));
101-
102-
if (!es6LibPath) {
103-
throw new Error(`Couldn't find lib.es6.d.ts at ${possibleEs6LibPaths.join(' nor ')}`);
104-
}
74+
.map((key) => `--${key} ${typedocOptions[key]}`)
75+
.join(' ');
10576

10677
const files = []
107-
.concat(TYPEDOC_CONFIG.files || [])
108-
.concat(TS_CONFIG.files.map(x => path.join(DOCGEN_PACKAGE_DIR, x)))
109-
.concat(includes.map(x => path.join(DOCGEN_DIR, kebob(x.package), x.entry)))
110-
.map(x => `${path.normalize(x)}`)
111-
.map(x => `./${path.relative(DOCGEN_DIR, x)}`)
112-
.concat(es6LibPath);
78+
.concat(TYPEDOC_CONFIG.files || [])
79+
.concat(TS_CONFIG.files)
80+
.concat(includes.map((x) => './' + path.join(x.package, x.entry)));
11381

11482
// run typedoc command
11583
_exec(`npx typedoc ${cmdLineOpts} ${files.join(' ')}`);
116-

0 commit comments

Comments
 (0)