2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @license
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Copyright Google Inc. 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
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * **Usage:**
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * ```
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * node tools/verify-codeownership
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * ```
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Verify whether there are directories in the codebase that don't have a codeowner (in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * `.github/CODEOWNERS`) and vice versa (that there are no patterns in `CODEOWNERS` that do not
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * correspond to actual directories).
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * The script does not aim to be exhaustive and highly accurate, checking all files and directories
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * (since that would be too complicated). Instead, it does a coarse check on some important (or
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * frequently changing) directories.
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Currently, it checks the following:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * - **Packages**: Top-level directories in `packages/`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * - **API docs examples**: Top-level directories in `packages/examples/`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * - **Guides**: Top-level files in `aio/content/guide/`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * - **Guide images**: Top-level directories in `aio/content/images/guide/`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * - **Guide examples**: Top-level directories in `aio/content/examples/`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								'use strict';
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Imports
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const chalk = require('chalk');
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const fs = require('fs');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const path = require('path');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Constants
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const PROJECT_ROOT_DIR = path.resolve(__dirname, '..');
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const CODEOWNERS_PATH = path.resolve(PROJECT_ROOT_DIR, '.github/CODEOWNERS');
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const PKG_DIR = path.resolve(PROJECT_ROOT_DIR, 'packages');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const PKG_EXAMPLES_DIR = path.resolve(PKG_DIR, 'examples');
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								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');
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const IGNORED_PKG_DIRS = new Set([
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Examples are checked separately.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  'examples',
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								]);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Run
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								_main();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Functions - Definitions
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								function _main() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const {packages: pkgPackagePaths, examples: pkgExamplePaths} = getPathsFromPkg();
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    guides: aioGuidePaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    images: aioGuideImagesPaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    examples: aioExamplePaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  } = getPathsFromAioContent();
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    pkgPackages: coPkgPackagePaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pkgExamples: coPkgExamplePaths,
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    aioGuides: coAioGuidePaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    aioImages: coAioGuideImagesPaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    aioExamples: coAioExamplePaths,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  } = getPathsFromCodeowners();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const pkgPackagesDiff = arrayDiff(pkgPackagePaths, coPkgPackagePaths);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const pkgExamplesDiff = arrayDiff(pkgExamplePaths, coPkgExamplePaths);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioGuidesDiff = arrayDiff(aioGuidePaths, coAioGuidePaths);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioImagesDiff = arrayDiff(aioGuideImagesPaths, coAioGuideImagesPaths);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioExamplesDiff = arrayDiff(aioExamplePaths, coAioExamplePaths);
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const hasDiff = (pkgPackagesDiff.diffCount > 0) || (pkgExamplesDiff.diffCount > 0) ||
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      (aioGuidesDiff.diffCount > 0) || (aioImagesDiff.diffCount > 0) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      (aioExamplesDiff.diffCount > 0);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (hasDiff) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    const expectedPkgPackagesSrc = path.relative(PROJECT_ROOT_DIR, PKG_DIR);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const expectedPkgExamplesSrc = path.relative(PROJECT_ROOT_DIR, PKG_EXAMPLES_DIR);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const expectedAioGuidesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDES_DIR);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const expectedAioImagesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDE_IMAGES_DIR);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const expectedAioExamplesSrc = path.relative(PROJECT_ROOT_DIR, AIO_GUIDE_EXAMPLES_DIR);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const actualSrc = path.relative(PROJECT_ROOT_DIR, CODEOWNERS_PATH);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    reportDiff(pkgPackagesDiff, expectedPkgPackagesSrc, actualSrc);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    reportDiff(pkgExamplesDiff, expectedPkgExamplesSrc, actualSrc);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    reportDiff(aioGuidesDiff, expectedAioGuidesSrc, actualSrc);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    reportDiff(aioImagesDiff, expectedAioImagesSrc, actualSrc);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    reportDiff(aioExamplesDiff, expectedAioExamplesSrc, actualSrc);
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // tslint:disable-next-line: no-console
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    console.log(chalk.red(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        '\nCode-ownership verification failed.\n' +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        'Please update \'.github/CODEOWNERS\' to ensure that all necessary files/directories ' +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        'have code-owners and all patterns that appear in the file correspond to actual ' +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        'files/directories in the repo.'));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // tslint:disable-next-line: no-console
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    console.log(chalk.green('\nCode-ownership verification succeeded!'));
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  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};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								function findDirectories(parentDir) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  return fs.readdirSync(parentDir).filter(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      name => fs.statSync(`${parentDir}/${name}`).isDirectory());
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								function getPathsFromAioContent() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    guides: fs.readdirSync(AIO_GUIDES_DIR),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    images: fs.readdirSync(AIO_GUIDE_IMAGES_DIR),
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    examples: fs.readdirSync(AIO_GUIDE_EXAMPLES_DIR)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                  .filter(name => fs.statSync(`${AIO_GUIDE_EXAMPLES_DIR}/${name}`).isDirectory()),
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								function getPathsFromCodeowners() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const pkgPackagesPathRe = /^\/packages\/([^\s\*/]+)\/\*?\*\s/;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const pkgExamplesPathRe = /^\/packages\/examples\/([^\s\*/]+)/;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Use capturing groups for `images/` and `examples` to be able to differentiate between the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // different kinds of matches (guide, image, example) later (see `isImage`/`isExample` below).
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const aioGuidesImagesExamplesPathRe =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      /^\/aio\/content\/(?:(images\/)?guide|(examples))\/([^\s\*/]+)/;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 10:13:57 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const manualGlobExpansions = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // `CODEOWNERS` has a glob to match all `testing/` directories, so no specific glob for
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // `packages/examples/testing/` is necessary.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    'testing/**': ['/packages/examples/testing/**'],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  };
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const pkgPackages = [];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const pkgExamples = [];
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioGuides = [];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioImages = [];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aioExamples = [];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Read `CODEOWNERS` and split into lines.
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const lines = fs.readFileSync(CODEOWNERS_PATH, 'utf8').split('\n').map(l => l.trim());
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 10:13:57 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  // Manually expand globs to known matching patterns.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  for (const [glob, expansions] of Object.entries(manualGlobExpansions)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const matchingLine = lines.find(l => l.startsWith(`${glob} `));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (matchingLine !== undefined) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      lines.push(...expansions);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  // Collect packages (`packages/`).
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  lines.map(l => l.match(pkgPackagesPathRe)).filter(m => m).forEach(([
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                                      , path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                                    ]) => pkgPackages.push(path));
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Collect API docs examples (`packages/examples/`).
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  lines.map(l => l.match(pkgExamplesPathRe)).filter(m => m).forEach(([
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                                      , path
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                                    ]) => pkgExamples.push(path));
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Collect `aio/` guides/images/examples.
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:56:38 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  lines.map(l => l.match(aioGuidesImagesExamplesPathRe))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      .filter(m => m)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      .forEach(([, isImage, isExample, path]) => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        const list = isExample ? aioExamples : isImage ? aioImages : aioGuides;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        list.push(path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      });
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  return {pkgPackages, pkgExamples, aioGuides, aioImages, aioExamples};
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								function getPathsFromPkg() {
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return {
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-10 13:47:36 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    packages: findDirectories(PKG_DIR).filter(name => !IGNORED_PKG_DIRS.has(name)),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    examples: findDirectories(PKG_EXAMPLES_DIR),
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-28 00:39:13 +03:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								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'));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |