ipsos-components
Version:
Material Design components for Angular
86 lines (68 loc) • 3.47 kB
text/typescript
import {task} from 'gulp';
import {readFileSync, existsSync} from 'fs';
import {join} from 'path';
import {green, red} from 'chalk';
import {releasePackages} from './publish';
import {sync as glob} from 'glob';
import {buildConfig, sequenceTask} from 'material2-build-tools';
/** Path to the directory where all releases are created. */
const releasesDir = join(buildConfig.outputDir, 'releases');
/** RegExp that matches Angular component inline styles that contain a sourcemap reference. */
const inlineStylesSourcemapRegex = /styles: ?\[["'].*sourceMappingURL=.*["']/;
/** RegExp that matches Angular component metadata properties that refer to external resources. */
const externalReferencesRegex = /(templateUrl|styleUrls): *["'[]/;
task('validate-release', sequenceTask(':publish:build-releases', 'validate-release:check-bundles'));
/** Task that checks the release bundles for any common mistakes before releasing to the public. */
task('validate-release:check-bundles', () => {
const releaseFailures = releasePackages
.map(packageName => checkReleasePackage(packageName))
.map((failures, index) => ({failures, packageName: releasePackages[index]}));
releaseFailures.forEach(({failures, packageName}) => {
failures.forEach(failure => console.error(red(`Failure (${packageName}): ${failure}`)));
});
if (releaseFailures.some(({failures}) => failures.length > 0)) {
// Throw an error to notify Gulp about the failures that have been detected.
throw 'Release output is not valid and not ready for being released.';
} else {
console.log(green('Release output has been checked and everything looks fine.'));
}
});
/** Task that validates the given release package before releasing. */
function checkReleasePackage(packageName: string): string[] {
return glob(join(releasesDir, packageName, 'esm2015/*.js'))
.reduce((failures: string[], bundlePath: string) => {
return failures.concat(checkEs2015ReleaseBundle(packageName, bundlePath));
}, []);
}
/**
* Checks an ES2015 bundle inside of a release package. Secondary entry-point bundles will be
* checked as well.
*/
function checkEs2015ReleaseBundle(packageName: string, bundlePath: string): string[] {
const bundleContent = readFileSync(bundlePath, 'utf8');
let failures: string[] = [];
if (inlineStylesSourcemapRegex.exec(bundleContent) !== null) {
failures.push('Bundles contain sourcemap references in component styles.');
}
if (externalReferencesRegex.exec(bundleContent) !== null) {
failures.push('Bundles are including references to external resources (templates or styles)');
}
if (packageName === 'material') {
failures = failures.concat(checkMaterialPackage());
}
return failures;
}
/** Function that includes special checks for the Material package. */
function checkMaterialPackage(): string[] {
const packagePath = join(releasesDir, 'material');
const prebuiltThemesPath = join(packagePath, 'prebuilt-themes');
const themingFilePath = join(packagePath, '_theming.scss');
const failures: string[] = [];
if (glob('*.css', {cwd: prebuiltThemesPath}).length === 0) {
failures.push('Prebuilt themes are not present in the Material release output.');
}
if (!existsSync(themingFilePath)) {
failures.push('The theming SCSS file is not present in the Material release output.');
}
return failures;
}