Skip to content

Commit a6af441

Browse files
authored
Merge pull request #399 from Microsoft/pgonzal/ad-command-line
Add a command line for api-documenter
2 parents 14b9f78 + 989ed38 commit a6af441

File tree

16 files changed

+191
-66
lines changed

16 files changed

+191
-66
lines changed

libraries/api-documenter/ad.cmd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@ECHO OFF
2+
@SETLOCAL
3+
node "%~dp0\lib\start" %*
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
require('../lib/start.js')
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
import { CommandLineParser } from '@microsoft/ts-command-line';
5+
import { MarkdownAction } from './MarkdownAction';
6+
import { YamlAction } from './YamlAction';
7+
8+
export class ApiDocumenterCommandLine extends CommandLineParser {
9+
constructor() {
10+
super({
11+
toolFilename: 'api-documenter',
12+
toolDescription: 'Reads *.api.json files produced by api-extractor, '
13+
+ ' and generates API documentation in various output formats'
14+
});
15+
this._populateActions();
16+
}
17+
18+
protected onDefineParameters(): void { // override
19+
// No parameters
20+
}
21+
22+
private _populateActions(): void {
23+
this.addAction(new MarkdownAction(this));
24+
this.addAction(new YamlAction(this));
25+
}
26+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
import * as fsx from 'fs-extra';
5+
import * as path from 'path';
6+
7+
import {
8+
CommandLineAction,
9+
CommandLineStringParameter
10+
} from '@microsoft/ts-command-line';
11+
12+
import { DocItemSet } from '../utils/DocItemSet';
13+
14+
export abstract class BaseAction extends CommandLineAction {
15+
protected inputFolder: string;
16+
protected outputFolder: string;
17+
18+
private _inputFolderParameter: CommandLineStringParameter;
19+
private _outputFolderParameter: CommandLineStringParameter;
20+
21+
protected onDefineParameters(): void { // override
22+
this._inputFolderParameter = this.defineStringParameter({
23+
parameterLongName: '--input-folder',
24+
parameterShortName: '-i',
25+
key: 'FOLDER1',
26+
description: `Specifies the input folder containing the *.api.json files to be processed.`
27+
+ ` If omitted, the default is "./input"`
28+
});
29+
30+
this._outputFolderParameter = this.defineStringParameter({
31+
parameterLongName: '--output-folder',
32+
parameterShortName: '-o',
33+
key: 'FOLDER2',
34+
description: `Specifies the output folder where the documentation will be written.`
35+
+ ` ANY EXISTING CONTENTS WILL BE DELETED!`
36+
+ ` If omitted, the default is "./${this.options.actionVerb}"`
37+
});
38+
}
39+
40+
protected buildDocItemSet(): DocItemSet {
41+
const docItemSet: DocItemSet = new DocItemSet();
42+
43+
this.inputFolder = this._inputFolderParameter.value || './input';
44+
if (!fsx.existsSync(this.inputFolder)) {
45+
throw new Error('The input folder does not exist: ' + this.inputFolder);
46+
}
47+
48+
this.outputFolder = this._outputFolderParameter.value || `./${this.options.actionVerb}`;
49+
if (!fsx.existsSync(this.outputFolder)) {
50+
throw new Error('The output folder does not exist: ' + this.outputFolder);
51+
}
52+
53+
for (const filename of fsx.readdirSync(this.inputFolder)) {
54+
if (filename.match(/\.api\.json$/i)) {
55+
console.log(`Reading ${filename}`);
56+
const filenamePath: string = path.join(this.inputFolder, filename);
57+
docItemSet.loadApiJsonFile(filenamePath);
58+
}
59+
}
60+
61+
docItemSet.calculateReferences();
62+
63+
return docItemSet;
64+
}
65+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine';
5+
import { BaseAction } from './BaseAction';
6+
import { DocItemSet } from '../utils/DocItemSet';
7+
import { MarkdownDocumenter } from '../markdown/MarkdownDocumenter';
8+
9+
export class MarkdownAction extends BaseAction {
10+
constructor(parser: ApiDocumenterCommandLine) {
11+
super({
12+
actionVerb: 'markdown',
13+
summary: 'Generate documentation as Markdown files (*.md)',
14+
documentation: 'Generate documentation as Markdown files (*.md)'
15+
});
16+
}
17+
18+
protected onExecute(): void { // override
19+
const docItemSet: DocItemSet = this.buildDocItemSet();
20+
const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter(docItemSet);
21+
markdownDocumenter.generateFiles(this.outputFolder);
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine';
5+
import { BaseAction } from './BaseAction';
6+
import { DocItemSet } from '../utils/DocItemSet';
7+
import { YamlDocumenter } from '../yaml/YamlDocumenter';
8+
9+
export class YamlAction extends BaseAction {
10+
constructor(parser: ApiDocumenterCommandLine) {
11+
super({
12+
actionVerb: 'yaml',
13+
summary: 'Generate documentation as universal reference YAML files (*.yml)',
14+
documentation: 'Generate documentation as YAML files (*.yml)'
15+
});
16+
}
17+
18+
protected onExecute(): void { // override
19+
const docItemSet: DocItemSet = this.buildDocItemSet();
20+
const yamlDocumenter: YamlDocumenter = new YamlDocumenter(docItemSet);
21+
yamlDocumenter.generateFiles(this.outputFolder);
22+
}
23+
}

libraries/api-documenter/src/index.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

libraries/api-documenter/src/markdown/MarkdownGenerator.ts renamed to libraries/api-documenter/src/markdown/MarkdownDocumenter.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,21 @@ import {
2222
MarkupStructuredElement
2323
} from '@microsoft/api-extractor';
2424

25-
import { DocItemSet, DocItem, DocItemKind, IDocItemSetResolveResult } from '../DocItemSet';
26-
import { RenderingHelpers } from '../RenderingHelpers';
27-
import { MarkupBuilder } from '../MarkupBuilder';
28-
import { MarkdownRenderer, IMarkdownRenderApiLinkArgs } from '../MarkdownRenderer';
25+
import {
26+
DocItemSet,
27+
DocItem,
28+
DocItemKind,
29+
IDocItemSetResolveResult
30+
} from '../utils/DocItemSet';
31+
import { Utilities } from '../utils/Utilities';
32+
import { MarkupBuilder } from '../utils/MarkupBuilder';
33+
import { MarkdownRenderer, IMarkdownRenderApiLinkArgs } from '../utils/MarkdownRenderer';
2934

3035
/**
3136
* Renders API documentation in the Markdown file format.
3237
* For more info: https://en.wikipedia.org/wiki/Markdown
3338
*/
34-
export class MarkdownGenerator {
39+
export class MarkdownDocumenter {
3540
private _docItemSet: DocItemSet;
3641
private _outputFolder: string;
3742

@@ -57,7 +62,7 @@ export class MarkdownGenerator {
5762
private _writePackagePage(docPackage: DocItem): void {
5863
console.log(`Writing ${docPackage.name} package`);
5964

60-
const unscopedPackageName: string = RenderingHelpers.getUnscopedPackageName(docPackage.name);
65+
const unscopedPackageName: string = Utilities.getUnscopedPackageName(docPackage.name);
6166

6267
const markupPage: IMarkupPage = MarkupBuilder.createPage(`${unscopedPackageName} package`);
6368
this._writeBreadcrumb(markupPage, docPackage);
@@ -229,7 +234,7 @@ export class MarkdownGenerator {
229234
// TODO: Extract constructor into its own section
230235
const constructorTitle: MarkupBasicElement[] = [
231236
MarkupBuilder.createApiLink(
232-
[MarkupBuilder.createCode(RenderingHelpers.getConciseSignature(docMember.name, apiMember), 'javascript')],
237+
[MarkupBuilder.createCode(Utilities.getConciseSignature(docMember.name, apiMember), 'javascript')],
233238
docMember.getApiReference())
234239
];
235240

@@ -247,7 +252,7 @@ export class MarkdownGenerator {
247252
case 'method':
248253
const methodTitle: MarkupBasicElement[] = [
249254
MarkupBuilder.createApiLink(
250-
[MarkupBuilder.createCode(RenderingHelpers.getConciseSignature(docMember.name, apiMember), 'javascript')],
255+
[MarkupBuilder.createCode(Utilities.getConciseSignature(docMember.name, apiMember), 'javascript')],
251256
docMember.getApiReference())
252257
];
253258

@@ -334,7 +339,7 @@ export class MarkdownGenerator {
334339
case 'method':
335340
const methodTitle: MarkupBasicElement[] = [
336341
MarkupBuilder.createApiLink(
337-
[MarkupBuilder.createCode(RenderingHelpers.getConciseSignature(docMember.name, apiMember), 'javascript')],
342+
[MarkupBuilder.createCode(Utilities.getConciseSignature(docMember.name, apiMember), 'javascript')],
338343
docMember.getApiReference())
339344
];
340345

@@ -596,7 +601,7 @@ export class MarkdownGenerator {
596601
let baseName: string = '';
597602
for (const part of docItem.getHierarchy()) {
598603
if (part.kind === DocItemKind.Package) {
599-
baseName = RenderingHelpers.getUnscopedPackageName(part.name);
604+
baseName = Utilities.getUnscopedPackageName(part.name);
600605
} else {
601606
baseName += '.' + part.name;
602607
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
import * as os from 'os';
5+
import * as colors from 'colors';
6+
import * as path from 'path';
7+
8+
import { ApiDocumenterCommandLine } from './cli/ApiDocumenterCommandLine';
9+
10+
const myPackageJsonFilename: string = path.resolve(path.join(
11+
__dirname, '..', 'package.json')
12+
);
13+
const myPackageJson: { version: string } = require(myPackageJsonFilename);
14+
15+
console.log(os.EOL + colors.bold(`api-documenter ${myPackageJson.version} `
16+
+ colors.cyan(' - http://aka.ms/extractor') + os.EOL));
17+
18+
const parser: ApiDocumenterCommandLine = new ApiDocumenterCommandLine();
19+
20+
parser.execute();

libraries/api-documenter/src/DocItemSet.ts renamed to libraries/api-documenter/src/utils/DocItemSet.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
IApiItemReference
99
} from '@microsoft/api-extractor';
1010

11-
import { RenderingHelpers } from './RenderingHelpers';
11+
import { Utilities } from './Utilities';
1212

1313
export enum DocItemKind {
1414
Package,
@@ -227,7 +227,7 @@ export class DocItemSet {
227227
closestMatch: undefined
228228
};
229229

230-
const packageName: string = RenderingHelpers.getScopedPackageName(reference.scopeName, reference.packageName);
230+
const packageName: string = Utilities.getScopedPackageName(reference.scopeName, reference.packageName);
231231
if (!packageName) {
232232
// This would indicate an invalid data file, since API Extractor is supposed to normalize this
233233
throw new Error('resolveApiItemReference() failed because the packageName should not be empty');

0 commit comments

Comments
 (0)