From fb9edf972efc063a7449e5596a63ae6e64af583f Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 5 Jul 2016 16:46:44 -0700 Subject: [PATCH] chore: fix "Invalid example" warnings from shred map builder closes #1832 The shred map (xref) builder was issuing warnings. This fix includes - Adjustments to the shredder map builder itself so that it understands, e.g., app-project relative example paths. - `**/guide/glossary.jade` now (Jade) `includes` the shared parent `glossary.jade` rather than (Harp) importing (via `partial`). This fixes `makeExample` path issues in the glossary. - Adjusted some `makeExample` paths that were ok for site build, but confused the xref tool. --- .../latest/guide/dependency-injection.jade | 2 +- public/docs/dart/latest/guide/glossary.jade | 2 +- public/docs/dart/latest/tutorial/toh-pt5.jade | 3 - public/docs/ts/latest/glossary.jade | 12 ++-- public/docs/ts/latest/guide/glossary.jade | 2 +- .../processors/shredMapProcessor.js | 61 +++++++++++++------ 6 files changed, 51 insertions(+), 31 deletions(-) diff --git a/public/docs/dart/latest/guide/dependency-injection.jade b/public/docs/dart/latest/guide/dependency-injection.jade index ad695a9732..7236d24c7d 100644 --- a/public/docs/dart/latest/guide/dependency-injection.jade +++ b/public/docs/dart/latest/guide/dependency-injection.jade @@ -101,7 +101,7 @@ block dart-map-alternative As an alternative to using a configuration `Map`, we can define a custom configuration class: - +makeExample('dependency-injection/ts/app/app.config.ts','config-alt','app/app-config.ts (alternative config)')(format='.') + +makeExample('lib/app_config.dart (alternative config)','config-alt') :marked Defining a configuration class has a few benefits. One key benefit diff --git a/public/docs/dart/latest/guide/glossary.jade b/public/docs/dart/latest/guide/glossary.jade index a66284569e..ca1429104e 100644 --- a/public/docs/dart/latest/guide/glossary.jade +++ b/public/docs/dart/latest/guide/glossary.jade @@ -1 +1 @@ -!= partial("../glossary") +include ../glossary diff --git a/public/docs/dart/latest/tutorial/toh-pt5.jade b/public/docs/dart/latest/tutorial/toh-pt5.jade index 1c0ab90de8..c2923c1a05 100644 --- a/public/docs/dart/latest/tutorial/toh-pt5.jade +++ b/public/docs/dart/latest/tutorial/toh-pt5.jade @@ -132,9 +132,6 @@ code-example(language="bash"). ### Add a base tag -// Our Tour of Heroes needs routing, -// so we load the library in the `index.html` in a script tag immediately *after* the angular script itself. -//+makeExample('toh-5/dart/web/index.html', 'router', 'index.html (router)')(format=".") :marked First, edit `index.html` and add `` at the top of the `` section. +makeExample('toh-5/dart/web/index.html', 'base-href', 'index.html (base href)')(format=".") diff --git a/public/docs/ts/latest/glossary.jade b/public/docs/ts/latest/glossary.jade index e386d0e2cf..f4eb1ee117 100644 --- a/public/docs/ts/latest/glossary.jade +++ b/public/docs/ts/latest/glossary.jade @@ -54,7 +54,7 @@ include _util-fns The barrel itself is a module file that re-exports *selected* exports of other modules. Imagine three modules in a `heroes` folder: - code-example(format=''). + code-example. // heroes/hero.component.ts export class HeroComponent {} @@ -65,26 +65,26 @@ include _util-fns export class HeroService {} :marked Without a barrel, a consumer would need three import statements: - code-example(format=''). + code-example. import { HeroComponent } from '../heroes/hero.component.ts'; import { Hero } from '../heroes/hero.model.ts'; import { HeroService } from '../heroes/hero.service.ts'; :marked We can add a barrel to the `heroes` folder (called `index` by convention) that exports all of these items: - code-example(format=''). + code-example. export * from './hero.model.ts'; // re-export all of its exports export * from './hero.service.ts'; // re-export all of its exports export { HeroComponent } from './hero.component.ts'; // re-export the named thing :marked Now a consumer can import what it needs from the barrel. - code-example(format=''). + code-example. import { Hero, HeroService } from '../heroes'; // index is implied :marked The Angular [scoped packages](#scoped-package) each have a barrel named `index`. // #enddocregion b-c :marked That's why we can write this: -+makeExample('../docs/_fragments/quickstart/ts/app/app.component.ts', 'import')(format=".") ++makeExcerpt('quickstart/ts/app/app.component.ts', 'import', '') // #docregion b-c :marked @@ -584,7 +584,7 @@ include _util-fns The only difference, from a consumer perspective, is that the package name begins with the Angular *scope name*, `@angular`. - +makeExample('../docs/_fragments/architecture/ts/app/app.component.ts', 'import')(format=".") + +makeExcerpt('architecture/ts/app/app.component.ts', 'import', '') // #docregion n-s-2 :marked diff --git a/public/docs/ts/latest/guide/glossary.jade b/public/docs/ts/latest/guide/glossary.jade index a66284569e..ca1429104e 100644 --- a/public/docs/ts/latest/guide/glossary.jade +++ b/public/docs/ts/latest/guide/glossary.jade @@ -1 +1 @@ -!= partial("../glossary") +include ../glossary diff --git a/tools/doc-shredder/processors/shredMapProcessor.js b/tools/doc-shredder/processors/shredMapProcessor.js index 5eb9ac1b24..569ba5511d 100644 --- a/tools/doc-shredder/processors/shredMapProcessor.js +++ b/tools/doc-shredder/processors/shredMapProcessor.js @@ -18,25 +18,37 @@ module.exports = function shredMapProcessor(log, createDocMessage) { var fragToJadeMap = {}; docs.forEach(function(doc) { - var jadePath = path.join(options.jadeDir, doc.fileInfo.relativePath); + var relativePath = doc.fileInfo.relativePath; + var jadePath = path.join(options.jadeDir, relativePath); + var lang = relativePath.substr(0, relativePath.indexOf('\/')); + var appProjDirName = jadeBaseFileNameToExampleName(doc.fileInfo.baseName); var fragInfoSet = {}; doc.fragItems.forEach(function(fragItem) { var mixinPath = fragItem.mixinPath; var fullExamplePath; + // Normalize mixinPath: strip out optional trailing '(...)' + var mixinPath = mixinPath.replace(/ \([^\)]*\)/,''); if ( mixinPath.indexOf('_api') >= 0) { var sourcePath = mixinPath.replace('_api/',''); fullExamplePath = path.join(options.apiExamplesDir, sourcePath); } else { fullExamplePath = path.join(options.devguideExamplesDir, mixinPath); } - var region = fragItem.region ? "-" + fragItem.region : ''; - var extn = path.extname(mixinPath); - var basename = path.basename(mixinPath, extn); - var fragDir = path.dirname(mixinPath); - var fragPath = path.join(fragDir, basename + region + extn) + '.md'; - var fullFragPath = path.join(options.fragmentsDir, fragPath); - - var fragInfo = { fragPath: fullFragPath, examplePath: fullExamplePath, exists: fs.existsSync(fullFragPath) }; + var fragInfo = makeFragInfo(options.fragmentsDir, fullExamplePath, fragItem, mixinPath); + if (!fragInfo.exists) { + var savedFragInfo = fragInfo; + // Assume that mixinPath is actually app-project-folder relative and + // prepend "lang/appProjDirName": + var appProjRelPath = mixinPath; + mixinPath = appProjDirName + '/' + lang + '/' + mixinPath; + fragInfo = makeFragInfo(options.fragmentsDir, fullExamplePath, fragItem, mixinPath); + if (fragInfo.exists) { + log.info('Ajusted example path (' + doc.fileInfo.baseName + '): ' + appProjRelPath + ' -> ' + mixinPath); + } else { + fragInfo = savedFragInfo; + } + } + var fragPath = fragInfo.relFragPath; fragInfoSet[fragPath] = fragInfo; if (fragInfo.exists) { var jadePathsSet = fragToJadeMap[fragPath]; @@ -46,7 +58,7 @@ module.exports = function shredMapProcessor(log, createDocMessage) { } jadePathsSet[jadePath] = jadePath; } else { - var relativePath = path.relative(".", fullFragPath); + var relativePath = path.relative(".", fragInfo.fragPath); log.warn(createDocMessage('Invalid example (unable to locate fragment file: "' + relativePath + '")', doc)); } }); @@ -82,13 +94,24 @@ module.exports = function shredMapProcessor(log, createDocMessage) { } }; -function getExampleName(fragPath) { - // pattern to isolate base fileName and extension from fragment name - var rx = /(.*)\-(.*)\.(.s)/; - var r = rx.exec(fragPath); - if (r) { - return r[1] + '.' + r[3]; - } else { - return fragPath; - } +// TODO: use the functionality in public/resources/js/util.js once it lands. +function jadeBaseFileNameToExampleName(name) { + // Adjust for known cases where chapter name is not the example name. + var matches = name.match(/(toh-)pt(\d+)/); + if (matches) name = matches[1] + matches[2]; + return name; +} + +function makeFragInfo(fragmentsDir, fullExamplePath, fragItem, mixinPath) { + var region = fragItem.region ? "-" + fragItem.region : ''; + var extn = path.extname(mixinPath); + var basename = path.basename(mixinPath, extn); + var fragDir = path.dirname(mixinPath); + var fragPath = path.join(fragDir, basename + region + extn) + '.md'; + var fullFragPath = path.join(fragmentsDir, fragPath); + return { + fragPath: fullFragPath, + relFragPath: fragPath, + examplePath: fullExamplePath, + exists: fs.existsSync(fullFragPath) }; } \ No newline at end of file