diff --git a/tools/gulp/tasks/material-release.ts b/tools/gulp/tasks/material-release.ts index ae093792b75..9762bb529c7 100644 --- a/tools/gulp/tasks/material-release.ts +++ b/tools/gulp/tasks/material-release.ts @@ -1,6 +1,6 @@ import {task, src, dest} from 'gulp'; import {join} from 'path'; -import {writeFileSync} from 'fs'; +import {writeFileSync, mkdirpSync} from 'fs-extra'; import {Bundler} from 'scss-bundle'; import {sequenceTask} from '../util/task_helpers'; import {composeRelease} from '../packaging/build-release'; @@ -14,6 +14,9 @@ const {packagesDir, outputDir} = buildConfig; /** Path to the directory where all releases are created. */ const releasesDir = join(outputDir, 'releases'); +/** Path to the output of the Material package. */ +const materialOutputPath = join(outputDir, 'packages', 'material'); + // Path to the sources of the Material package. const materialPath = join(packagesDir, 'lib'); // Path to the release output of material. @@ -23,7 +26,7 @@ const themingEntryPointPath = join(materialPath, 'core', 'theming', '_all-theme. // Output path for the scss theming bundle. const themingBundlePath = join(releasePath, '_theming.scss'); // Matches all pre-built theme css files -const prebuiltThemeGlob = join(materialPath, '**/theming/prebuilt/*.css?(.map)'); +const prebuiltThemeGlob = join(materialOutputPath, '**/theming/prebuilt/*.css?(.map)'); // Matches all SCSS files in the library. const allScssGlob = join(materialPath, '**/*.scss'); @@ -54,7 +57,10 @@ task('material:bundle-theming-scss', () => { // Instantiates the SCSS bundler and bundles all imports of the specified entry point SCSS file. // A glob of all SCSS files in the library will be passed to the bundler. The bundler takes an // array of globs, which will match SCSS files that will be only included once in the bundle. - new Bundler().Bundle(themingEntryPointPath, [allScssGlob]).then(result => { + return new Bundler().Bundle(themingEntryPointPath, [allScssGlob]).then(result => { + // The release directory is not created yet because the composing of the release happens when + // this task finishes. + mkdirpSync(releasePath); writeFileSync(themingBundlePath, result.bundledContent); }); }); diff --git a/tools/gulp/tasks/validate-release.ts b/tools/gulp/tasks/validate-release.ts index 7c845325aa2..81249c2850f 100644 --- a/tools/gulp/tasks/validate-release.ts +++ b/tools/gulp/tasks/validate-release.ts @@ -1,9 +1,10 @@ import {task} from 'gulp'; -import {readFileSync} from 'fs'; +import {readFileSync, existsSync} from 'fs'; import {join} from 'path'; import {green, red} from 'chalk'; import {sequenceTask} from '../util/task_helpers'; import {releasePackages} from './publish'; +import {sync as glob} from 'glob'; import {buildConfig} from '../packaging/build-config'; /** Path to the directory where all releases are created. */ @@ -19,27 +20,27 @@ task('validate-release', sequenceTask(':publish:build-releases', 'validate-relea /** Task that checks the release bundles for any common mistakes before releasing to the public. */ task('validate-release:check-bundles', () => { - const bundleFailures = releasePackages - .map(packageName => join(releasesDir, packageName, '@angular', `${packageName}.js`)) - .map(packageBundle => checkPackageBundle(packageBundle)) + const releaseFailures = releasePackages + .map(packageName => checkReleasePackage(packageName)) .map((failures, index) => ({failures, packageName: releasePackages[index]})); - bundleFailures.forEach(({failures, packageName}) => { + releaseFailures.forEach(({failures, packageName}) => { failures.forEach(failure => console.error(red(`Failure (${packageName}): ${failure}`))); }); - if (bundleFailures.some(({failures}) => failures.length > 0)) { + if (releaseFailures.some(({failures}) => failures.length > 0)) { // Throw an error to notify Gulp about the failures that have been detected. - throw 'Release bundles are not valid and ready for being released.'; + throw 'Release output is not valid and not ready for being released.'; } else { - console.log(green('Release bundles have been checked and are looking fine.')); + console.log(green('Release output has been checked and everything looks fine.')); } }); -/** Task that checks the given release bundle for common mistakes. */ -function checkPackageBundle(bundlePath: string): string[] { +/** Task that validates the given release package before releasing. */ +function checkReleasePackage(packageName: string): string[] { + const bundlePath = join(releasesDir, packageName, '@angular', `${packageName}.js`); const bundleContent = readFileSync(bundlePath, 'utf8'); - const failures = []; + let failures = []; if (inlineStylesSourcemapRegex.exec(bundleContent) !== null) { failures.push('Bundles contain sourcemap references in component styles.'); @@ -49,5 +50,27 @@ function checkPackageBundle(bundlePath: string): string[] { 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 = []; + + 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; }