Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 1bef20a

Browse files
chalinkwalrath
authored andcommitted
docs(api/dart): add support for generation and display (#1888)
Fixes #1880. Supersedes #1593.
1 parent 08d051d commit 1bef20a

File tree

19 files changed

+737
-28
lines changed

19 files changed

+737
-28
lines changed

.travis.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ env:
1515
- TASK=lint
1616
- TASK="run-e2e-tests --fast" SCRIPT=examples-install.sh
1717
- TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh
18-
- TASK=harp-compile SCRIPT=deploy-install.sh
19-
- TASK=harp-compile SCRIPT=deploy-install-preview.sh
18+
- TASK=build-compile SCRIPT=deploy-install.sh
19+
- TASK=build-compile SCRIPT=deploy-install-preview.sh
2020
matrix:
2121
fast_finish: true
2222
allow_failures:
2323
- env: "TASK=\"run-e2e-tests --fast\" SCRIPT=examples-install-preview.sh"
24-
- env: "TASK=harp-compile SCRIPT=deploy-install-preview.sh"
24+
- env: "TASK=build-compile SCRIPT=deploy-install-preview.sh"
2525
before_install:
2626
- npm install -g gulp --no-optional
2727
install:

gulpfile.js

+138-12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var tslint = require('gulp-tslint');
3030
// 2. Think about using spawn instead of exec in case of long error messages.
3131

3232
var TOOLS_PATH = './tools';
33+
var ANGULAR_IO_PROJECT_PATH = path.resolve('.');
3334
var ANGULAR_PROJECT_PATH = '../angular';
3435
var PUBLIC_PATH = './public';
3536
var TEMP_PATH = './_temp';
@@ -63,12 +64,21 @@ var _devguideShredJadeOptions = {
6364
};
6465

6566
var _apiShredOptions = {
67+
lang: 'ts',
6668
examplesDir: path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/examples'),
6769
fragmentsDir: path.join(DOCS_PATH, '_fragments/_api'),
6870
zipDir: path.join(RESOURCES_PATH, 'zips/api'),
6971
logLevel: _dgeniLogLevel
7072
};
7173

74+
var _apiShredOptionsForDart = {
75+
lang: 'dart',
76+
examplesDir: path.resolve(ngPathFor('dart'), 'examples'),
77+
fragmentsDir: path.join(DOCS_PATH, '_fragments/_api'),
78+
zipDir: path.join(RESOURCES_PATH, 'zips/api'),
79+
logLevel: _dgeniLogLevel
80+
};
81+
7282
var _excludePatterns = ['**/node_modules/**', '**/typings/**', '**/packages/**'];
7383

7484
var _excludeMatchers = _excludePatterns.map(function(excludePattern){
@@ -96,6 +106,14 @@ var _exampleProtractorBoilerplateFiles = [
96106

97107
var _exampleConfigFilename = 'example-config.json';
98108

109+
var lang, langs;
110+
function configLangs(langOption) {
111+
lang = (langOption || 'all').toLowerCase();
112+
if (lang === 'all') { lang = '(ts|js|dart)'; }
113+
langs = lang.match(/\w+/g); // the languages in `lang` as an array
114+
}
115+
configLangs(argv.lang);
116+
99117
function isDartPath(path) {
100118
// Testing via indexOf() for now. If we need to match only paths with folders
101119
// named 'dart' vs 'dart*' then try: path.match('/dart(/|$)') != null;
@@ -131,6 +149,7 @@ gulp.task('run-e2e-tests', runE2e);
131149
* all means (ts|js|dart)
132150
*/
133151
function runE2e() {
152+
if (!argv.lang) configLangs('ts|js'); // Exclude dart by default
134153
var promise;
135154
if (argv.fast) {
136155
// fast; skip all setup
@@ -183,8 +202,6 @@ function runE2e() {
183202
// each app/spec collection sequentially.
184203
function findAndRunE2eTests(filter, outputFile) {
185204
// create an output file with header.
186-
var lang = (argv.lang || '(ts|js)').toLowerCase();
187-
if (lang === 'all') { lang = '(ts|js|dart)'; }
188205
var startTime = new Date().getTime();
189206
var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`;
190207
header += argv.fast ?
@@ -528,7 +545,9 @@ gulp.task('build-docs', ['build-devguide-docs', 'build-api-docs', 'build-plunker
528545
// Stop zipping examples Feb 28, 2016
529546
//gulp.task('build-docs', ['build-devguide-docs', 'build-api-docs', 'build-plunkers', '_zip-examples']);
530547

531-
gulp.task('build-api-docs', ['build-js-api-docs', 'build-ts-api-docs', 'build-dart-cheatsheet']);
548+
gulp.task('build-api-docs', ['build-js-api-docs', 'build-ts-api-docs',
549+
// On TRAVIS? Skip building the Dart API docs for now.
550+
...(process.env.TRAVIS ? [] : ['build-dart-api-docs'])]);
532551

533552
gulp.task('build-devguide-docs', ['_shred-devguide-examples', '_shred-devguide-shared-jade'], function() {
534553
return buildShredMaps(true);
@@ -542,12 +561,40 @@ gulp.task('build-js-api-docs', ['_shred-api-examples'], function() {
542561
return buildApiDocs('js');
543562
});
544563

564+
gulp.task('build-dart-api-docs', ['_shred-api-examples', 'dartdoc'], function() {
565+
// TODO(chalin): also build build-dart-cheatsheet
566+
return buildApiDocsForDart();
567+
});
568+
545569
gulp.task('build-plunkers', ['_copy-example-boilerplate'], function() {
546570
return plunkerBuilder.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log });
547571
});
548572

549573
gulp.task('build-dart-cheatsheet', [], function() {
550-
return buildApiDocs('dart');
574+
gutil.log('build-dart-cheatsheet - NOT IMPLEMENTED YET');
575+
// return buildApiDocsForDart();
576+
});
577+
578+
gulp.task('dartdoc', ['pub upgrade'], function() {
579+
const ngRepoPath = ngPathFor('dart');
580+
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'doc'))) {
581+
gutil.log('Skipping dartdoc: --fast flag enabled and "doc" dir exists');
582+
return true;
583+
}
584+
checkAngularProjectPath(ngRepoPath);
585+
const dartdoc = spawnExt('dartdoc', ['--output', 'doc/api', '--add-crossdart'], { cwd: ngRepoPath});
586+
return dartdoc.promise;
587+
});
588+
589+
gulp.task('pub upgrade', [], function() {
590+
const ngRepoPath = ngPathFor('dart');
591+
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'packages'))) {
592+
gutil.log('Skipping pub upgrade: --fast flag enabled and "packages" dir exists');
593+
return true;
594+
}
595+
checkAngularProjectPath(ngRepoPath);
596+
const pubUpgrade = spawnExt('pub', ['upgrade'], { cwd: ngRepoPath});
597+
return pubUpgrade.promise;
551598
});
552599

553600
gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){
@@ -596,10 +643,35 @@ gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){
596643
});
597644
});
598645

599-
gulp.task('harp-compile', ['build-docs'], function() {
646+
gulp.task('harp-compile', [], function() {
647+
return harpCompile()
648+
});
649+
650+
gulp.task('serve', [], function() {
651+
// Harp will serve files from workspace.
652+
const cmd = 'npm run harp -- server .';
653+
gutil.log('Launching harp server (over project files)');
654+
gutil.log(` > ${cmd}`);
655+
gutil.log('Note: issuing this command directly from the command line will show harp comiple warnings.');
656+
return execPromise(cmd);
657+
});
658+
659+
gulp.task('serve-www', [], function() {
660+
// Serve generated site.
661+
return execPromise('npm run live-server ./www');
662+
});
663+
664+
gulp.task('build-compile', ['build-docs'], function() {
600665
return harpCompile();
601666
});
602667

668+
gulp.task('check-serve', ['build-docs'], function() {
669+
return harpCompile().then(function() {
670+
gutil.log('Launching live-server over ./www');
671+
return execPromise('npm run live-server ./www');
672+
});
673+
});
674+
603675
gulp.task('check-deploy', ['build-docs'], function() {
604676
return harpCompile().then(function() {
605677
gutil.log('compile ok');
@@ -693,8 +765,15 @@ gulp.task('_shred-clean-devguide', function(cb) {
693765
});
694766

695767
gulp.task('_shred-api-examples', ['_shred-clean-api'], function() {
696-
checkAngularProjectPath();
697-
return docShredder.shred(_apiShredOptions);
768+
const promises = [];
769+
gutil.log('Shredding API examples for languages: ' + langs.join(', '));
770+
langs.forEach((lang) => {
771+
if (lang === 'js') return; // JS is handled via TS.
772+
checkAngularProjectPath(ngPathFor(lang));
773+
const options = lang == 'dart' ? _apiShredOptionsForDart : _apiShredOptions;
774+
promises.push(docShredder.shred(options));
775+
});
776+
return Q.all(promises);
698777
});
699778

700779
gulp.task('_shred-clean-api', function(cb) {
@@ -1087,8 +1166,8 @@ function buildApiDocs(targetLanguage) {
10871166
var dgeni = new Dgeni([package]);
10881167
return dgeni.generate();
10891168
} catch(err) {
1090-
gutil.log(err);
1091-
gutil.log(err.stack);
1169+
console.error(err);
1170+
console.error(err.stack);
10921171
throw err;
10931172
}
10941173

@@ -1099,6 +1178,48 @@ function buildApiDocs(targetLanguage) {
10991178
}
11001179
}
11011180

1181+
1182+
function buildApiDocsForDart() {
1183+
const apiDir = 'api';
1184+
const vers = 'latest';
1185+
const dab = require('./tools/dart-api-builder/dab')(ANGULAR_IO_PROJECT_PATH);
1186+
const log = dab.log;
1187+
1188+
log.level = _dgeniLogLevel;
1189+
const dabInfo = dab.dartPkgConfigInfo;
1190+
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, apiDir);
1191+
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'doc', apiDir);
1192+
// Exclude API entries for developer/internal libraries. Also exclude entries for
1193+
// the top-level catch all "angular2" library (otherwise every entry appears twice).
1194+
dabInfo.excludeLibRegExp = new RegExp(/^(?!angular2)|\.testing|_|codegen|^angular2$/);
1195+
1196+
try {
1197+
checkAngularProjectPath('dart');
1198+
var destPath = dabInfo.ngIoDartApiDocPath;
1199+
var sourceDirs = fs.readdirSync(dabInfo.ngDartDocPath)
1200+
.filter((name) => !name.match(/^index/))
1201+
.map((name) => path.join(dabInfo.ngDartDocPath, name));
1202+
log.info(`Building Dart API pages for ${sourceDirs.length} libraries`);
1203+
1204+
return copyFiles(sourceDirs, [destPath]).then(() => {
1205+
log.debug('Finished copying', sourceDirs.length, 'directories from', dabInfo.ngDartDocPath, 'to', destPath);
1206+
1207+
const apiEntries = dab.loadApiDataAndSaveToApiListFile();
1208+
const tmpDocsPath = path.resolve(path.join(process.env.HOME, 'tmp/docs.json'));
1209+
if (argv.dumpDocsJson) fs.writeFileSync(tmpDocsPath, JSON.stringify(apiEntries, null, 2));
1210+
dab.createApiDataAndJadeFiles(apiEntries);
1211+
1212+
}).catch((err) => {
1213+
console.log(err);
1214+
});
1215+
1216+
} catch(err) {
1217+
console.error(err);
1218+
console.error(err.stack);
1219+
throw err;
1220+
}
1221+
}
1222+
11021223
function buildShredMaps(shouldWrite) {
11031224
var options = {
11041225
devguideExamplesDir: _devguideShredOptions.examplesDir,
@@ -1270,8 +1391,13 @@ function execCommands(cmds, options, cb) {
12701391
});
12711392
}
12721393

1273-
function checkAngularProjectPath() {
1274-
if (!fs.existsSync(ANGULAR_PROJECT_PATH)) {
1275-
throw new Error('API related tasks require the angular2 repo to be at ' + path.resolve(ANGULAR_PROJECT_PATH));
1394+
function ngPathFor(lang) {
1395+
return ANGULAR_PROJECT_PATH + (lang === 'dart' ? '-dart' : '');
1396+
}
1397+
1398+
function checkAngularProjectPath(lang) {
1399+
var ngPath = path.resolve(ngPathFor(lang || 'ts'));
1400+
if (!fs.existsSync(ngPath)) {
1401+
throw new Error('API related tasks require the angular2 repo to be at ' + ngPath);
12761402
}
12771403
}

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"broken-link-checker": "0.7.1",
3131
"browser-sync": "^2.9.3",
3232
"canonical-path": "0.0.2",
33+
"cheerio": "^0.20.0",
3334
"cross-spawn": "^4.0.0",
3435
"codelyzer": "0.0.22",
3536
"del": "^2.2.0",

public/_includes/_hero.jade

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
// Refer to jade.template.html and addJadeDataDocsProcessor to figure out where the context of this jade file originates
1+
// template: public/_includes/_hero
2+
//- Refer to jade.template.html and addJadeDataDocsProcessor to figure out where the context of this jade file originates
23
- var textFormat = '';
34
- var headerTitle = title + (typeof varType !== 'undefined' ? (': ' + varType) : '');
45
- var capitalize = function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); }
56
- var useBadges = docType || stability;
6-
7-
// renamer :: String -> String
8-
// Renames `Let` and `Var` into `Const`
7+
//- renamer :: String -> String
8+
//- Renames `Let` and `Var` into `Const`
99
- var renamer = function renamer(docType) {
1010
- return (docType === 'Let' || docType === 'Var') ? 'Const' : docType
1111
- }
1212

1313
if current.path[4] && current.path[3] == 'api'
1414
- var textFormat = 'is-standard-case'
1515

16-
header(class="hero background-sky")
16+
header(class="hero background-sky", style=fixHeroCss ? "height:auto" : "")
1717
div(class="inner-header")
1818
h1(class="hero-title text-display-1 #{textFormat}") #{headerTitle}
1919
if useBadges
@@ -33,5 +33,7 @@ header(class="hero background-sky")
3333
if subtitle
3434
h2.hero-subtitle.text-subhead #{subtitle}
3535

36+
else if current.path[3] == 'api' && current.path[1] == 'dart'
37+
block breadcrumbs
3638
else if current.path[0] == "docs"
3739
!= partial("_version-dropdown")

public/docs/_layout-dart-api.jade

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//- WARNING: _layout.jade and _layout-dart-api.jade should match in terms of content
2+
//- except that one uses Harp partial/yield and the other uses Jade extends/include.
3+
doctype
4+
html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework")
5+
// template: public/docs/_layout-dart-api
6+
head
7+
include ../_includes/_head-include
8+
block head-extra
9+
10+
block var-def
11+
body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl as appCtrl")
12+
include ../_includes/_main-nav
13+
if current.path[2]
14+
include _includes/_side-nav
15+
include ../_includes/_hero
16+
include ../_includes/_banner
17+
18+
if current.path[3] == 'api'
19+
if current.path[4] == 'index'
20+
block main-content
21+
else
22+
article(class="l-content-small grid-fluid docs-content")
23+
block main-content
24+
else if current.path.indexOf('cheatsheet') > 0
25+
block main-content
26+
else
27+
if current.path[3] == 'index' || current.path[3] == 'styleguide'
28+
article(class="l-content-small grid-fluid docs-content")
29+
block main-content
30+
else
31+
article(class="l-content-small grid-fluid docs-content")
32+
div(class="c10")
33+
.showcase
34+
.showcase-content
35+
block main-content
36+
if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4]
37+
include ../_includes/_next-item
38+
39+
include ../_includes/_footer
40+
include ../_includes/_scripts-include

public/docs/_layout.jade

+5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
//- WARNING: _layout.jade and _layout-dart-api.jade should match in terms of content
2+
//- except that one uses Harp partial/yield and the other uses Jade extends/include.
13
doctype
24
html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework")
5+
// template: public/docs/_layout
36
head
47
!= partial("../_includes/_head-include")
8+
block head-extra
59

10+
//-
611
body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl as appCtrl")
712
!= partial("../_includes/_main-nav")
813
if current.path[2]
+11-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
.l-main-section
2-
h2 Beta
1+
:marked
2+
> **WARNING:** API documentation is preliminary and subject to change.
33

4-
p.
5-
The proposed Angular 2 API does not yet have Dart-specific documentation.
6-
However, because the Dart and JavaScript APIs are generated from the same source,
7-
you might find the JavaScript API docs helpful:
4+
> **Known issues:** Although this generated API reference displays Dart
5+
APIs, individual pages sometimes describe TypeScript APIs accompanied with
6+
TypeScript code. The angular.io issue tracker contains [all known
7+
issues][api-issues]; if you notice others, please [report
8+
them][new-issue]. Thanks!
89

9-
p.text-center
10-
<b><a href="/docs/js/latest/api/">Angular 2 API Preview (JavaScript)</a></b>
10+
[new-issue]: https://github.com/angular/angular.io/issues/new?labels=dart,api&title=%5BDart%5D%5BAPI%5D%20
11+
[api-issues]: https://github.com/angular/angular.io/issues?q=label%3Aapi+label%3Adart
12+
13+
api-list(src="api-list.json" lang="dart")

0 commit comments

Comments
 (0)