diff --git a/aio/tools/transforms/cli-docs-package/index.js b/aio/tools/transforms/cli-docs-package/index.js index 3d4fa95da7..ecefe7d809 100644 --- a/aio/tools/transforms/cli-docs-package/index.js +++ b/aio/tools/transforms/cli-docs-package/index.js @@ -1,4 +1,5 @@ const {resolve} = require('canonical-path'); +const semver = require('semver'); const Package = require('dgeni').Package; const basePackage = require('../angular-base-package'); const contentPackage = require('../content-package'); @@ -8,59 +9,60 @@ const CLI_SOURCE_PATH = resolve(CLI_SOURCE_ROOT, 'node_modules/@angular/cli'); const CLI_SOURCE_HELP_PATH = resolve(CLI_SOURCE_PATH, 'help'); // Define the dgeni package for generating the docs -module.exports = new Package('cli-docs', [basePackage, contentPackage]) +module.exports = + new Package('cli-docs', [basePackage, contentPackage]) -// Register the services and file readers -.factory(require('./readers/cli-command')) + // Register the services and file readers + .factory(require('./readers/cli-command')) -// Register the processors -.processor(require('./processors/processCliContainerDoc')) -.processor(require('./processors/processCliCommands')) -.processor(require('./processors/filterHiddenCommands')) + // Register the processors + .processor(require('./processors/processCliContainerDoc')) + .processor(require('./processors/processCliCommands')) + .processor(require('./processors/filterHiddenCommands')) -// Configure file reading -.config(function(readFilesProcessor, cliCommandFileReader) { - readFilesProcessor.fileReaders.push(cliCommandFileReader); - readFilesProcessor.sourceFiles = readFilesProcessor.sourceFiles.concat([ - { - basePath: CLI_SOURCE_HELP_PATH, - include: resolve(CLI_SOURCE_HELP_PATH, '*.json'), - fileReader: 'cliCommandFileReader' - }, - { - basePath: CONTENTS_PATH, - include: resolve(CONTENTS_PATH, 'cli/**'), - fileReader: 'contentFileReader' - }, - ]); -}) + // Configure file reading + .config(function(readFilesProcessor, cliCommandFileReader) { + readFilesProcessor.fileReaders.push(cliCommandFileReader); + readFilesProcessor.sourceFiles = readFilesProcessor.sourceFiles.concat([ + { + basePath: CLI_SOURCE_HELP_PATH, + include: resolve(CLI_SOURCE_HELP_PATH, '*.json'), + fileReader: 'cliCommandFileReader' + }, + { + basePath: CONTENTS_PATH, + include: resolve(CONTENTS_PATH, 'cli/**'), + fileReader: 'contentFileReader' + }, + ]); + }) -.config(function(templateFinder, templateEngine, getInjectables) { - // Where to find the templates for the CLI doc rendering - templateFinder.templateFolders.unshift(resolve(TEMPLATES_PATH, 'cli')); - // Add in templating filters and tags - templateEngine.filters = templateEngine.filters.concat(getInjectables(requireFolder(__dirname, './rendering'))); -}) + .config(function(templateFinder, templateEngine, getInjectables) { + // Where to find the templates for the CLI doc rendering + templateFinder.templateFolders.unshift(resolve(TEMPLATES_PATH, 'cli')); + // Add in templating filters and tags + templateEngine.filters = templateEngine.filters.concat( + getInjectables(requireFolder(__dirname, './rendering'))); + }) -.config(function(renderDocsProcessor) { + .config(function(renderDocsProcessor) { - const cliPackage = require(resolve(CLI_SOURCE_PATH, 'package.json')); - const repoUrlParts = cliPackage.repository.url.replace(/\.git$/, '').split('/'); - const version = `v${cliPackage.version}`; - const repo = repoUrlParts.pop(); - const owner = repoUrlParts.pop(); - const cliVersionInfo = { - gitRepoInfo: { owner, repo }, - currentVersion: { raw: version } - }; + const cliPackage = require(resolve(CLI_SOURCE_PATH, 'package.json')); + const repoUrlParts = cliPackage.repository.url.replace(/\.git$/, '').split('/'); + const version = `v${semver.clean(cliPackage.version)}`; + const repo = repoUrlParts.pop(); + const owner = repoUrlParts.pop(); + const cliVersionInfo = {gitRepoInfo: {owner, repo}, currentVersion: {raw: version}}; - // Add the cli version data to the renderer, for use in things like github links - renderDocsProcessor.extraData.cliVersionInfo = cliVersionInfo; -}) + // Add the cli version data to the renderer, for use in things like github links + renderDocsProcessor.extraData.cliVersionInfo = cliVersionInfo; + }) -.config(function(convertToJsonProcessor, postProcessHtml) { - convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(['cli-command', 'cli-overview']); - postProcessHtml.docTypes = postProcessHtml.docTypes.concat(['cli-command', 'cli-overview']); -}); + .config(function(convertToJsonProcessor, postProcessHtml) { + convertToJsonProcessor.docTypes = + convertToJsonProcessor.docTypes.concat(['cli-command', 'cli-overview']); + postProcessHtml.docTypes = + postProcessHtml.docTypes.concat(['cli-command', 'cli-overview']); + }); diff --git a/aio/tools/transforms/cli-docs-package/readers/cli-command.js b/aio/tools/transforms/cli-docs-package/readers/cli-command.js index bca735a8ee..d1203bff48 100644 --- a/aio/tools/transforms/cli-docs-package/readers/cli-command.js +++ b/aio/tools/transforms/cli-docs-package/readers/cli-command.js @@ -26,22 +26,59 @@ module.exports = function cliCommandFileReader(log) { docType: 'cli-command', id: `cli-${doc.name}`, commandAliases: doc.aliases || [], - aliases: computeAliases(doc), - path, + aliases: computeAliases(doc), path, outputPath: `${path}.json`, breadCrumbs: [ - { text: 'CLI', path: 'cli' }, - { text: name, path }, + {text: 'CLI', path: 'cli'}, + {text: name, path}, ] }); + if (doc.longDescription) { + doc.longDescriptionDoc = createLongDescriptionDoc(fileInfo); + } return [result]; } catch (e) { log.warn(`Failed to read cli command file: "${fileInfo.relativePath}" - ${e.message}`); } } }; -}; + function computeAliases(doc) { + return [doc.name].concat(doc.aliases || []).map(alias => `cli-${alias}`); + } -function computeAliases(doc) { - return [doc.name].concat(doc.aliases || []).map(alias => `cli-${alias}`); -} \ No newline at end of file + /** + * Synthesize a doc for the CLI command long description, which is used to generate links + * for viewing and editing the long description in GitHub. + * + * The long description is stored in a markdown file that is referenced from the original + * schema file for the command, via the `$longDescription` field. The field is a relative path + * to the markdown file from the schema file. + * + * This function tries to retrieve that original schema based on the file path of the help JSON + * file, which was passed to the `cliCommandFileReader.getDocs()` method. + */ + function createLongDescriptionDoc(fileInfo) { + try { + const path = require('canonical-path'); + const fs = require('fs'); + const json5 = require('json5'); + + const schemaJsonPath = path.resolve(fileInfo.basePath, '../commands', fileInfo.relativePath); + const schemaJson = fs.readFileSync(schemaJsonPath); + const schema = json5.parse(schemaJson); + if (schema.$longDescription) { + return { + docType: 'content', + startingLine: 0, + fileInfo: { + realProjectRelativePath: + path.join(path.dirname(fileInfo.realProjectRelativePath), schema.$longDescription) + } + }; + } + } catch (e) { + log.warn('Unable to read CLI long description file info', e, fileInfo); + return undefined; + } + } +}; diff --git a/aio/tools/transforms/cli-docs-package/readers/cli-command.spec.js b/aio/tools/transforms/cli-docs-package/readers/cli-command.spec.js index 341c2758af..9c7cfdb3c4 100644 --- a/aio/tools/transforms/cli-docs-package/readers/cli-command.spec.js +++ b/aio/tools/transforms/cli-docs-package/readers/cli-command.spec.js @@ -40,7 +40,12 @@ const content = ` } `; -const fileInfo = {content, baseName: 'add'}; +const fileInfo = { + content, + baseName: 'add', + relativePath: 'add.json', + basePath: __dirname + '/mocks/help', +}; describe('cli-command reader', () => { describe('getDocs', () => { @@ -77,8 +82,8 @@ describe('cli-command reader', () => { it('should compute the bread crumbs', () => { const docs = reader.getDocs(fileInfo); expect(docs[0].breadCrumbs).toEqual([ - { text: 'CLI', path: 'cli' }, - { text: 'add', path: 'cli/add' }, + {text: 'CLI', path: 'cli'}, + {text: 'add', path: 'cli/add'}, ]); }); @@ -89,7 +94,9 @@ describe('cli-command reader', () => { it('should extract the long description', () => { const docs = reader.getDocs(fileInfo); - expect(docs[0].longDescription).toEqual('Add support for a library in your project, for example adding `@angular/pwa` which would configure\nyour project for PWA support.\n'); + expect(docs[0].longDescription) + .toEqual( + 'Add support for a library in your project, for example adding `@angular/pwa` which would configure\nyour project for PWA support.\n'); }); it('should extract the command type', () => { @@ -110,10 +117,19 @@ describe('cli-command reader', () => { it('should extract the options', () => { const docs = reader.getDocs(fileInfo); expect(docs[0].options).toEqual([ - jasmine.objectContaining({ name: 'collection' }), - jasmine.objectContaining({ name: 'help' }), - jasmine.objectContaining({ name: 'helpJson' }), + jasmine.objectContaining({name: 'collection'}), + jasmine.objectContaining({name: 'help'}), + jasmine.objectContaining({name: 'helpJson'}), ]); }); + + it('should extract file info for the long description', () => { + const [doc] = reader.getDocs(fileInfo); + expect(doc.longDescriptionDoc).toEqual({ + docType: 'content', + startingLine: 0, + fileInfo: {realProjectRelativePath: 'packages/angular/cli/commands/add-long.md'} + }); + }); }); }); diff --git a/aio/tools/transforms/cli-docs-package/readers/mocks/commands/add.json b/aio/tools/transforms/cli-docs-package/readers/mocks/commands/add.json new file mode 100644 index 0000000000..84423ec268 --- /dev/null +++ b/aio/tools/transforms/cli-docs-package/readers/mocks/commands/add.json @@ -0,0 +1,3 @@ +{ + "$longDescription": "./add-long.md" +} \ No newline at end of file diff --git a/aio/tools/transforms/templates/cli/cli-command.template.html b/aio/tools/transforms/templates/cli/cli-command.template.html index 0b775a4b7d..5de2178ff9 100644 --- a/aio/tools/transforms/templates/cli/cli-command.template.html +++ b/aio/tools/transforms/templates/cli/cli-command.template.html @@ -14,7 +14,10 @@ {$ cli.renderSyntax(doc) $} {% if doc.longDescription.length %} -

Description

+

+ {$ github.githubLinks(doc.longDescriptionDoc, cliVersionInfo) $} + Description +

{$ doc.longDescription | marked $} {% endif%}