From b68ef96472a2154160cd961027d2c12fc5745442 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Fri, 6 Nov 2015 21:40:30 +0000 Subject: [PATCH] api-builder: add target package --- gulpfile.js | 50 ++++++--- package.json | 2 +- tools/api-builder/angular.io-package/index.js | 3 +- tools/api-builder/target-package/index.js | 3 +- .../target-package/inline-tag-defs/target.js | 23 +++- .../inline-tag-defs/target.spec.js | 46 ++++++-- .../target-package/mocks/mockPackage.js | 11 ++ .../services/targetEnvironments.js | 51 +++++++++ .../services/targetEnvironments.spec.js | 105 ++++++++++++++++++ 9 files changed, 263 insertions(+), 31 deletions(-) create mode 100644 tools/api-builder/target-package/mocks/mockPackage.js create mode 100644 tools/api-builder/target-package/services/targetEnvironments.js create mode 100644 tools/api-builder/target-package/services/targetEnvironments.spec.js diff --git a/gulpfile.js b/gulpfile.js index 4e4b9ab71f..a648936759 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -11,6 +11,7 @@ var Q = require("q"); var delPromise = Q.denodeify(del); var Minimatch = require("minimatch").Minimatch; var Dgeni = require('dgeni'); +var Package = require('dgeni').Package; var fsExtra = require('fs-extra'); var fs = fsExtra; var exec = require('child_process').exec; @@ -102,11 +103,14 @@ gulp.task('build-devguide-docs', ['_shred-devguide-examples'], function() { return buildShredMaps(true); }); -gulp.task('build-api-docs', ['_shred-api-examples'], function() { - if (!fs.existsSync(ANGULAR_PROJECT_PATH)) { - throw new Error('build-api-docs task requires the angular2 repo to be at ' + path.resolve(ANGULAR_PROJECT_PATH)); - } - return buildApiDocs(); +gulp.task('build-api-docs', ['build-js-api-docs', 'build-ts-api-docs']); + +gulp.task('build-ts-api-docs', ['_shred-api-examples'], function() { + return buildApiDocs('ts'); +}); + +gulp.task('build-js-api-docs', ['_shred-api-examples'], function() { + return buildApiDocs('js'); }); gulp.task('_shred-devguide-examples', ['_shred-clean-devguide'], function() { @@ -119,6 +123,7 @@ gulp.task('_shred-clean-devguide', function(cb) { }); gulp.task('_shred-api-examples', ['_shred-clean-api'], function() { + checkAngularProjectPath(); return docShredder.shred( _apiShredOptions); }); @@ -232,7 +237,7 @@ function apiSourceWatch(postShredAction) { console.log('Event type: ' + event.event); // added, changed, or deleted console.log('Event path: ' + event.path); // The path of the modified file // need to run just build - buildApiDocs().then(done); + Q.all([buildApiDocs('ts'), buildApiDocs('js')]).then(done); }); var examplesPattern = [path.join(ANGULAR_PROJECT_PATH, 'modules/angular2/examples/**/*.*')]; watch(examplesPattern, function (event, done) { @@ -249,19 +254,34 @@ function apiSourceWatch(postShredAction) { } -function buildApiDocs() { +// Generate the API docs for the specified language, if not specified then it defaults to ts +function buildApiDocs(targetLanguage) { + var ALLOWED_LANGUAGES = ['ts', 'js']; + checkAngularProjectPath(); try { - var dgeni = new Dgeni([require(path.resolve(TOOLS_PATH, 'api-builder/angular.io-package'))]); - return dgeni.generate().then(function() { - // Make a copy of the JS API docs to the TS folder - return gulp.src([path.join(DOCS_PATH, 'js/latest/api/**/*.*'), '!' + path.join(DOCS_PATH, 'js/latest/api/index.jade')]) - .pipe(gulp.dest('./public/docs/ts/latest/api')); + // Build a specialized package to generate different versions of the API docs + var package = new Package('apiDocs', [require(path.resolve(TOOLS_PATH, 'api-builder/angular.io-package'))]); + package.config(function(targetEnvironments, writeFilesProcessor) { + ALLOWED_LANGUAGES.forEach(function(target) { targetEnvironments.addAllowed(target); }); + if (targetLanguage) { + targetEnvironments.activate(targetLanguage); + writeFilesProcessor.outputFolder = targetLanguage + '/latest/api'; + } }); + + var dgeni = new Dgeni([package]); + return dgeni.generate(); } catch(err) { console.log(err); console.log(err.stack); throw err; } + + function copyApiDocsToJsFolder() { + // Make a copy of the JS API docs to the TS folder + return gulp.src([path.join(DOCS_PATH, 'ts/latest/api/**/*.*'), '!' + path.join(DOCS_PATH, 'ts/latest/api/index.jade')]) + .pipe(gulp.dest('./public/docs/js/latest/api')); + } } function devGuideExamplesWatch(shredOptions, postShredAction) { @@ -443,6 +463,10 @@ function execCommands(cmds, options, cb) { }); } - +function checkAngularProjectPath() { + if (!fs.existsSync(ANGULAR_PROJECT_PATH)) { + throw new Error('API related tasks require the angular2 repo to be at ' + path.resolve(ANGULAR_PROJECT_PATH)); + } +} gulp.task('default', ['help']); \ No newline at end of file diff --git a/package.json b/package.json index 71d1e12eaf..eb3acbc979 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "canonical-path": "0.0.2", "del": "^1.2.0", "dgeni": "^0.4.0", - "dgeni-packages": "^0.11.0", + "dgeni-packages": "^0.11.1", "diff": "^2.1.3", "fs-extra": "^0.24.0", "glob": "^5.0.14", diff --git a/tools/api-builder/angular.io-package/index.js b/tools/api-builder/angular.io-package/index.js index bed1bfa0fc..f3f61d23c4 100644 --- a/tools/api-builder/angular.io-package/index.js +++ b/tools/api-builder/angular.io-package/index.js @@ -1,12 +1,13 @@ var path = require('canonical-path'); var Package = require('dgeni').Package; var basePackage = require('../docs-package'); +var targetPackage = require('../target-package'); var PROJECT_PATH = path.resolve(__dirname, "../../.."); var PUBLIC_PATH = path.resolve(PROJECT_PATH, 'public'); var DOCS_PATH = path.resolve(PUBLIC_PATH, 'docs'); -module.exports = new Package('angular.io', [basePackage]) +module.exports = new Package('angular.io', [basePackage, targetPackage]) .factory(require('./services/renderMarkdown')) .processor(require('./processors/addJadeDataDocsProcessor')) diff --git a/tools/api-builder/target-package/index.js b/tools/api-builder/target-package/index.js index 28230d8c07..2dfbcf3efd 100644 --- a/tools/api-builder/target-package/index.js +++ b/tools/api-builder/target-package/index.js @@ -1,7 +1,8 @@ var Package = require('dgeni').Package; -module.exports = new Package('target', []) +module.exports = new Package('target', [require('dgeni-packages/jsdoc')]) +.factory(require('./services/targetEnvironments')) .factory(require('./inline-tag-defs/target')) .config(function(inlineTagProcessor, targetInlineTagDef) { diff --git a/tools/api-builder/target-package/inline-tag-defs/target.js b/tools/api-builder/target-package/inline-tag-defs/target.js index 99c74ee7ed..32428c391b 100644 --- a/tools/api-builder/target-package/inline-tag-defs/target.js +++ b/tools/api-builder/target-package/inline-tag-defs/target.js @@ -5,19 +5,30 @@ var _ = require('lodash'); * @description * Process inline `target` block tags * (of the form `{@target environment1 environment2}...{@endtarget}`), - * filtering out the blocks that do not match the containing document's - * `targetEnvironments`. + * filtering out the blocks that do not match the active `targetEnvironments`. */ -module.exports = function targetInlineTagDef() { +module.exports = function targetInlineTagDef(targetEnvironments, log, createDocMessage) { return { name: 'target', end: 'endtarget', handler: function(doc, tagName, tagDescription) { var targets = tagDescription && tagDescription.tag.split(' '); - if (!targets || !doc.targetEnvironments || - _.intersection(targets, doc.targetEnvironments).length) { - return tagDescription.content; + var hasTargets = targets && targets.length; + + try { + // Return the contents of this block if any of the following is true: + // * it has no targets + // * there are no targets stored in the targetEnvironments service + // * the block's targets overlap with the active targets in the targetEnvironments service + if (!hasTargets || !targetEnvironments.hasActive() || targetEnvironments.someActive(targets)) + { + return tagDescription.content; + } + } catch(x) { + log.error(createDocMessage('Error processing target inline tag def - ' + x.message, doc)); } + + // Otherwise return an empty string return ''; } }; diff --git a/tools/api-builder/target-package/inline-tag-defs/target.spec.js b/tools/api-builder/target-package/inline-tag-defs/target.spec.js index 115665218b..66de233949 100644 --- a/tools/api-builder/target-package/inline-tag-defs/target.spec.js +++ b/tools/api-builder/target-package/inline-tag-defs/target.spec.js @@ -1,24 +1,52 @@ -var targetFactory = require('./target'); +var mockPackage = require('../mocks/mockPackage'); +var Dgeni = require('dgeni'); describe('target inline-tag-def', function() { - it('should filter out content that does not match the doc.targetEnvironments', function() { - var doc, target, result; + var dgeni, injector, targetInlineTagDef; - doc = { - targetEnvironments: ['js', 'es6'] - }; + beforeEach(function() { + dgeni = new Dgeni([mockPackage()]); + injector = dgeni.configureInjector(); + targetInlineTagDef = injector.get('targetInlineTagDef'); + }); - target = targetFactory(); - result = target.handler(doc, 'target', { + + it('should filter out content that does not match the targetEnvironments', function() { + + var doc = {}; + + var targetEnvironments = injector.get('targetEnvironments'); + targetEnvironments.addAllowed('js', true); + targetEnvironments.addAllowed('es6', true); + targetEnvironments.addAllowed('ts', false); + + var result = targetInlineTagDef.handler(doc, 'target', { tag: 'es6 ts', content: 'abc' }); expect(result).toEqual('abc'); - result = target.handler(doc, 'target', { + result = targetInlineTagDef.handler(doc, 'target', { tag: 'ts', content: 'xyz' }); expect(result).toEqual(''); }); + + + it('should not filter anything if there are no doc nor global target environments', function() { + var doc = {}; + + var result = targetInlineTagDef.handler(doc, 'target', { + tag: 'es6 ts', + content: 'abc' + }); + expect(result).toEqual('abc'); + + result = targetInlineTagDef.handler(doc, 'target', { + tag: 'ts', + content: 'xyz' + }); + expect(result).toEqual('xyz'); + }); }); \ No newline at end of file diff --git a/tools/api-builder/target-package/mocks/mockPackage.js b/tools/api-builder/target-package/mocks/mockPackage.js new file mode 100644 index 0000000000..834d53c959 --- /dev/null +++ b/tools/api-builder/target-package/mocks/mockPackage.js @@ -0,0 +1,11 @@ +var Package = require('dgeni').Package; + +module.exports = function mockPackage() { + + return new Package('mockPackage', [require('../')]) + + // provide a mock log service + .factory('log', function() { return require('dgeni/lib/mocks/log')(false); }) + .factory('templateEngine', function() { return {}; }); + +}; diff --git a/tools/api-builder/target-package/services/targetEnvironments.js b/tools/api-builder/target-package/services/targetEnvironments.js new file mode 100644 index 0000000000..eda914271d --- /dev/null +++ b/tools/api-builder/target-package/services/targetEnvironments.js @@ -0,0 +1,51 @@ +module.exports = function targetEnvironments() { + var _targets = Object.create(null); + var _activeCount = 0; + + var checkAllowed = function(target) { + if (!(target in _targets)) { + throw new Error('Error accessing target "' + target + '". It is not in the list of allowed targets: ' + Object.keys(_targets)); + } + }; + + var updateActiveCount = function() { + _activeCount = 0; + for(target in _targets) { + if (_targets[target]) _activeCount++; + } + }; + + return { + addAllowed: function(target, isActive) { + _targets[target] = !!isActive; + updateActiveCount(); + }, + removeAllowed: function(target) { + delete _targets[target]; + updateActiveCount(); + }, + activate: function(target) { + checkAllowed(target); + _targets[target] = true; + updateActiveCount(); + }, + deactivate: function(target) { + checkAllowed(target); + _targets[target] = false; + updateActiveCount(); + }, + isActive: function(target) { + checkAllowed(target); + return _targets[target]; + }, + hasActive: function() { + return _activeCount > 0; + }, + someActive: function(targets) { + for(var i=0,ii=targets.length; i