From 9491318c26f2e2609001b0593b7e6fd2b01e77e0 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 20 Jan 2021 10:13:59 +0000 Subject: [PATCH] build(docs-infra): move docs-watch settings to a base package (#40479) This new `base-authoring-package` captures all the settings, which turns of potentially fatal checks, in one place. This new package is then used as a base for all the docs-watch related packages, rather than dotting the settings in a variety of different packages. This also has the benefit that the standard configuration for doc-gen is fatal on failed checks by default. PR Close #40479 --- .../transforms/angular-base-package/index.js | 41 +++++++++++++------ .../angular-content-package/index.js | 4 +- .../transforms/angular.io-package/index.js | 38 ----------------- .../transforms/authors-package/api-package.js | 27 ++++++------ .../authors-package/base-authoring-package.js | 36 ++++++++++++++++ .../getting-started-package.js | 3 +- .../authors-package/guide-package.js | 3 +- .../authors-package/marketing-package.js | 5 ++- .../authors-package/tutorial-package.js | 3 +- .../transforms/authors-package/watchr.js | 14 +++---- .../links-package/inline-tag-defs/link.js | 2 +- .../inline-tag-defs/link.spec.js | 5 ++- 12 files changed, 97 insertions(+), 84 deletions(-) create mode 100644 aio/tools/transforms/authors-package/base-authoring-package.js diff --git a/aio/tools/transforms/angular-base-package/index.js b/aio/tools/transforms/angular-base-package/index.js index 890b480668..e62f4373fb 100644 --- a/aio/tools/transforms/angular-base-package/index.js +++ b/aio/tools/transforms/angular-base-package/index.js @@ -5,18 +5,22 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ +const { extname, resolve } = require('canonical-path'); +const { existsSync } = require('fs'); const path = require('path'); -const Package = require('dgeni').Package; +const Package = require('dgeni').Package; const gitPackage = require('dgeni-packages/git'); const jsdocPackage = require('dgeni-packages/jsdoc'); const nunjucksPackage = require('dgeni-packages/nunjucks'); -const linksPackage = require('../links-package'); -const examplesPackage = require('../examples-package'); -const targetPackage = require('../target-package'); -const remarkPackage = require('../remark-package'); const postProcessPackage = require('dgeni-packages/post-process-html'); +const { SRC_PATH } = require('../config'); +const examplesPackage = require('../examples-package'); +const linksPackage = require('../links-package'); +const remarkPackage = require('../remark-package'); +const targetPackage = require('../target-package'); + const { PROJECT_ROOT, CONTENTS_PATH, OUTPUT_PATH, DOCS_OUTPUT_PATH, TEMPLATES_PATH, AIO_PATH, requireFolder } = require('../config'); module.exports = new Package('angular-base', [ @@ -53,13 +57,6 @@ module.exports = new Package('angular-base', [ inlineTagProcessor.inlineTagDefinitions.push(require('./inline-tag-defs/custom-search-defs/')); }) - .config(function(checkAnchorLinksProcessor, checkForUnusedExampleRegions) { - // These are disabled here to prevent false negatives for the `docs-watch` task. - // It is re-enabled in the main `angular.io-package` - checkAnchorLinksProcessor.$enabled = false; - checkForUnusedExampleRegions.$enabled = false; - }) - // Where do we get the source files? .config(function(readFilesProcessor, collectExamples, generateKeywordsProcessor, jsonFileReader) { @@ -125,7 +122,25 @@ module.exports = new Package('angular-base', [ getLinkInfo.useFirstAmbiguousLink = false; }) - + .config(function(checkAnchorLinksProcessor) { + // since we encode the HTML to JSON we need to ensure that this processor runs before that encoding happens. + checkAnchorLinksProcessor.$runBefore = ['convertToJsonProcessor']; + checkAnchorLinksProcessor.$runAfter = ['fixInternalDocumentLinks']; + // We only want to check docs that are going to be output as JSON docs. + checkAnchorLinksProcessor.checkDoc = (doc) => doc.path && doc.outputPath && extname(doc.outputPath) === '.json' && doc.docType !== 'json-doc'; + // Since we have a `base[href="/"]` arrangement all links are relative to that and not relative to the source document's path + checkAnchorLinksProcessor.base = '/'; + // Ignore links to local assets + // (This is not optimal in terms of performance without making changes to dgeni-packages there is no other way. + // That being said do this only add 500ms onto the ~30sec doc-gen run - so not a huge issue) + checkAnchorLinksProcessor.ignoredLinks.push({ + test(url) { + return (existsSync(resolve(SRC_PATH, url))); + } + }); + checkAnchorLinksProcessor.pathVariants = ['', '/', '.html', '/index.html', '#top-of-page']; + checkAnchorLinksProcessor.errorOnUnmatchedLinks = true; + }) .config(function(computePathsProcessor, generateKeywordsProcessor) { diff --git a/aio/tools/transforms/angular-content-package/index.js b/aio/tools/transforms/angular-content-package/index.js index 47d7432ae6..37b8ce8c5c 100644 --- a/aio/tools/transforms/angular-content-package/index.js +++ b/aio/tools/transforms/angular-content-package/index.js @@ -18,7 +18,7 @@ const { CONTENTS_PATH, GUIDE_EXAMPLES_PATH } = require('../config'); module.exports = new Package('angular-content', [basePackage, contentPackage]) // Where do we get the source files? - .config(function(readFilesProcessor, collectExamples, renderExamples) { + .config(function(readFilesProcessor, collectExamples) { const gitignoreFilePath = path.resolve(GUIDE_EXAMPLES_PATH, '.gitignore'); const gitignoreFile = fs.readFileSync(gitignoreFilePath, 'utf8'); @@ -91,8 +91,6 @@ module.exports = new Package('angular-content', [basePackage, contentPackage]) collectExamples.exampleFolders.push('examples'); collectExamples.registerIgnoredExamples(ignoredExamplePaths, gitignoreFilePath); - - renderExamples.ignoreBrokenExamples = true; }) diff --git a/aio/tools/transforms/angular.io-package/index.js b/aio/tools/transforms/angular.io-package/index.js index dd53e65985..f891ab05cb 100644 --- a/aio/tools/transforms/angular.io-package/index.js +++ b/aio/tools/transforms/angular.io-package/index.js @@ -11,9 +11,6 @@ const apiPackage = require('../angular-api-package'); const contentPackage = require('../angular-content-package'); const errorsPackage = require('../angular-errors-package'); const cliDocsPackage = require('../cli-docs-package'); -const { extname, resolve } = require('canonical-path'); -const { existsSync } = require('fs'); -const { SRC_PATH } = require('../config'); module.exports = new Package('angular.io', [gitPackage, apiPackage, contentPackage, cliDocsPackage, errorsPackage]) @@ -29,41 +26,6 @@ module.exports = new Package('angular.io', [gitPackage, apiPackage, contentPacka renderDocsProcessor.extraData.versionInfo = versionInfo; }) - .config(function(checkForUnusedExampleRegions) { - // Re-enable this processor that was disabled in the `angular-base` package to - // avoid running it during `serve-and-sync` runs. - checkForUnusedExampleRegions.$enabled = true; - }) - - .config(function(checkAnchorLinksProcessor, linkInlineTagDef, renderExamples) { - - // Fail the processing if there is an invalid link - linkInlineTagDef.failOnBadLink = true; - - checkAnchorLinksProcessor.$enabled = true; - // since we encode the HTML to JSON we need to ensure that this processor runs before that encoding happens. - checkAnchorLinksProcessor.$runBefore = ['convertToJsonProcessor']; - checkAnchorLinksProcessor.$runAfter = ['fixInternalDocumentLinks']; - // We only want to check docs that are going to be output as JSON docs. - checkAnchorLinksProcessor.checkDoc = (doc) => doc.path && doc.outputPath && extname(doc.outputPath) === '.json' && doc.docType !== 'json-doc'; - // Since we have a `base[href="/"]` arrangement all links are relative to that and not relative to the source document's path - checkAnchorLinksProcessor.base = '/'; - // Ignore links to local assets - // (This is not optimal in terms of performance without making changes to dgeni-packages there is no other way. - // That being said do this only add 500ms onto the ~30sec doc-gen run - so not a huge issue) - checkAnchorLinksProcessor.ignoredLinks.push({ - test(url) { - return (existsSync(resolve(SRC_PATH, url))); - } - }); - checkAnchorLinksProcessor.pathVariants = ['', '/', '.html', '/index.html', '#top-of-page']; - checkAnchorLinksProcessor.errorOnUnmatchedLinks = true; - - // Make sure we fail if the examples are not right - renderExamples.ignoreBrokenExamples = false; - - }) - .config(function(renderLinkInfo, postProcessHtml) { renderLinkInfo.docTypes = postProcessHtml.docTypes; }); diff --git a/aio/tools/transforms/authors-package/api-package.js b/aio/tools/transforms/authors-package/api-package.js index ce23228a3d..cc23500436 100644 --- a/aio/tools/transforms/authors-package/api-package.js +++ b/aio/tools/transforms/authors-package/api-package.js @@ -8,6 +8,7 @@ const Package = require('dgeni').Package; const apiPackage = require('../angular-api-package'); const { API_SOURCE_PATH } = require('../config'); +const baseAuthoringPackage = require('./base-authoring-package'); const packageMap = { animations: ['animations/index.ts', 'animations/browser/index.ts', 'animations/browser/testing/index.ts'], @@ -26,19 +27,19 @@ const packageMap = { function createPackage(packageName) { - return new Package('author-api', [apiPackage]) - .config(function(readTypeScriptModules) { - readTypeScriptModules.sourceFiles = packageMap[packageName]; - }) - .config(function(readFilesProcessor) { - readFilesProcessor.sourceFiles = [ - { - basePath: API_SOURCE_PATH, - include: `${API_SOURCE_PATH}/examples/${packageName}/**/*`, - fileReader: 'exampleFileReader' - } - ]; - }); + return new Package('author-api', [baseAuthoringPackage, apiPackage]) + .config(function(readTypeScriptModules) { + readTypeScriptModules.sourceFiles = packageMap[packageName]; + }) + .config(function(readFilesProcessor) { + readFilesProcessor.sourceFiles = [ + { + basePath: API_SOURCE_PATH, + include: `${API_SOURCE_PATH}/examples/${packageName}/**/*`, + fileReader: 'exampleFileReader' + } + ]; + }); } diff --git a/aio/tools/transforms/authors-package/base-authoring-package.js b/aio/tools/transforms/authors-package/base-authoring-package.js new file mode 100644 index 0000000000..3dbfd6cb46 --- /dev/null +++ b/aio/tools/transforms/authors-package/base-authoring-package.js @@ -0,0 +1,36 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const Package = require('dgeni').Package; +const basePackage = require('../angular-base-package'); + +/** + * A base package used by all the authoring packages in this folder. + * + * This package turns off lots of the potentially fatal checks to allow + * doc-gen to complete when authors are using the `docs-watch` or `serve-and-sync` + * jobs. + */ +const baseAuthoringPackage = new Package('base-authoring', [basePackage]); +baseAuthoringPackage + .config(function(checkAnchorLinksProcessor, checkForUnusedExampleRegions) { + // These are disabled here to prevent false negatives for the `docs-watch` task. + checkAnchorLinksProcessor.$enabled = false; + checkForUnusedExampleRegions.$enabled = false; + }) + + .config(function(linkInlineTagDef) { + // Do not fail the processing if there is an invalid link + linkInlineTagDef.failOnBadLink = false; + }) + + .config(function(renderExamples) { + // Do not fail the processing if there is a broken example + renderExamples.ignoreBrokenExamples = true; + }); + +module.exports = baseAuthoringPackage; diff --git a/aio/tools/transforms/authors-package/getting-started-package.js b/aio/tools/transforms/authors-package/getting-started-package.js index eb2e0110ff..a94af77fa4 100644 --- a/aio/tools/transforms/authors-package/getting-started-package.js +++ b/aio/tools/transforms/authors-package/getting-started-package.js @@ -12,6 +12,7 @@ const {readFileSync} = require('fs'); const contentPackage = require('../angular-content-package'); const {CONTENTS_PATH} = require('../config'); +const baseAuthoringPackage = require('./base-authoring-package'); const {codeExampleMatcher} = require('./utils'); /* eslint no-console: "off" */ @@ -27,7 +28,7 @@ function createPackage(tutorialName) { console.log(examples.map(example => ' - ' + example).join('\n')); } - return new Package('author-getting-started', [contentPackage]) + return new Package('author-getting-started', [baseAuthoringPackage, contentPackage]) .config(function(readFilesProcessor) { readFilesProcessor.sourceFiles = [ {basePath: CONTENTS_PATH, include: tutorialFilePath, fileReader: 'contentFileReader'}, { diff --git a/aio/tools/transforms/authors-package/guide-package.js b/aio/tools/transforms/authors-package/guide-package.js index 4ba82e950d..e7cffffb07 100644 --- a/aio/tools/transforms/authors-package/guide-package.js +++ b/aio/tools/transforms/authors-package/guide-package.js @@ -14,6 +14,7 @@ const {readFileSync} = require('fs'); const contentPackage = require('../angular-content-package'); const {CONTENTS_PATH} = require('../config'); +const baseAuthoringPackage = require('./base-authoring-package'); const {codeExampleMatcher} = require('./utils'); function createPackage(guideName) { @@ -27,7 +28,7 @@ function createPackage(guideName) { console.log(examples.map(example => ' - ' + example).join('\n')); } - return new Package('author-guide', [contentPackage]).config(function(readFilesProcessor) { + return new Package('author-guide', [baseAuthoringPackage, contentPackage]).config(function(readFilesProcessor) { readFilesProcessor.sourceFiles = [ {basePath: CONTENTS_PATH, include: guideFilePath, fileReader: 'contentFileReader'}, { basePath: CONTENTS_PATH, diff --git a/aio/tools/transforms/authors-package/marketing-package.js b/aio/tools/transforms/authors-package/marketing-package.js index dd762096fe..8a51250fe8 100644 --- a/aio/tools/transforms/authors-package/marketing-package.js +++ b/aio/tools/transforms/authors-package/marketing-package.js @@ -7,10 +7,11 @@ */ const Package = require('dgeni').Package; const contentPackage = require('../angular-content-package'); -const { CONTENTS_PATH } = require('../config'); +const {CONTENTS_PATH} = require('../config'); +const baseAuthoringPackage = require('./base-authoring-package'); function createPackage() { - return new Package('author-marketing', [contentPackage]) + return new Package('author-marketing', [baseAuthoringPackage, contentPackage]) .config(function(readFilesProcessor) { readFilesProcessor.sourceFiles = [ { diff --git a/aio/tools/transforms/authors-package/tutorial-package.js b/aio/tools/transforms/authors-package/tutorial-package.js index 3fd0fbda16..020deb08fb 100644 --- a/aio/tools/transforms/authors-package/tutorial-package.js +++ b/aio/tools/transforms/authors-package/tutorial-package.js @@ -12,6 +12,7 @@ const {readFileSync} = require('fs'); const contentPackage = require('../angular-content-package'); const {CONTENTS_PATH} = require('../config'); +const baseAuthoringPackage = require('./base-authoring-package'); const {codeExampleMatcher} = require('./utils'); /* eslint no-console: "off" */ @@ -27,7 +28,7 @@ function createPackage(tutorialName) { console.log(examples.map(example => ' - ' + example).join('\n')); } - return new Package('author-tutorial', [contentPackage]).config(function(readFilesProcessor) { + return new Package('author-tutorial', [baseAuthoringPackage, contentPackage]).config(function(readFilesProcessor) { readFilesProcessor.sourceFiles = [ {basePath: CONTENTS_PATH, include: tutorialFilePath, fileReader: 'contentFileReader'}, { basePath: CONTENTS_PATH, diff --git a/aio/tools/transforms/authors-package/watchr.js b/aio/tools/transforms/authors-package/watchr.js index 70982f43dc..d9cf254ef3 100644 --- a/aio/tools/transforms/authors-package/watchr.js +++ b/aio/tools/transforms/authors-package/watchr.js @@ -29,15 +29,11 @@ if (process.argv.indexOf('--watch-only') === -1) { console.log('Skip the full doc-gen by running: `yarn docs-watch --watch-only`'); console.log('================================================================'); const {Dgeni} = require('dgeni'); - const dgeni = new Dgeni([require('../angular.io-package')]); - - // Turn off all the potential failures for this doc-gen one-off run. - // This enables authors to run `docs-watch` while the docs are still in an unstable state. - const injector = dgeni.configureInjector(); - injector.get('linkInlineTagDef').failOnBadLink = false; - injector.get('checkAnchorLinksProcessor').$enabled = false; - injector.get('renderExamples').ignoreBrokenExamples = true; - + const dgeni = new Dgeni([ + // The base-authoring-package will turn off potential failures for this doc-gen one-off run. + // This enables authors to run `docs-watch` while the docs are still in an unstable state. + require('./base-authoring-package'), + require('../angular.io-package')]); p = dgeni.generate(); } diff --git a/aio/tools/transforms/links-package/inline-tag-defs/link.js b/aio/tools/transforms/links-package/inline-tag-defs/link.js index 16f44baaf7..ff671bae5f 100644 --- a/aio/tools/transforms/links-package/inline-tag-defs/link.js +++ b/aio/tools/transforms/links-package/inline-tag-defs/link.js @@ -14,7 +14,7 @@ var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/; module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) { return { name: 'link', - failOnBadLink: false, + failOnBadLink: true, description: 'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors', handler(doc, tagName, tagDescription) { diff --git a/aio/tools/transforms/links-package/inline-tag-defs/link.spec.js b/aio/tools/transforms/links-package/inline-tag-defs/link.spec.js index c380b2ce3c..878ab04859 100644 --- a/aio/tools/transforms/links-package/inline-tag-defs/link.spec.js +++ b/aio/tools/transforms/links-package/inline-tag-defs/link.spec.js @@ -25,7 +25,7 @@ describe('link inline-tag-def', function() { const doc = {}; const tagName = 'link'; const tagDescription = 'doc-id link text'; - getLinkInfo.and.returnValue({ url: 'url/to/doc', title: 'link text' }); + getLinkInfo.and.returnValue({ url: 'url/to/doc', title: 'link text', valid: true }); tag.handler(doc, tagName, tagDescription); expect(getLinkInfo).toHaveBeenCalledWith('doc-id', 'link text', doc); }); @@ -34,7 +34,7 @@ describe('link inline-tag-def', function() { const doc = {}; const tagName = 'link'; const tagDescription = 'doc-id link text'; - getLinkInfo.and.returnValue({ url: 'url/to/doc', title: 'link text' }); + getLinkInfo.and.returnValue({ url: 'url/to/doc', title: 'link text', valid: true }); const result = tag.handler(doc, tagName, tagDescription); expect(result).toEqual('link text'); }); @@ -43,6 +43,7 @@ describe('link inline-tag-def', function() { const doc = {}; const tagName = 'link'; const tagDescription = 'doc-id link text'; + tag.failOnBadLink = false; getLinkInfo.and.returnValue({ valid: false, error: 'Error message', errorType: 'error' }); expect(() => tag.handler(doc, tagName, tagDescription)).not.toThrow(); expect(log.warn).toHaveBeenCalledWith('Error in {@link doc-id link text} - Error message - doc');