Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 92 additions & 12 deletions .github/CODEOWNERS

Large diffs are not rendered by default.

30 changes: 0 additions & 30 deletions aio/content/examples/property-binding/src/app/app.component.ts

This file was deleted.

2 changes: 1 addition & 1 deletion aio/content/guide/template-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ The following event binding listens for the button's click events, calling
the component's `onSave()` method whenever a click occurs:

<figure>
<img src='generated/images/guide/event-binding/syntax-diagram.svg' alt="Syntax diagram">
<img src='generated/images/guide/template-syntax/syntax-diagram.svg' alt="Syntax diagram">
</figure>

### Target event
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed aio/content/images/guide/intro/people.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed aio/content/images/guide/ngmodule/final-plunker.png
Binary file not shown.
Binary file not shown.
Binary file removed aio/content/images/guide/ngmodule/v3-plunker.png
Binary file not shown.
Binary file not shown.
Binary file removed aio/content/images/guide/quickstart/my-first-app.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Binary file removed aio/content/images/guide/unit-testing/spectrum.png
Diff not rendered.
87 changes: 87 additions & 0 deletions aio/scripts/verify-guide-codeownership.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use strict';

// Imports
const fs = require('fs');
const path = require('path');

// Constants
const PROJECT_ROOT_DIR = path.resolve(__dirname, '../..');
const CODEOWNERS_PATH = path.resolve(PROJECT_ROOT_DIR, '.github/CODEOWNERS');
const AIO_CONTENT_DIR = path.resolve(PROJECT_ROOT_DIR, 'aio/content');
const AIO_GUIDES_DIR = path.resolve(AIO_CONTENT_DIR, 'guide');
const AIO_GUIDE_IMAGES_DIR = path.resolve(AIO_CONTENT_DIR, 'images/guide');
const AIO_GUIDE_EXAMPLES_DIR = path.resolve(AIO_CONTENT_DIR, 'examples');

// Run
_main();

// Functions - Definitions
function _main() {
const {guides: acGuidePaths, images: acGuideImagesPaths, examples: acExamplePaths} = getPathsFromAioContent();
const {guides: coGuidePaths, images: coGuideImagesPaths, examples: coExamplePaths} = getPathsFromCodeowners();

const guidesDiff = arrayDiff(acGuidePaths, coGuidePaths);
const imagesDiff = arrayDiff(acGuideImagesPaths, coGuideImagesPaths);
const examplesDiff = arrayDiff(acExamplePaths, coExamplePaths);
const hasDiff = !!(guidesDiff.diffCount || imagesDiff.diffCount || examplesDiff.diffCount);

if (hasDiff) {
const expectedGuidesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDES_DIR);
const expectedImagesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDE_IMAGES_DIR);
const expectedExamplesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDE_EXAMPLES_DIR);
const actualSrc = path.relative(PROJECT_ROOT_DIR, CODEOWNERS_PATH);

reportDiff(guidesDiff, expectedGuidesSrc, actualSrc);
reportDiff(imagesDiff, expectedImagesSrc, actualSrc);
reportDiff(examplesDiff, expectedExamplesSrc, actualSrc);
}

process.exit(hasDiff ? 1 : 0);
}

function arrayDiff(expected, actual) {
const missing = expected.filter(x => !actual.includes(x)).sort();
const extra = actual.filter(x => !expected.includes(x)).sort();

return {missing, extra, diffCount: missing.length + extra.length};
}

function getPathsFromAioContent() {
return {
guides: fs.readdirSync(AIO_GUIDES_DIR),
images: fs.readdirSync(AIO_GUIDE_IMAGES_DIR),
examples: fs.readdirSync(AIO_GUIDE_EXAMPLES_DIR).
filter(name => fs.statSync(`${AIO_GUIDE_EXAMPLES_DIR}/${name}`).isDirectory()),
};
}

function getPathsFromCodeowners() {
const guidesOrImagesPathRe = /^\/aio\/content\/(?:(images\/)?guide|(examples))\/([^\s/]+)/;

return fs.
readFileSync(CODEOWNERS_PATH, 'utf8').
split('\n').
map(l => l.trim().match(guidesOrImagesPathRe)).
filter(m => m).
reduce((aggr, [, isImage, isExample, path]) => {
const list = isExample ? aggr.examples :
isImage ? aggr.images :
aggr.guides;
list.push(path);
return aggr;
}, {guides: [], images: [], examples: []});
}

function reportDiff(diff, expectedSrc, actualSrc) {
if (diff.missing.length) {
console.error(
`\nEntries in '${expectedSrc}' but not in '${actualSrc}':\n` +
diff.missing.map(x => ` - ${x}`).join('\n'));
}

if (diff.extra.length) {
console.error(
`\nEntries in '${actualSrc}' but not in '${expectedSrc}':\n` +
diff.extra.map(x => ` - ${x}`).join('\n'));
}
}