Skip to content

Commit bd52998

Browse files
feat(docgen): Create a docker image uirouter:docgen which generates docs so projects do not need a direct dependency on typedoc
1 parent e3c5247 commit bd52998

File tree

7 files changed

+134
-0
lines changed

7 files changed

+134
-0
lines changed

docgen/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM node:12
2+
3+
RUN apt-get update && apt-get install -y rsync jq vim
4+
5+
WORKDIR /home/node/work
6+
COPY package.json /home/node/work
7+
RUN npm install
8+
RUN sed -i'' -e 's/Globals/{{name}}/' node_modules/typedoc-default-themes/bin/default/partials/breadcrumb.hbs
9+
10+
COPY clone.sh /home/node/work
11+
COPY docgen.sh /home/node/work
12+
COPY prep_docgen.js /home/node/work
13+
COPY findSemverPackage.js /home/node/work
14+
15+
ENTRYPOINT ["/home/node/work/docgen.sh"]

docgen/clone.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
REPO=$1
4+
DIR=$2
5+
BRANCH=$3
6+
7+
mkdir -p $DIR
8+
git clone $REPO $DIR
9+
cd $DIR
10+
git checkout $BRANCH

docgen/docgen.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
WORK=/home/node/work
5+
PROJECT=${WORK}/project
6+
7+
[[ -d $PROJECT ]] || {
8+
echo "package must be mounted in Docker at $PROJECT"
9+
exit 1
10+
}
11+
12+
[[ -e $PROJECT/package.json ]] || {
13+
echo "package must be mounted in Docker at $PROJECT"
14+
exit 1
15+
}
16+
17+
pushd $WORK
18+
cp $WORK/project/docgen.json .
19+
cp $WORK/project/typedoc.json .
20+
README=$(jq -r .readme < typedoc.json)
21+
cp $WORK/project/$README .
22+
23+
./prep_docgen.js
24+
bash ./clone_repos.sh
25+
npx typedoc

docgen/docker_push.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
3+
docker build -t docgen . --no-cache
4+
docker tag docgen:latest uirouter/docgen:stable
5+
docker push uirouter/docgen:stable
6+

docgen/findSemverPackage.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const child_process = require('child_process');
2+

docgen/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"dependencies": {
3+
"lodash": "^4.17.19",
4+
"find-parent-dir": "^0.3.0",
5+
"typedoc": "0.17.8",
6+
"typescript": "3.9.7",
7+
"typedoc-plugin-ui-router": "3.0.2"
8+
}
9+
}

docgen/prep_docgen.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env node
2+
const fs = require('fs');
3+
const childProcess = require('child_process');
4+
const _ = require('lodash');
5+
6+
const WORKDIR = process.cwd();
7+
const PACKAGE_DIR = `${WORKDIR}/project`;
8+
const SRC_DIR = `${PACKAGE_DIR}/src`;
9+
const DOCGENCONFIG_PATH = `${PACKAGE_DIR}/docgen.json`;
10+
const TSCONFIG_PATH = `${PACKAGE_DIR}/tsconfig.json`;
11+
const PACKAGEJSON_PATH = `${PACKAGE_DIR}/package.json`;
12+
13+
if (!fs.existsSync(SRC_DIR)) { throw new Error(`${SRC_DIR} does not exist`) }
14+
if (!fs.existsSync(DOCGENCONFIG_PATH)) { throw new Error(`${DOCGENCONFIG_PATH} does not exist`); }
15+
16+
const PACKAGEJSON = JSON.parse(fs.readFileSync(PACKAGEJSON_PATH));
17+
const DOCGENCONFIG = getDocgenConfig();
18+
const TSCONFIG_COPY = JSON.parse(fs.readFileSync(TSCONFIG_PATH).toString());
19+
20+
// Merge tsconfig block from docgen.json into tsconfig.json
21+
_.merge(TSCONFIG_COPY, DOCGENCONFIG.tsconfig);
22+
fs.writeFileSync(`${WORKDIR}/tsconfig.json`, JSON.stringify(TSCONFIG_COPY, null, 2));
23+
24+
function getDocgenConfig() {
25+
const config = JSON.parse(fs.readFileSync(DOCGENCONFIG_PATH));
26+
const requiredKeys = ['navigation', 'tsconfig'];
27+
const missing = requiredKeys.find((key) => !_.has(config, key));
28+
if (missing) {
29+
console.error(`${DOCGENCONFIG_PATH} does not contain configuration key: '${missing}'`);
30+
process.exit(1);
31+
}
32+
return config;
33+
}
34+
35+
// Fetch all included packages (i.e., core module)
36+
const CLONE_COMMANDS = ['#!/usr/bin/env bash', 'set -x'];
37+
38+
(DOCGENCONFIG.include || []).forEach(include => {
39+
const { pkg, repo, branch } = include;
40+
const semver = ['peerDependencies', 'dependencies', 'devDependencies']
41+
.map((key) => (PACKAGEJSON[key] || {})[pkg])
42+
.find((x) => !!x);
43+
44+
const version = branch || findSemverPackage(pkg, semver);
45+
CLONE_COMMANDS.push(`./clone.sh ${repo} ${PACKAGE_DIR}/src/includes/${pkg} ${version}`);
46+
});
47+
48+
fs.writeFileSync('clone_repos.sh', CLONE_COMMANDS.join('\n'));
49+
50+
// Finds the newest version of a package published to NPM that matches the desired semver range
51+
function findSemverPackage(packageName, semver) {
52+
const stdout = childProcess.execSync(`npm info ${packageName}@${semver} version`).toString();
53+
const lines = stdout.split(/\n/).filter(x => x.length);
54+
if (lines.length === 0) {
55+
throw new Error(`No published package matched ${packageName}@${semver}`)
56+
} else if (lines.length === 1) {
57+
return lines[ 0 ];
58+
} else {
59+
const line = stdout.trim().split(/\n/).pop().trim();
60+
const [, version] = /.* '(.*)'$/.exec(line) || [];
61+
if (!version) {
62+
console.log({ stdout, line });
63+
throw new Error(`Couldn't find version matching ${packageName}@${semver} in npm registry`)
64+
}
65+
return version;
66+
}
67+
}

0 commit comments

Comments
 (0)