From 7e08a7b2a7feba3ba66c322313895ea7403d267b Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 16 Oct 2015 17:30:14 -0400 Subject: [PATCH 01/21] Initial port of build process to gulp 1. Move all build related code to gulpfile.js 2. Add `npm` scripts for all gulp tasks so no one needs to install gulp globally. 3. Added new `jshint-watch` task for continually running jsHint on changed files and writing the results to the console. --- .gitignore | 2 +- .idea/cesium.iml | 1 + .idea/watcherTasks.xml | 25 +- .jshintrc | 3 +- .travis.yml | 4 +- gulpfile.js | 788 +++++++++++++++++++++++++++++++++++++++++ package.json | 66 +++- 7 files changed, 844 insertions(+), 45 deletions(-) create mode 100644 gulpfile.js diff --git a/.gitignore b/.gitignore index 9cd1f06d26eb..3b8dc6af394d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ Thumbs.db /Apps/CesiumViewer/Gallery/gallery-index.js /Apps/Sandcastle/jsHintOptions.js +/Apps/Sandcastle/.jshintrc /Apps/Sandcastle/gallery/gallery-index.js /Source/Cesium.js @@ -15,7 +16,6 @@ Thumbs.db /Source/Shaders/*.js /Source/Shaders/*/*.js /Source/Shaders/*/*/*.js -!/Source/Shaders/Shaders.profile.js /Specs/SpecList.js diff --git a/.idea/cesium.iml b/.idea/cesium.iml index 7bac7e6aefdc..9d1caefa1f83 100644 --- a/.idea/cesium.iml +++ b/.idea/cesium.iml @@ -4,6 +4,7 @@ + diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml index 30c92c70896b..c8f67ffc55ee 100644 --- a/.idea/watcherTasks.xml +++ b/.idea/watcherTasks.xml @@ -1,25 +1,2 @@ - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/.jshintrc b/.jshintrc index d0aab9e94a74..41bbea9cc9b4 100644 --- a/.jshintrc +++ b/.jshintrc @@ -41,5 +41,6 @@ "shadow": false, "sub": false, "supernew": false, - "browser": true + "browser": true, + "predef": [ "JSON" ] } \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b5e0c12a89b6..27cf02d7e417 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "0.10" + - "0.12" sudo: false script: - - ant jsHint release -DnodePath=node + - npm run jsHint && npm run release diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 000000000000..2f7e6b4b6eba --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,788 @@ +/*jslint node: true, latedef: nofunc*/ +"use strict"; + +var fs = require('fs'); +var path = require('path'); +var os = require('os'); +var child_process = require('child_process'); + +var globby = require('globby'); +var jshint = require('gulp-jshint'); +var async = require('async'); +var rimraf = require('rimraf'); +var stripComments = require('strip-comments'); +var mkdirp = require('mkdirp'); +var eventStream = require('event-stream'); +var gulp = require('gulp'); +var gulpInsert = require('gulp-insert'); +var gulpZip = require('gulp-zip'); +var gulpRename = require('gulp-rename'); +var gulpReplace = require('gulp-replace'); + +var packageJson = require('./package.json'); + +//Gulp doesn't seem to have a way to get the currently running tasks for setting +//per-task variables. We use the command line argument here to detect which task is being run. +var noDevelopmentGallery = process.argv[2] === 'release' || process.argv[2] === 'makeZipFile'; + +var sourceFiles = ['Source/**/*.js', + '!Source/*.js', + '!Source/Workers/**', + '!Source/ThirdParty/Workers/**', + 'Source/Workers/createTaskProcessorWorker.js']; + +var jsHintFiles = ['Source/**/*.js', + '!Source/Shaders/**', + '!Source/ThirdParty/**', + '!Source/Workers/cesiumWorkerBootstrapper.js', + 'Apps/**/*.js', + 'Apps/Sandcastle/gallery/*.html', + '!Apps/Sandcastle/ThirdParty/**', + 'Specs/**/*.js', + 'Tools/buildTasks/**/*.js']; + +var filesToClean = ['Source/Cesium.js', + 'Build', + 'Instrumented', + 'Source/Shaders/**.js', + 'Specs/SpecList.js', + 'Apps/Sandcastle/.jshintrc', + 'Apps/Sandcastle/jsHintOptions.js', + 'Apps/Sandcastle/gallery/gallery-index.js', + 'Cesium-*.zip']; + +var filesToSortRequires = ['Source/**/*.js', + '!Source/Shaders/**', + '!Source/ThirdParty/**', + '!Source/Workers/cesiumWorkerBootstrapper.js', + '!Source/copyrightHeader.js', + '!Source/Workers/transferTypedArrayTest.js', + 'Apps/**/*.js', + '!Apps/Sandcastle/ThirdParty/**', + '!Apps/Sandcastle/jsHintOptions.js', + 'Specs/**/*.js', + '!Specs/spec-main.js', + '!Specs/SpecRunner.js', + '!Specs/SpecList.js', + '!Apps/Sandcastle/Sandcastle-client.js', + '!Apps/Sandcastle/Sandcastle-header.js', + '!Apps/Sandcastle/Sandcastle-warn.js', + '!Apps/Sandcastle/gallery/gallery-index.js']; + +gulp.task('default', ['combine']); + +gulp.task('build', function(done) { + mkdirp.sync('Build'); + glslToJavaScript(false, 'Build/minifyShaders.state'); + createCesiumJs(); + createSpecList(); + createGalleryList(); + createSandcastleJsHintOptions(); + done(); +}); + +gulp.task('buildApps', ['combine', 'minifyRelease'], function() { + return buildCesiumViewer(); +}); + +gulp.task('clean', function(done) { + async.forEach(filesToClean, rimraf, done); +}); + +gulp.task('cloc', ['build'], function(done) { + var glsl = globby.sync(['Source/Shaders/*.glsl', 'Source/Shaders/**/*.glsl', 'Source/main.js']); + glsl = glsl.join(' '); + + var clockPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); + var cloc_definitions = path.join('Tools', 'cloc-1.60', 'cloc_definitions'); + + console.log('Source:'); + child_process.execSync('perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + + ' Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + + glsl, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + + console.log('Specs:'); + child_process.execSync('perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/', { + stdio : [process.stdin, process.stdout, process.stderr] + }); + + done(); +}); + +gulp.task('combine', ['generateStubs'], function() { + return combineJavaScript({ + removePragmas : false, + minify : false, + outputDirectory : path.join('Build', 'CesiumUnminified') + }); +}); + +gulp.task('combineRelease', ['generateStubs'], function() { + return combineJavaScript({ + removePragmas : true, + minify : false, + outputDirectory : path.join('Build', 'CesiumUnminified') + }); +}); + +//Builds the documentation +gulp.task('generateDocumentation', function() { + var envPathSeperator = os.platform() === 'win32' ? ';' : ':'; + + child_process.execSync('jsdoc --configure Tools/jsdoc/conf.json', { + stdio : [process.stdin, process.stdout, process.stderr], + env : { + PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin', + CESIUM_VERSION : packageJson.version + } + }); + + return gulp.src('Documentation/Images/**').pipe(gulp.dest('Build/Documentation/Images')); +}); + +gulp.task('instrumentForCoverage', ['build'], function(done) { + var exe = path.join('Tools', 'jscoverage-0.5.1', 'jscoverage.exe'); + child_process.execSync(exe + ' Source Instrumented --no-instrument=./ThirdParty', { + stdio : [process.stdin, process.stdout, process.stderr] + }); + done(); +}); + +//Runs jsHint +gulp.task('jsHint', ['build'], function() { + return gulp.src(jsHintFiles) + .pipe(jshint.extract('auto')) + .pipe(jshint()) + .pipe(jshint.reporter('jshint-stylish')); +}); + +//Runs jsHint automatically on file change. +gulp.task('jsHint-watch', function() { + gulp.watch(jsHintFiles).on('change', function(event) { + gulp.src(event.path) + .pipe(jshint.extract('auto')) + .pipe(jshint()) + .pipe(jshint.reporter('jshint-stylish')); + }); +}); + +gulp.task('makeZipFile', ['release'], function() { + var builtSrc = gulp.src([ + 'Build/Apps/**', + 'Build/Cesium/**', + 'Build/CesiumUnminified/**', + 'Build/Documentation/**' + ], { + root : 'Build', + base : '.' + }); + + var staticSrc = gulp.src([ + 'Apps/**', + '!Apps/Sandcastle/gallery/development/**', + 'Source/**', + 'Specs/**', + 'ThirdParty/**', + 'logo.png', + 'favicon.ico', + 'gulpfile.js', + 'server.js', + 'package.json', + 'LICENSE.md', + 'CHANGES.md', + 'README.md', + 'web.config' + ], { + base : '.' + }); + + var indexSrc = gulp.src('index.release.html').pipe(gulpRename("index.html")); + + var version = packageJson.version; + if (/\.0$/.test(version)) { + version = version.substring(0, version.length - 2); + } + + return eventStream.merge(builtSrc, staticSrc, indexSrc) + .pipe(gulpZip('Cesium-' + version + '.zip')) + .pipe(gulp.dest('.')); +}); + +gulp.task('minify', ['generateStubs'], function() { + return combineJavaScript({ + removePragmas : false, + minify : true, + outputDirectory : path.join('Build', 'Cesium') + }); +}); + +gulp.task('minifyRelease', ['generateStubs'], function() { + return combineJavaScript({ + removePragmas : true, + minify : true, + outputDirectory : path.join('Build', 'Cesium') + }); +}); + +gulp.task('release', ['buildApps', 'generateDocumentation']); + +gulp.task('generateStubs', ['build'], function() { + mkdirp.sync(path.join('Build', 'Stubs')); + + var contents = '\ +/*global define,Cesium*/\n\ +(function() {\n\ +"use strict";\n\ +/*jshint sub:true*/\n'; + var modulePathMappings = []; + + globby.sync(sourceFiles).forEach(function(file) { + file = path.relative('Source', file); + var moduleId = file.replace(/\\/, '/'); + moduleId = moduleId.substring(0, moduleId.lastIndexOf('.')); + + var baseName = path.basename(file); + var propertyName = baseName.substring(0, baseName.lastIndexOf('.')); + propertyName = "['" + String(propertyName) + "']"; + + contents += '\ +define(\'' + moduleId + '\', function() {\n\ + return Cesium' + propertyName + ';\n\ +});\n\n'; + + modulePathMappings.push(' \'' + moduleId + '\' : \'../Stubs/Cesium\''); + }); + + contents += '})();'; + + var paths = '\ +/*global define*/\n\ +define(function() {\n\ + "use strict";\n\ + return {\n' + modulePathMappings.join(',\n') + '\n\ + };\n\ +});'; + + fs.writeFileSync(path.join('Build', 'Stubs', 'Cesium.js'), contents); + fs.writeFileSync(path.join('Build', 'Stubs', 'paths.js'), paths); +}); + +//Alphabetizes and formats require statement at top of each file. +gulp.task('sortRequires', function(done) { + var noModulesRegex = /[\s\S]*?define\(function\(\)/; + var requiresRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[)([\S\s]*?)]([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/; + var splitRegex = /,\s*/; + var filesChecked = 0; + + var files = globby.sync(filesToSortRequires); + async.forEach(files, function(file, callback) { + if (filesChecked > 0 && filesChecked % 50 === 0) { + console.log('Sorted requires in ' + filesChecked + ' files'); + } + ++filesChecked; + + fs.readFile(file, function(err, contents) { + if (err) { + return callback(err); + } + + var result = requiresRegex.exec(contents); + + if (result === null) { + if (!noModulesRegex.test(contents)) { + console.log(file + ' does not have the expected syntax.'); + } + return; + } + + // In specs, the first require is significant, + // unless the spec is given an explicit name. + var preserveFirst = false; + if (result[2] === 'defineSuite' && result[4] === ', function') { + preserveFirst = true; + } + + var names = result[3].split(splitRegex); + if (names.length === 1 && names[0].trim() === '') { + names.length = 0; + } + + var i; + for (i = 0; i < names.length; ++i) { + if (names[i].indexOf('//') >= 0 || names[i].indexOf('/*') >= 0) { + console.log(file + ' contains comments in the require list. Skipping so nothing gets broken.'); + return; + } + } + + var identifiers = result[5].split(splitRegex); + if (identifiers.length === 1 && identifiers[0].trim() === '') { + identifiers.length = 0; + } + + for (i = 0; i < identifiers.length; ++i) { + if (identifiers[i].indexOf('//') >= 0 || identifiers[i].indexOf('/*') >= 0) { + console.log(file + ' contains comments in the require list. Skipping so nothing gets broken.'); + return; + } + } + + var requires = []; + + for (i = preserveFirst ? 1 : 0; i < names.length && i < identifiers.length; ++i) { + requires.push({ + name : names[i].trim(), + identifier : identifiers[i].trim() + }); + } + + requires.sort(function(a, b) { + var aName = a.name.toLowerCase(); + var bName = b.name.toLowerCase(); + if (aName < bName) { + return -1; + } else if (aName > bName) { + return 1; + } else { + return 0; + } + }); + + if (preserveFirst) { + requires.splice(0, 0, { + name : names[0].trim(), + identifier : identifiers[0].trim() + }); + } + + // Convert back to separate lists for the names and identifiers, and add + // any additional names or identifiers that don't have a corresponding pair. + var sortedNames = requires.map(function(item) { + return item.name; + }); + for (i = sortedNames.length; i < names.length; ++i) { + sortedNames.push(names[i].trim()); + } + + var sortedIdentifiers = requires.map(function(item) { + return item.identifier; + }); + for (i = sortedIdentifiers.length; i < identifiers.length; ++i) { + sortedIdentifiers.push(identifiers[i].trim()); + } + + var outputNames = ']'; + if (sortedNames.length > 0) { + outputNames = '\r\n ' + + sortedNames.join(',\r\n ') + + '\r\n ]'; + } + + var outputIdentifiers = '('; + if (sortedIdentifiers.length > 0) { + outputIdentifiers = '(\r\n ' + + sortedIdentifiers.join(',\r\n '); + } + + contents = result[1] + + outputNames + + result[4].replace(/^[,\s]+/, ', ').trim() + + outputIdentifiers + + ') {' + + result[6]; + + fs.writeFile(file, contents, callback); + }); + }, done); +}); + +function combineJavaScriptCombineCesium(debug, minify, combineOutput) { + var rjsPath = path.join('..', 'ThirdParty', 'requirejs-2.1.9', 'r.js'); + var rjsOptions = path.join('..', 'Tools', 'build.js'); + var relativeAlmondPath = path.join('..', 'ThirdParty', 'almond-0.2.6', 'almond.js'); + var relativeCombineOutputDirectory = path.join('..', combineOutput); + debug = debug ? 'true' : 'false'; + child_process.execSync('node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + + ' optimize=' + minify + ' baseUrl=. skipModuleInsertion=true name=' + relativeAlmondPath + + ' include=main out=' + relativeCombineOutputDirectory + '/Cesium.js', { + stdio : [process.stdin, process.stdout, process.stderr], + cwd : 'Source' + }); +} + +function combineJavaScriptCombineCesiumWorkers(debug, minify, combineOutput) { + var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); + var rjsOptions = path.join('Tools', 'build.js'); + debug = debug ? 'true' : 'false'; + + var files = globby.sync(['Source/Workers/cesiumWorkerBootstrapper.js', + 'Source/Workers/transferTypedArrayTest.js', + 'Source/ThirdParty/Workers/*.js']); + + files.forEach(function(file) { + var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + + ' optimize=' + minify + ' baseUrl=. skipModuleInsertion=true wrap=false' + + ' include=' + file.slice(0, -3) + ' out=' + path.join(combineOutput, path.relative('Source', file)); + child_process.execSync(cmdLine, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + }); + + files = globby.sync(['Source/Workers/*.js', + '!Source/Workers/cesiumWorkerBootstrapper.js', + '!Source/Workers/transferTypedArrayTest.js', + '!Source/ThirdParty/Workers/*.js']); + + files.forEach(function(file) { + var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + + ' optimize=' + minify + ' baseUrl=.' + + ' include=' + file.slice(0, -3) + ' out=' + path.join(combineOutput, path.relative('Source', file)); + child_process.execSync(cmdLine, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + }); +} + +function minifyCSS(outputDirectory) { + var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); + var rjsOptions = path.join('Tools', 'build.js'); + + return gulp.src('Source/**/*.css', + { + base : 'Source', + noDir : true + }) + .pipe(gulp.dest(outputDirectory)) + .on('finish', function(err) { + if (err) { + throw err; + } + + var files = globby.sync(outputDirectory + '/**/*.css'); + files.forEach(function(file) { + var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' cssIn=' + file + ' out=' + file; + child_process.execSync(cmdLine, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + }); + }); +} + +function combineJavaScript(options) { + var optimizer = options.minify ? 'uglify2' : 'none'; + var outputDirectory = options.outputDirectory; + var removePragmas = options.removePragmas; + + var combineOutput = path.join('Build', 'combineOutput', optimizer); + var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js')); + combineJavaScriptCombineCesium(!removePragmas, optimizer, combineOutput); + combineJavaScriptCombineCesiumWorkers(!removePragmas, optimizer, combineOutput); + + var streams = []; + + //copy to build folder with copyright header added at the top + streams.push(gulp.src([combineOutput + '/**']) + .pipe(gulpInsert.prepend(copyrightHeader)) + .pipe(gulp.dest(outputDirectory)) + .on('finish', function(err) { + if (err) { + throw err; + } + rimraf.sync(combineOutput); + })); + + var everythingElse = ['Source/**', '!**/*.js', '!**/*.glsl']; + if (options.minify) { + streams.push(minifyCSS(path.join('Build', 'Cesium'))); + everythingElse.push('!**/*.css'); + } + + streams.push(gulp.src(everythingElse, {nodir : true}) + .pipe(gulp.dest(outputDirectory))); + + return eventStream.merge(streams); +} + +function glslToJavaScript(minify, minifyStateFilePath) { + fs.writeFileSync(minifyStateFilePath, minify); + var minifyStateFileLastModified = fs.existsSync(minifyStateFilePath) ? fs.statSync(minifyStateFilePath).mtime.getTime() : 0; + +// collect all currently existing JS files into a set, later we will remove the ones +// we still are using from the set, then delete any files remaining in the set. + var leftOverJsFiles = {}; + + globby.sync(['Source/Shaders/**/*.js']).forEach(function(file) { + leftOverJsFiles[path.normalize(file)] = true; + }); + + var builtinFunctions = []; + var builtinConstants = []; + var builtinStructs = []; + + var glslFiles = globby.sync(['Source/Shaders/**/*.glsl']); + glslFiles.forEach(function(glslFile) { + glslFile = path.normalize(glslFile); + var baseName = path.basename(glslFile, '.glsl'); + var jsFile = path.join(path.dirname(glslFile), baseName) + '.js'; + + // identify built in functions, structs, and constants + if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Functions'))) === 0) { + builtinFunctions.push(baseName); + } + else if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Constants'))) === 0) { + builtinConstants.push(baseName); + } + else if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Structs'))) === 0) { + builtinStructs.push(baseName); + } + + delete leftOverJsFiles[jsFile]; + + var jsFileExists = fs.existsSync(jsFile); + var jsFileModified = jsFileExists ? fs.statSync(jsFile).mtime.getTime() : 0; + var glslFileModified = fs.statSync(glslFile).mtime.getTime(); + + if (jsFileExists && jsFileModified > glslFileModified && jsFileModified > minifyStateFileLastModified) { + return; + } + + var contents = fs.readFileSync(glslFile, 'utf8'); + contents = contents.replace(/\r\n/gm, '\n'); + + var copyrightComments = ''; + var extractedCopyrightComments = contents.match(/\/\*\*(?:[^*\/]|\*(?!\/)|\n)*?@license(?:.|\n)*?\*\//gm); + if (extractedCopyrightComments) { + copyrightComments = extractedCopyrightComments.join('\n') + '\n'; + } + + if (minify) { + contents = stripComments(contents); + contents = contents.replace(/\s+$/gm, '').replace(/^\s+/gm, '').replace(/\n+/gm, '\n'); + contents += '\n'; + } + + contents = contents.split('"').join('\\"').replace(/\n/gm, '\\n\\\n'); + contents = copyrightComments + '\ + //This file is automatically rebuilt by the Cesium build process.\n\ + /*global define*/\n\ + define(function() {\n\ + "use strict";\n\ + return "' + contents + '";\n\ +});'; + + fs.writeFileSync(jsFile, contents); + }); + + // delete any left over JS files from old shaders + Object.keys(leftOverJsFiles).forEach(rimraf.sync); + + var generateBuiltinContents = function(contents, builtins, path) { + var amdPath = contents.amdPath; + var amdClassName = contents.amdClassName; + var builtinLookup = contents.builtinLookup; + for (var i = 0; i < builtins.length; i++) { + var builtin = builtins[i]; + amdPath = amdPath + ',\n \'./' + path + '/' + builtin + '\''; + amdClassName = amdClassName + ',\n ' + 'czm_' + builtin; + builtinLookup = builtinLookup + ',\n ' + 'czm_' + builtin + ' : ' + 'czm_' + builtin; + } + contents.amdPath = amdPath; + contents.amdClassName = amdClassName; + contents.builtinLookup = builtinLookup; + }; + +//generate the JS file for Built-in GLSL Functions, Structs, and Constants + var contents = {amdPath : '', amdClassName : '', builtinLookup : ''}; + generateBuiltinContents(contents, builtinConstants, 'Constants'); + generateBuiltinContents(contents, builtinStructs, 'Structs'); + generateBuiltinContents(contents, builtinFunctions, 'Functions'); + + contents.amdPath = contents.amdPath.replace(',\n', ''); + contents.amdClassName = contents.amdClassName.replace(',\n', ''); + contents.builtinLookup = contents.builtinLookup.replace(',\n', ''); + + var fileContents = '\ +//This file is automatically rebuilt by the Cesium build process.\n\ +/*global define*/\n\ +define([\n' + + contents.amdPath + + '\n ], function(\n' + + contents.amdClassName + + ') {\n\ + "use strict";\n\ + return {\n' + contents.builtinLookup + '};\n\ +});'; + + fs.writeFileSync(path.join('Source', 'Shaders', 'Builtin', 'CzmBuiltins.js'), fileContents); +} + +function createCesiumJs() { + var moduleIds = []; + var parameters = []; + var assignments = []; + + var nonIdentifierRegexp = /[^0-9a-zA-Z_$]/g; + + globby.sync(sourceFiles).forEach(function(file) { + file = path.relative('Source', file); + var moduleId = path.normalize(file); + moduleId = moduleId.substring(0, moduleId.lastIndexOf('.')); + + var baseName = path.basename(file); + var assignmentName = baseName.substring(0, baseName.lastIndexOf('.')); + assignmentName = "['" + assignmentName + "']"; + if (moduleId.indexOf(path.normalize('Source\\Shaders\\')) === 0) { + assignmentName = '._shaders' + assignmentName; + } + + var parameterName = moduleId.replace(nonIdentifierRegexp, '_'); + + moduleIds.push("'./" + moduleId.replace(/\\/g, '/') + "'"); + parameters.push(parameterName); + assignments.push('Cesium' + assignmentName + ' = ' + parameterName + ';'); + }); + + var version = packageJson.version; + + var contents = '\ +/*global define*/\n\ +define([' + moduleIds.join(', ') + '], function(' + parameters.join(', ') + ') {\n\ + "use strict";\n\ + /*jshint sub:true*/\n\ + var Cesium = {\n\ + VERSION : "' + version + '",\n\ + _shaders : {}\n\ + };\n\ + ' + assignments.join('\n ') + '\n\ + return Cesium;\n\ +});'; + + fs.writeFileSync('Source/Cesium.js', contents); +} + +function createSpecList() { + var specFiles = globby.sync(['Specs/**/*.js', '!Specs/*.js']); + var specs = []; + + specFiles.forEach(function(file) { + var spec = file.substring(0, file.lastIndexOf('.')).replace('\\', '/'); + specs.push("'" + spec + "'"); + }); + + var contents = 'var specs = [' + specs.join(',') + '];'; + fs.writeFileSync(path.join('Specs', 'SpecList.js'), contents); +} + +function createGalleryList() { + var demos = []; + var output = path.join('Apps', 'Sandcastle', 'gallery', 'gallery-index.js'); + + var fileList = ['Apps/Sandcastle/gallery/**/*.html']; + if (noDevelopmentGallery) { + fileList.push('!Apps/Sandcastle/gallery/development/**/*.html'); + } + + globby.sync(fileList).forEach(function(file) { + var demo = file.substring(24, file.lastIndexOf('.')).replace('\\', '/'); + var demoObject = { + name : String(demo), + date : fs.statSync(file).mtime.getTime() + }; + + if (fs.existsSync(file.replace('.html', '') + '.jpg')) { + demoObject.img = demo + '.jpg'; + } + + demos.push(JSON.stringify(demoObject, null, 2)); + }); + + var contents = '\ +// This file is automatically rebuilt by the Cesium build process.\n\ +var gallery_demos = [' + demos.join(', ') + '];'; + + fs.writeFileSync(output, contents); +} + +function createSandcastleJsHintOptions() { + var jsHintOptions = JSON.parse(fs.readFileSync('.jshintrc', 'utf8')); + jsHintOptions.predef = ['JSON', 'require', 'console', 'Sandcastle', 'Cesium']; + + var contents = JSON.stringify(jsHintOptions, null, 2); + fs.writeFile(path.join('Apps', 'Sandcastle', '.jshintrc'), contents); + + contents = '\ +// This file is automatically rebuilt by the Cesium build process.\n\ +var sandcastleJsHintOptions = ' + contents + ';'; + fs.writeFile(path.join('Apps', 'Sandcastle', 'jsHintOptions.js'), contents); +} + +function buildCesiumViewer() { + var cesiumViewerOutputDirectory = 'Build/Apps/CesiumViewer'; + var cesiumViewerStartup = path.join(cesiumViewerOutputDirectory, 'CesiumViewerStartup.js'); + mkdirp.sync(cesiumViewerOutputDirectory); + + var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); + var rjsOptions = path.join('Tools', 'build.js'); + + //mainConfigFile must be relative to the build.js file + var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=false' + + ' optimize=uglify2 mainConfigFile=../Apps/CesiumViewer/CesiumViewerStartup.js' + + ' name=CesiumViewerStartup out=' + cesiumViewerStartup; + child_process.execSync(cmdLine, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + + var cesiumViewerCss = path.join(cesiumViewerOutputDirectory, 'CesiumViewer.css'); + cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' cssIn=Apps/CesiumViewer/CesiumViewer.css out=' + cesiumViewerCss; + child_process.execSync(cmdLine, { + stdio : [process.stdin, process.stdout, process.stderr] + }); + + //add copyright header + var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js')); + + return eventStream.merge( + gulp.src(cesiumViewerStartup) + .pipe(gulpInsert.prepend(copyrightHeader)) + .pipe(gulpReplace('../../Source', '.')) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) + .pipe(gulp.dest(cesiumViewerOutputDirectory)), + + gulp.src(['Apps/CesiumViewer/**', + '!Apps/CesiumViewer/**/*.js', + '!Apps/CesiumViewer/**/*.css']) + .pipe(gulpReplace('../../Source', '.')) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) + .pipe(gulp.dest(cesiumViewerOutputDirectory)), + + gulp.src(['ThirdParty/requirejs-2.1.9/require.min.js']) + .pipe(gulpRename('require.js')) + .pipe(gulp.dest(cesiumViewerOutputDirectory)), + + gulp.src(['Build/Cesium/Assets/**', + 'Build/Cesium/Workers/**', + 'Build/Cesium/ThirdParty/Workers/**', + 'Build/Cesium/Widgets/**', + '!Build/Cesium/Widgets/**/*.css'], + { + base : 'Build/Cesium', + nodir : true + }) + .pipe(gulpReplace('../../Source', '.')) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) + .pipe(gulp.dest(cesiumViewerOutputDirectory)), + + gulp.src(['Build/Cesium/Widgets/InfoBox/InfoBoxDescription.css'], + { + base : 'Build/Cesium' + }) + .pipe(gulpReplace('../../Source', '.')) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) + .pipe(gulp.dest(cesiumViewerOutputDirectory)), + + gulp.src(['web.config']) + .pipe(gulp.dest(cesiumViewerOutputDirectory)) + ); +} \ No newline at end of file diff --git a/package.json b/package.json index e3704b1f42b3..df5e235389a9 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,50 @@ { - "name": "cesium", - "version": "1.14.0", - "description": "Cesium is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", - "homepage": "http://cesiumjs.org", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/AnalyticalGraphicsInc/cesium.git" - }, - "devDependencies": { - "jsdoc": "3.3.3", - "express": "4.13.3", - "compression": "1.6.0", - "request": "2.65.0", - "yargs": "3.27.0" - } -} \ No newline at end of file + "name": "cesium", + "version": "1.14.0", + "description": "Cesium is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", + "homepage": "http://cesiumjs.org", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/AnalyticalGraphicsInc/cesium.git" + }, + "devDependencies": { + "async": "^1.4.2", + "compression": "1.6.0", + "event-stream": "^3.3.2", + "express": "4.13.3", + "globby": "^3.0.1", + "gulp": "^3.9.0", + "gulp-insert": "^0.5.0", + "gulp-jshint": "^1.11.2", + "gulp-rename": "^1.2.2", + "gulp-replace": "^0.5.4", + "gulp-zip": "^3.0.2", + "jsdoc": "3.3.3", + "jshint-stylish": "^2.0.1", + "mkdirp": "^0.5.1", + "request": "2.65.0", + "rimraf": "^2.4.3", + "strip-comments": "^0.3.2", + "yargs": "3.27.0" + }, + "scripts": { + "start": "node server.js", + "build": "gulp build", + "buildApps": "gulp buildApps", + "clean": "gulp clean", + "cloc": "gulp cloc", + "combine": "gulp combine", + "combineRelease": "gulp combineRelease", + "generateDocumentation": "gulp generateDocumentation", + "instrumentForCoverage": "gulp instrumentForCoverage", + "jsHint": "gulp jsHint --silent", + "jsHint-watch": "gulp jsHint-watch --silent", + "makeZipFile": "gulp makeZipFile", + "minify": "gulp minify", + "minifyRelease": "gulp minifyRelease", + "release": "gulp release", + "generateStubs": "gulp generateStubs", + "sortRequires": "gulp sortRequires" + } +} From ac4406013e3902ec9bb6c118fcf6c9f2a848e0a6 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 18 Oct 2015 13:03:20 -0400 Subject: [PATCH 02/21] Use r.js optimizer programatically via npm module. Also general code clean up. This change temporarily disables the almond loader. --- gulpfile.js | 364 ++++++++++++++++++++++++++++----------------------- package.json | 6 +- 2 files changed, 207 insertions(+), 163 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2f7e6b4b6eba..053aaa2729ab 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,12 +18,15 @@ var gulpInsert = require('gulp-insert'); var gulpZip = require('gulp-zip'); var gulpRename = require('gulp-rename'); var gulpReplace = require('gulp-replace'); +var Promise = require('bluebird'); +var requirejs = require('requirejs'); var packageJson = require('./package.json'); //Gulp doesn't seem to have a way to get the currently running tasks for setting //per-task variables. We use the command line argument here to detect which task is being run. var noDevelopmentGallery = process.argv[2] === 'release' || process.argv[2] === 'makeZipFile'; +var copyUnminified = process.argv[2] === 'combine' || process.argv[2] === 'default' || process.argv[2] === undefined; var sourceFiles = ['Source/**/*.js', '!Source/*.js', @@ -39,7 +42,8 @@ var jsHintFiles = ['Source/**/*.js', 'Apps/Sandcastle/gallery/*.html', '!Apps/Sandcastle/ThirdParty/**', 'Specs/**/*.js', - 'Tools/buildTasks/**/*.js']; + 'Tools/buildTasks/**/*.js', + 'gulpfile.js']; var filesToClean = ['Source/Cesium.js', 'Build', @@ -112,18 +116,30 @@ gulp.task('cloc', ['build'], function(done) { }); gulp.task('combine', ['generateStubs'], function() { + var outputDirectory = path.join('Build', 'CesiumUnminified'); return combineJavaScript({ removePragmas : false, - minify : false, - outputDirectory : path.join('Build', 'CesiumUnminified') + optimizer : 'none', + outputDirectory : outputDirectory + }).then(function() { + if (!copyUnminified) { + return; + } + return streamToPromise(gulp.src(outputDirectory + '/**').pipe(gulp.dest(path.join('Build', 'Cesium')))); }); }); gulp.task('combineRelease', ['generateStubs'], function() { + var outputDirectory = path.join('Build', 'CesiumUnminified'); return combineJavaScript({ removePragmas : true, - minify : false, - outputDirectory : path.join('Build', 'CesiumUnminified') + optimizer : 'none', + outputDirectory : outputDirectory + }).then(function() { + if (!copyUnminified) { + return; + } + return streamToPromise(gulp.src(outputDirectory + '/**').pipe(gulp.dest(path.join('Build', 'Cesium')))); }); }); @@ -143,14 +159,11 @@ gulp.task('generateDocumentation', function() { }); gulp.task('instrumentForCoverage', ['build'], function(done) { - var exe = path.join('Tools', 'jscoverage-0.5.1', 'jscoverage.exe'); - child_process.execSync(exe + ' Source Instrumented --no-instrument=./ThirdParty', { - stdio : [process.stdin, process.stdout, process.stderr] - }); - done(); + var jscoveragePath = path.join('Tools', 'jscoverage-0.5.1', 'jscoverage.exe'); + var cmdLine = jscoveragePath + ' Source Instrumented --no-instrument=./ThirdParty'; + child_process.exec(cmdLine, {stdio : [process.stdin, process.stdout, process.stderr]}, done); }); -//Runs jsHint gulp.task('jsHint', ['build'], function() { return gulp.src(jsHintFiles) .pipe(jshint.extract('auto')) @@ -158,7 +171,6 @@ gulp.task('jsHint', ['build'], function() { .pipe(jshint.reporter('jshint-stylish')); }); -//Runs jsHint automatically on file change. gulp.task('jsHint-watch', function() { gulp.watch(jsHintFiles).on('change', function(event) { gulp.src(event.path) @@ -181,7 +193,7 @@ gulp.task('makeZipFile', ['release'], function() { var staticSrc = gulp.src([ 'Apps/**', - '!Apps/Sandcastle/gallery/development/**', + '!Apps/Sandcastle/gallery/development', 'Source/**', 'Specs/**', 'ThirdParty/**', @@ -213,7 +225,7 @@ gulp.task('makeZipFile', ['release'], function() { gulp.task('minify', ['generateStubs'], function() { return combineJavaScript({ removePragmas : false, - minify : true, + optimizer : 'uglify2', outputDirectory : path.join('Build', 'Cesium') }); }); @@ -221,14 +233,14 @@ gulp.task('minify', ['generateStubs'], function() { gulp.task('minifyRelease', ['generateStubs'], function() { return combineJavaScript({ removePragmas : true, - minify : true, + optimizer : 'uglify2', outputDirectory : path.join('Build', 'Cesium') }); }); gulp.task('release', ['buildApps', 'generateDocumentation']); -gulp.task('generateStubs', ['build'], function() { +gulp.task('generateStubs', ['build'], function(done) { mkdirp.sync(path.join('Build', 'Stubs')); var contents = '\ @@ -267,9 +279,9 @@ define(function() {\n\ fs.writeFileSync(path.join('Build', 'Stubs', 'Cesium.js'), contents); fs.writeFileSync(path.join('Build', 'Stubs', 'paths.js'), paths); + done(); }); -//Alphabetizes and formats require statement at top of each file. gulp.task('sortRequires', function(done) { var noModulesRegex = /[\s\S]*?define\(function\(\)/; var requiresRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[)([\S\s]*?)]([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/; @@ -398,111 +410,120 @@ gulp.task('sortRequires', function(done) { }, done); }); -function combineJavaScriptCombineCesium(debug, minify, combineOutput) { - var rjsPath = path.join('..', 'ThirdParty', 'requirejs-2.1.9', 'r.js'); - var rjsOptions = path.join('..', 'Tools', 'build.js'); - var relativeAlmondPath = path.join('..', 'ThirdParty', 'almond-0.2.6', 'almond.js'); - var relativeCombineOutputDirectory = path.join('..', combineOutput); - debug = debug ? 'true' : 'false'; - child_process.execSync('node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + - ' optimize=' + minify + ' baseUrl=. skipModuleInsertion=true name=' + relativeAlmondPath + - ' include=main out=' + relativeCombineOutputDirectory + '/Cesium.js', { - stdio : [process.stdin, process.stdout, process.stderr], - cwd : 'Source' +function combineCesium(debug, optimizer, combineOutput) { + return requirejsOptimize({ + wrap : true, + useStrict : true, + optimize : optimizer, + optimizeCss : 'standard', + pragmas : { + debug : debug + }, + baseUrl : 'Source', + skipModuleInsertion : true, + //name : path.join('..', 'ThirdParty', 'almond-0.2.6', 'almond.js'), + include : 'main', + out : path.join(combineOutput, 'Cesium.js') }); } -function combineJavaScriptCombineCesiumWorkers(debug, minify, combineOutput) { - var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); - var rjsOptions = path.join('Tools', 'build.js'); - debug = debug ? 'true' : 'false'; - - var files = globby.sync(['Source/Workers/cesiumWorkerBootstrapper.js', - 'Source/Workers/transferTypedArrayTest.js', - 'Source/ThirdParty/Workers/*.js']); - - files.forEach(function(file) { - var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + - ' optimize=' + minify + ' baseUrl=. skipModuleInsertion=true wrap=false' + - ' include=' + file.slice(0, -3) + ' out=' + path.join(combineOutput, path.relative('Source', file)); - child_process.execSync(cmdLine, { - stdio : [process.stdin, process.stdout, process.stderr] - }); - }); - - files = globby.sync(['Source/Workers/*.js', - '!Source/Workers/cesiumWorkerBootstrapper.js', - '!Source/Workers/transferTypedArrayTest.js', - '!Source/ThirdParty/Workers/*.js']); - - files.forEach(function(file) { - var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=' + debug + - ' optimize=' + minify + ' baseUrl=.' + - ' include=' + file.slice(0, -3) + ' out=' + path.join(combineOutput, path.relative('Source', file)); - child_process.execSync(cmdLine, { - stdio : [process.stdin, process.stdout, process.stderr] - }); - }); +function combineWorkers(debug, optimizer, combineOutput) { + return Promise.join( + globby(['Source/Workers/cesiumWorkerBootstrapper.js', + 'Source/Workers/transferTypedArrayTest.js', + 'Source/ThirdParty/Workers/*.js']).then(function(files) { + return Promise.all(files.map(function(file) { + return requirejsOptimize({ + wrap : false, + useStrict : true, + optimize : optimizer, + optimizeCss : 'standard', + pragmas : { + debug : debug + }, + baseUrl : '.', + skipModuleInsertion : true, + include : file.slice(0, -3), + out : path.join(combineOutput, path.relative('Source', file)) + }); + })); + }), + globby(['Source/Workers/*.js', + '!Source/Workers/cesiumWorkerBootstrapper.js', + '!Source/Workers/transferTypedArrayTest.js', + '!Source/ThirdParty/Workers/*.js']).then(function(files) { + return Promise.all(files.map(function(file) { + return requirejsOptimize({ + wrap : true, + useStrict : true, + optimize : optimizer, + optimizeCss : 'standard', + pragmas : { + debug : debug + }, + baseUrl : '.', + include : file.slice(0, -3), + out : path.join(combineOutput, path.relative('Source', file)) + }); + })); + }) + ); } function minifyCSS(outputDirectory) { - var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); - var rjsOptions = path.join('Tools', 'build.js'); - - return gulp.src('Source/**/*.css', - { - base : 'Source', - noDir : true - }) - .pipe(gulp.dest(outputDirectory)) - .on('finish', function(err) { - if (err) { - throw err; - } - - var files = globby.sync(outputDirectory + '/**/*.css'); - files.forEach(function(file) { - var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' cssIn=' + file + ' out=' + file; - child_process.execSync(cmdLine, { - stdio : [process.stdin, process.stdout, process.stderr] - }); - }); + return globby('Source/**/*.css').then(function(files) { + return Promise.all(files.map(function(file) { + return requirejsOptimize({ + wrap : true, + useStrict : true, + optimizeCss : 'standard', + pragmas : { + debug : true + }, + cssIn : file, + out : path.join(outputDirectory, path.relative('Source', file)) }); + })); + }); } function combineJavaScript(options) { - var optimizer = options.minify ? 'uglify2' : 'none'; + var optimizer = options.optimizer; var outputDirectory = options.outputDirectory; var removePragmas = options.removePragmas; var combineOutput = path.join('Build', 'combineOutput', optimizer); var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js')); - combineJavaScriptCombineCesium(!removePragmas, optimizer, combineOutput); - combineJavaScriptCombineCesiumWorkers(!removePragmas, optimizer, combineOutput); - - var streams = []; - - //copy to build folder with copyright header added at the top - streams.push(gulp.src([combineOutput + '/**']) - .pipe(gulpInsert.prepend(copyrightHeader)) - .pipe(gulp.dest(outputDirectory)) - .on('finish', function(err) { - if (err) { - throw err; - } - rimraf.sync(combineOutput); - })); - - var everythingElse = ['Source/**', '!**/*.js', '!**/*.glsl']; - if (options.minify) { - streams.push(minifyCSS(path.join('Build', 'Cesium'))); - everythingElse.push('!**/*.css'); - } - streams.push(gulp.src(everythingElse, {nodir : true}) - .pipe(gulp.dest(outputDirectory))); + var promise = Promise.join( + combineCesium(!removePragmas, optimizer, combineOutput), + combineWorkers(!removePragmas, optimizer, combineOutput) + ); + + return promise.then(function() { + var promises = []; + + //copy to build folder with copyright header added at the top + var stream = gulp.src([combineOutput + '/**']) + .pipe(gulpInsert.prepend(copyrightHeader)) + .pipe(gulp.dest(outputDirectory)); + + promises.push(streamToPromise(stream)); - return eventStream.merge(streams); + var everythingElse = ['Source/**', '!**/*.js', '!**/*.glsl']; + + if (optimizer === 'uglify2') { + promises.push(minifyCSS(outputDirectory)); + everythingElse.push('!**/*.css'); + } + + stream = gulp.src(everythingElse, {nodir : true}).pipe(gulp.dest(outputDirectory)); + promises.push(streamToPromise(stream)); + + return Promise.all(promises).then(function() { + rimraf.sync(combineOutput); + }); + }); } function glslToJavaScript(minify, minifyStateFilePath) { @@ -721,68 +742,89 @@ var sandcastleJsHintOptions = ' + contents + ';'; function buildCesiumViewer() { var cesiumViewerOutputDirectory = 'Build/Apps/CesiumViewer'; var cesiumViewerStartup = path.join(cesiumViewerOutputDirectory, 'CesiumViewerStartup.js'); + var cesiumViewerCss = path.join(cesiumViewerOutputDirectory, 'CesiumViewer.css'); mkdirp.sync(cesiumViewerOutputDirectory); - var rjsPath = path.join('ThirdParty', 'requirejs-2.1.9', 'r.js'); - var rjsOptions = path.join('Tools', 'build.js'); + var promise = Promise.join( + requirejsOptimize({ + wrap : true, + useStrict : true, + optimizeCss : 'standard', + pragmas : { + debug : false + }, + optimize : 'uglify2', + mainConfigFile : 'Apps/CesiumViewer/CesiumViewerStartup.js', + name : 'CesiumViewerStartup', + out : cesiumViewerStartup + }), + requirejsOptimize({ + wrap : true, + useStrict : true, + optimizeCss : 'standard', + pragmas : { + debug : false + }, + cssIn : 'Apps/CesiumViewer/CesiumViewer.css', + out : cesiumViewerCss + }) + ); - //mainConfigFile must be relative to the build.js file - var cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' pragmas.debug=false' + - ' optimize=uglify2 mainConfigFile=../Apps/CesiumViewer/CesiumViewerStartup.js' + - ' name=CesiumViewerStartup out=' + cesiumViewerStartup; - child_process.execSync(cmdLine, { - stdio : [process.stdin, process.stdout, process.stderr] - }); + promise = promise.then(function() { + var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js')); - var cesiumViewerCss = path.join(cesiumViewerOutputDirectory, 'CesiumViewer.css'); - cmdLine = 'node ' + rjsPath + ' -o ' + rjsOptions + ' cssIn=Apps/CesiumViewer/CesiumViewer.css out=' + cesiumViewerCss; - child_process.execSync(cmdLine, { - stdio : [process.stdin, process.stdout, process.stderr] - }); + var stream = eventStream.merge( + gulp.src(cesiumViewerStartup) + .pipe(gulpInsert.prepend(copyrightHeader)) + .pipe(gulpReplace('../../Source', '.')) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')), - //add copyright header - var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js')); + gulp.src(cesiumViewerCss) + .pipe(gulpReplace('../../Source', '.')), - return eventStream.merge( - gulp.src(cesiumViewerStartup) - .pipe(gulpInsert.prepend(copyrightHeader)) - .pipe(gulpReplace('../../Source', '.')) - .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) - .pipe(gulp.dest(cesiumViewerOutputDirectory)), - - gulp.src(['Apps/CesiumViewer/**', - '!Apps/CesiumViewer/**/*.js', - '!Apps/CesiumViewer/**/*.css']) - .pipe(gulpReplace('../../Source', '.')) - .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) - .pipe(gulp.dest(cesiumViewerOutputDirectory)), - - gulp.src(['ThirdParty/requirejs-2.1.9/require.min.js']) - .pipe(gulpRename('require.js')) - .pipe(gulp.dest(cesiumViewerOutputDirectory)), - - gulp.src(['Build/Cesium/Assets/**', - 'Build/Cesium/Workers/**', - 'Build/Cesium/ThirdParty/Workers/**', - 'Build/Cesium/Widgets/**', - '!Build/Cesium/Widgets/**/*.css'], - { - base : 'Build/Cesium', - nodir : true - }) - .pipe(gulpReplace('../../Source', '.')) - .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) - .pipe(gulp.dest(cesiumViewerOutputDirectory)), - - gulp.src(['Build/Cesium/Widgets/InfoBox/InfoBoxDescription.css'], - { + gulp.src(['Apps/CesiumViewer/index.html']) + .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')), + + gulp.src(['Apps/CesiumViewer/**', + '!Apps/CesiumViewer/index.html', + '!Apps/CesiumViewer/**/*.js', + '!Apps/CesiumViewer/**/*.css']), + + gulp.src(['ThirdParty/requirejs-2.1.9/require.min.js']) + .pipe(gulpRename('require.js')), + + gulp.src(['Build/Cesium/Assets/**', + 'Build/Cesium/Workers/**', + 'Build/Cesium/ThirdParty/Workers/**', + 'Build/Cesium/Widgets/**', + '!Build/Cesium/Widgets/**/*.css'], + { + base : 'Build/Cesium', + nodir : true + }), + + gulp.src(['Build/Cesium/Widgets/InfoBox/InfoBoxDescription.css'], { base : 'Build/Cesium' - }) - .pipe(gulpReplace('../../Source', '.')) - .pipe(gulpReplace('../../ThirdParty/requirejs-2.1.9', '.')) - .pipe(gulp.dest(cesiumViewerOutputDirectory)), + }), - gulp.src(['web.config']) - .pipe(gulp.dest(cesiumViewerOutputDirectory)) - ); + gulp.src(['web.config']) + ); + + return streamToPromise(stream.pipe(gulp.dest(cesiumViewerOutputDirectory))); + }); + + return promise; +} + +function requirejsOptimize(config) { + return new Promise(function(resolve, reject) { + requirejs.optimize(config, resolve, reject); + }); +} + +function streamToPromise(stream) { + return new Promise(function(resolve, reject) { + stream.on('finish', resolve); + stream.on('end', reject); + }); } \ No newline at end of file diff --git a/package.json b/package.json index df5e235389a9..510a123682a2 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "async": "^1.4.2", + "bluebird": "^2.10.2", "compression": "1.6.0", "event-stream": "^3.3.2", "express": "4.13.3", @@ -24,6 +25,7 @@ "jshint-stylish": "^2.0.1", "mkdirp": "^0.5.1", "request": "2.65.0", + "requirejs": "^2.1.20", "rimraf": "^2.4.3", "strip-comments": "^0.3.2", "yargs": "3.27.0" @@ -38,8 +40,8 @@ "combineRelease": "gulp combineRelease", "generateDocumentation": "gulp generateDocumentation", "instrumentForCoverage": "gulp instrumentForCoverage", - "jsHint": "gulp jsHint --silent", - "jsHint-watch": "gulp jsHint-watch --silent", + "jsHint": "gulp jsHint", + "jsHint-watch": "gulp jsHint-watch", "makeZipFile": "gulp makeZipFile", "minify": "gulp minify", "minifyRelease": "gulp minifyRelease", From a1406897fa0f459d3567e9866d5c0e9deae8b0e3 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 18 Oct 2015 13:48:20 -0400 Subject: [PATCH 03/21] Fix Node 0.10 support Go back to using it for Travis. Also fix an issue causing makeZipFile to have incomplete data on Linux. --- .travis.yml | 2 +- gulpfile.js | 68 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27cf02d7e417..2dfa93e1b8e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "0.12" + - "0.10" sudo: false script: - npm run jsHint && npm run release diff --git a/gulpfile.js b/gulpfile.js index 053aaa2729ab..ec8533bf20c3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -93,26 +93,41 @@ gulp.task('clean', function(done) { async.forEach(filesToClean, rimraf, done); }); -gulp.task('cloc', ['build'], function(done) { +gulp.task('cloc', ['build'], function() { var glsl = globby.sync(['Source/Shaders/*.glsl', 'Source/Shaders/**/*.glsl', 'Source/main.js']); glsl = glsl.join(' '); var clockPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); var cloc_definitions = path.join('Tools', 'cloc-1.60', 'cloc_definitions'); - console.log('Source:'); - child_process.execSync('perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + - ' Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + - glsl, { - stdio : [process.stdin, process.stdout, process.stderr] - }); - - console.log('Specs:'); - child_process.execSync('perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/', { - stdio : [process.stdin, process.stdout, process.stderr] - }); + var cmdLine; + return Promise.join( + new Promise(function(resolve, reject) { + cmdLine = 'perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + + ' Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + glsl; + child_process.exec(cmdLine, function(error, stdout, stderr) { + if (error) { + console.log(stderr); + return reject(error); + } + console.log('Source:'); + console.log(stdout); + return resolve(); + }); + }), - done(); + new Promise(function(resolve, reject) { + cmdLine = 'perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/'; + child_process.exec(cmdLine, function(error, stdout, stderr) { + if (error) { + console.log(stderr); + return reject(error); + } + console.log('Specs:'); + console.log(stdout); + return resolve(); + }); + })); }); gulp.task('combine', ['generateStubs'], function() { @@ -147,15 +162,23 @@ gulp.task('combineRelease', ['generateStubs'], function() { gulp.task('generateDocumentation', function() { var envPathSeperator = os.platform() === 'win32' ? ';' : ':'; - child_process.execSync('jsdoc --configure Tools/jsdoc/conf.json', { - stdio : [process.stdin, process.stdout, process.stderr], - env : { - PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin', - CESIUM_VERSION : packageJson.version - } + return new Promise(function(resolve, reject) { + child_process.exec('jsdoc --configure Tools/jsdoc/conf.json', { + stdio : [process.stdin, process.stdout, process.stderr], + env : { + PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin', + CESIUM_VERSION : packageJson.version + } + }, function(error, stdout, stderr) { + if (error) { + console.log(stderr); + return reject(error); + } + console.log(stdout); + var stream = gulp.src('Documentation/Images/**').pipe(gulp.dest('Build/Documentation/Images')); + return streamToPromise(stream).then(resolve); + }); }); - - return gulp.src('Documentation/Images/**').pipe(gulp.dest('Build/Documentation/Images')); }); gulp.task('instrumentForCoverage', ['build'], function(done) { @@ -180,14 +203,13 @@ gulp.task('jsHint-watch', function() { }); }); -gulp.task('makeZipFile', ['release'], function() { +gulp.task('makeZipFile', /*['release'],*/ function() { var builtSrc = gulp.src([ 'Build/Apps/**', 'Build/Cesium/**', 'Build/CesiumUnminified/**', 'Build/Documentation/**' ], { - root : 'Build', base : '.' }); From d12c5a04e9cf79a9a276fb14bd89e20483f03a00 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 18 Oct 2015 14:36:55 -0400 Subject: [PATCH 04/21] Ongoing gulp work 1. Remove debug code 2. Fix documentation github links 3. Fix accidental include of development gallery directory. --- gulpfile.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ec8533bf20c3..25ceb64675b2 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -28,6 +28,11 @@ var packageJson = require('./package.json'); var noDevelopmentGallery = process.argv[2] === 'release' || process.argv[2] === 'makeZipFile'; var copyUnminified = process.argv[2] === 'combine' || process.argv[2] === 'default' || process.argv[2] === undefined; +var version = packageJson.version; +if (/\.0$/.test(version)) { + version = version.substring(0, version.length - 2); +} + var sourceFiles = ['Source/**/*.js', '!Source/*.js', '!Source/Workers/**', @@ -167,7 +172,7 @@ gulp.task('generateDocumentation', function() { stdio : [process.stdin, process.stdout, process.stderr], env : { PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin', - CESIUM_VERSION : packageJson.version + CESIUM_VERSION : version } }, function(error, stdout, stderr) { if (error) { @@ -203,7 +208,7 @@ gulp.task('jsHint-watch', function() { }); }); -gulp.task('makeZipFile', /*['release'],*/ function() { +gulp.task('makeZipFile', ['release'], function() { var builtSrc = gulp.src([ 'Build/Apps/**', 'Build/Cesium/**', @@ -215,7 +220,7 @@ gulp.task('makeZipFile', /*['release'],*/ function() { var staticSrc = gulp.src([ 'Apps/**', - '!Apps/Sandcastle/gallery/development', + '!Apps/Sandcastle/gallery/development/**', 'Source/**', 'Specs/**', 'ThirdParty/**', @@ -229,16 +234,12 @@ gulp.task('makeZipFile', /*['release'],*/ function() { 'README.md', 'web.config' ], { - base : '.' + base : '.', + nodir : true }); var indexSrc = gulp.src('index.release.html').pipe(gulpRename("index.html")); - var version = packageJson.version; - if (/\.0$/.test(version)) { - version = version.substring(0, version.length - 2); - } - return eventStream.merge(builtSrc, staticSrc, indexSrc) .pipe(gulpZip('Cesium-' + version + '.zip')) .pipe(gulp.dest('.')); @@ -687,15 +688,13 @@ function createCesiumJs() { assignments.push('Cesium' + assignmentName + ' = ' + parameterName + ';'); }); - var version = packageJson.version; - var contents = '\ /*global define*/\n\ define([' + moduleIds.join(', ') + '], function(' + parameters.join(', ') + ') {\n\ "use strict";\n\ /*jshint sub:true*/\n\ var Cesium = {\n\ - VERSION : "' + version + '",\n\ + VERSION : "' + packageJson.version + '",\n\ _shaders : {}\n\ };\n\ ' + assignments.join('\n ') + '\n\ From aecb78a4b8c17f73c717c3da79e89b3ae287a77d Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 18 Oct 2015 18:01:56 -0400 Subject: [PATCH 05/21] Add build-watch gulp task Also clean up exec usage. --- gulpfile.js | 24 +++++++++++++++++++----- package.json | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 25ceb64675b2..1818806fa7ce 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -39,6 +39,10 @@ var sourceFiles = ['Source/**/*.js', '!Source/ThirdParty/Workers/**', 'Source/Workers/createTaskProcessorWorker.js']; +var buildFiles = ['Specs/**/*.js', + '!Specs/SpecList.js', + 'Source/Shaders/**/*.glsl']; + var jsHintFiles = ['Source/**/*.js', '!Source/Shaders/**', '!Source/ThirdParty/**', @@ -90,6 +94,10 @@ gulp.task('build', function(done) { done(); }); +gulp.task('build-watch', function() { + gulp.watch(buildFiles, ['build']); +}); + gulp.task('buildApps', ['combine', 'minifyRelease'], function() { return buildCesiumViewer(); }); @@ -169,7 +177,6 @@ gulp.task('generateDocumentation', function() { return new Promise(function(resolve, reject) { child_process.exec('jsdoc --configure Tools/jsdoc/conf.json', { - stdio : [process.stdin, process.stdout, process.stderr], env : { PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin', CESIUM_VERSION : version @@ -189,10 +196,17 @@ gulp.task('generateDocumentation', function() { gulp.task('instrumentForCoverage', ['build'], function(done) { var jscoveragePath = path.join('Tools', 'jscoverage-0.5.1', 'jscoverage.exe'); var cmdLine = jscoveragePath + ' Source Instrumented --no-instrument=./ThirdParty'; - child_process.exec(cmdLine, {stdio : [process.stdin, process.stdout, process.stderr]}, done); + child_process.exec(cmdLine, function(error, stdout, stderr) { + if (error) { + console.log(stderr); + return done(error); + } + console.log(stdout); + done(); + }); }); -gulp.task('jsHint', ['build'], function() { +gulp.task('jsHint', function() { return gulp.src(jsHintFiles) .pipe(jshint.extract('auto')) .pipe(jshint()) @@ -752,12 +766,12 @@ function createSandcastleJsHintOptions() { jsHintOptions.predef = ['JSON', 'require', 'console', 'Sandcastle', 'Cesium']; var contents = JSON.stringify(jsHintOptions, null, 2); - fs.writeFile(path.join('Apps', 'Sandcastle', '.jshintrc'), contents); + fs.writeFileSync(path.join('Apps', 'Sandcastle', '.jshintrc'), contents); contents = '\ // This file is automatically rebuilt by the Cesium build process.\n\ var sandcastleJsHintOptions = ' + contents + ';'; - fs.writeFile(path.join('Apps', 'Sandcastle', 'jsHintOptions.js'), contents); + fs.writeFileSync(path.join('Apps', 'Sandcastle', 'jsHintOptions.js'), contents); } function buildCesiumViewer() { diff --git a/package.json b/package.json index 510a123682a2..e4dc3647e27a 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "scripts": { "start": "node server.js", "build": "gulp build", + "build-watch": "gulp build-watch", "buildApps": "gulp buildApps", "clean": "gulp clean", "cloc": "gulp cloc", From bc1ea1eb31a0a753583459ba7b4c0db4d0442553 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Sun, 18 Oct 2015 19:39:12 -0400 Subject: [PATCH 06/21] Fix almond loader. --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 1818806fa7ce..45542d6b5e4f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -458,7 +458,7 @@ function combineCesium(debug, optimizer, combineOutput) { }, baseUrl : 'Source', skipModuleInsertion : true, - //name : path.join('..', 'ThirdParty', 'almond-0.2.6', 'almond.js'), + name : path.join('..', 'ThirdParty', 'almond-0.2.6', 'almond'), include : 'main', out : path.join(combineOutput, 'Cesium.js') }); From 845e253da06c5be56224a68048b31fa344d989da Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 19 Oct 2015 16:15:45 -0400 Subject: [PATCH 07/21] Switch eclipse launch configurations to gulp. --- .externalToolBuilders/automaticBuild.launch | 15 ++++--------- launches/build.launch | 25 +++++++-------------- launches/buildApps.launch | 19 +++++----------- launches/clean.launch | 19 +++++----------- launches/combine.launch | 19 +++++----------- launches/generateDocumentation.launch | 19 +++++----------- launches/instrumentForCoverage.launch | 19 +++++----------- launches/makeZipFile.launch | 19 +++++----------- launches/minify.launch | 19 +++++----------- launches/release.launch | 19 +++++----------- 10 files changed, 52 insertions(+), 140 deletions(-) diff --git a/.externalToolBuilders/automaticBuild.launch b/.externalToolBuilders/automaticBuild.launch index e62321e0e9df..83c0e8b1ffd2 100644 --- a/.externalToolBuilders/automaticBuild.launch +++ b/.externalToolBuilders/automaticBuild.launch @@ -1,16 +1,9 @@ - - - - - - + - - - - - + + + diff --git a/launches/build.launch b/launches/build.launch index 9077e9b71ce6..1e1b0cef8f58 100644 --- a/launches/build.launch +++ b/launches/build.launch @@ -1,19 +1,10 @@ - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/launches/buildApps.launch b/launches/buildApps.launch index 7511b418114f..7d2da3bb5569 100644 --- a/launches/buildApps.launch +++ b/launches/buildApps.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/clean.launch b/launches/clean.launch index 4455a37b9519..56a6d8ac6b16 100644 --- a/launches/clean.launch +++ b/launches/clean.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/combine.launch b/launches/combine.launch index 27fa6d679ab0..ba47fec26fd4 100644 --- a/launches/combine.launch +++ b/launches/combine.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/generateDocumentation.launch b/launches/generateDocumentation.launch index 3190168e7e8a..ba6fa9b406c0 100644 --- a/launches/generateDocumentation.launch +++ b/launches/generateDocumentation.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/instrumentForCoverage.launch b/launches/instrumentForCoverage.launch index febd332c25f5..76ed4fb1be65 100644 --- a/launches/instrumentForCoverage.launch +++ b/launches/instrumentForCoverage.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/makeZipFile.launch b/launches/makeZipFile.launch index e42377388366..843477cde9b7 100644 --- a/launches/makeZipFile.launch +++ b/launches/makeZipFile.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/minify.launch b/launches/minify.launch index e26fa2d8959e..9a36433246ae 100644 --- a/launches/minify.launch +++ b/launches/minify.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + diff --git a/launches/release.launch b/launches/release.launch index 4ac00159ae55..c9ae048e39ee 100644 --- a/launches/release.launch +++ b/launches/release.launch @@ -1,19 +1,10 @@ - - - - - - - - + - - - - - - + + + + From 19add8ca175aa74a8f280d30d8d9c9804cf0097f Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 19 Oct 2015 16:20:51 -0400 Subject: [PATCH 08/21] Add `build` back as a `jsHint` dependancy. --- gulpfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 45542d6b5e4f..f5aae38ad2ca 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -206,7 +206,7 @@ gulp.task('instrumentForCoverage', ['build'], function(done) { }); }); -gulp.task('jsHint', function() { +gulp.task('jsHint', ['build'], function() { return gulp.src(jsHintFiles) .pipe(jshint.extract('auto')) .pipe(jshint()) @@ -862,4 +862,4 @@ function streamToPromise(stream) { stream.on('finish', resolve); stream.on('end', reject); }); -} \ No newline at end of file +} From 554faffc74741289d2a4d8abfd0e6c5dff4dec4b Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 19 Oct 2015 19:11:53 -0400 Subject: [PATCH 09/21] Fix stubs generation. --- gulpfile.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index f5aae38ad2ca..3afc4aa9aa79 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -289,7 +289,7 @@ gulp.task('generateStubs', ['build'], function(done) { globby.sync(sourceFiles).forEach(function(file) { file = path.relative('Source', file); - var moduleId = file.replace(/\\/, '/'); + var moduleId = file.replace(/\\/g, '/'); moduleId = moduleId.substring(0, moduleId.lastIndexOf('.')); var baseName = path.basename(file); @@ -586,13 +586,14 @@ function glslToJavaScript(minify, minifyStateFilePath) { var jsFile = path.join(path.dirname(glslFile), baseName) + '.js'; // identify built in functions, structs, and constants - if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Functions'))) === 0) { + var baseDir = path.join('Source', 'Shaders', 'Builtin'); + if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Functions'))) === 0) { builtinFunctions.push(baseName); } - else if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Constants'))) === 0) { + else if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Constants'))) === 0) { builtinConstants.push(baseName); } - else if (glslFile.indexOf(path.normalize(path.join('Source', 'Shaders', 'Builtin', 'Structs'))) === 0) { + else if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Structs'))) === 0) { builtinStructs.push(baseName); } From 4addf0d8ab25711748fc03d08a0b600c8eafd5b1 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 19 Oct 2015 21:52:33 -0400 Subject: [PATCH 10/21] createTaskProcessorWorker was not being properly excluded. --- gulpfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/gulpfile.js b/gulpfile.js index 3afc4aa9aa79..c781514aff17 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -488,6 +488,7 @@ function combineWorkers(debug, optimizer, combineOutput) { globby(['Source/Workers/*.js', '!Source/Workers/cesiumWorkerBootstrapper.js', '!Source/Workers/transferTypedArrayTest.js', + '!Source/Workers/createTaskProcessorWorker.js', '!Source/ThirdParty/Workers/*.js']).then(function(files) { return Promise.all(files.map(function(file) { return requirejsOptimize({ From 26452fd20e12a2b8e30b630286dac87f7a05ce04 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Mon, 19 Oct 2015 23:26:00 -0400 Subject: [PATCH 11/21] Fix issues with combined Workers It was only exposed during the release tests. --- gulpfile.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index c781514aff17..ea1c4508de31 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -289,8 +289,7 @@ gulp.task('generateStubs', ['build'], function(done) { globby.sync(sourceFiles).forEach(function(file) { file = path.relative('Source', file); - var moduleId = file.replace(/\\/g, '/'); - moduleId = moduleId.substring(0, moduleId.lastIndexOf('.')); + var moduleId = filePathToModuleId(file); var baseName = path.basename(file); var propertyName = baseName.substring(0, baseName.lastIndexOf('.')); @@ -478,9 +477,9 @@ function combineWorkers(debug, optimizer, combineOutput) { pragmas : { debug : debug }, - baseUrl : '.', + baseUrl : 'Source', skipModuleInsertion : true, - include : file.slice(0, -3), + include : filePathToModuleId(path.relative('Source', file)), out : path.join(combineOutput, path.relative('Source', file)) }); })); @@ -499,8 +498,8 @@ function combineWorkers(debug, optimizer, combineOutput) { pragmas : { debug : debug }, - baseUrl : '.', - include : file.slice(0, -3), + baseUrl : 'Source', + include : filePathToModuleId(path.relative('Source', file)), out : path.join(combineOutput, path.relative('Source', file)) }); })); @@ -687,19 +686,19 @@ function createCesiumJs() { globby.sync(sourceFiles).forEach(function(file) { file = path.relative('Source', file); - var moduleId = path.normalize(file); - moduleId = moduleId.substring(0, moduleId.lastIndexOf('.')); + var moduleId = file; + moduleId = filePathToModuleId(moduleId); var baseName = path.basename(file); var assignmentName = baseName.substring(0, baseName.lastIndexOf('.')); assignmentName = "['" + assignmentName + "']"; - if (moduleId.indexOf(path.normalize('Source\\Shaders\\')) === 0) { + if (moduleId.indexOf('Source/Shaders/') === 0) { assignmentName = '._shaders' + assignmentName; } var parameterName = moduleId.replace(nonIdentifierRegexp, '_'); - moduleIds.push("'./" + moduleId.replace(/\\/g, '/') + "'"); + moduleIds.push("'./" + moduleId + "'"); parameters.push(parameterName); assignments.push('Cesium' + assignmentName + ' = ' + parameterName + ';'); }); @@ -853,6 +852,10 @@ function buildCesiumViewer() { return promise; } +function filePathToModuleId(moduleId) { + return moduleId.substring(0, moduleId.lastIndexOf('.')).replace(/\\/g, '/'); +} + function requirejsOptimize(config) { return new Promise(function(resolve, reject) { requirejs.optimize(config, resolve, reject); From 221590ddb1248d028c78c65523089080a43cf441 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 21 Oct 2015 11:30:50 -0400 Subject: [PATCH 12/21] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 073a600f972f..967676c265c9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Change Log * Fixed token issue in `ArcGisMapServerImageryProvider`. * `ImageryLayerFeatureInfo` now has an `imageryLayer` property, indicating the layer that contains the feature. * Added `BoxOutlineGeometry.fromAxisAlignedBoundingBox` and `BoxGeometry.fromAxisAlignedBoundingBox` functions. +* Switched to [gulp](http://gulpjs.com/) for all build tasks. `Java` and `ant` are no longer required to develop Cesium. [#3106](https://github.com/AnalyticalGraphicsInc/cesium/pull/3106) * The WebGL setting of `failIfMajorPerformanceCaveat` now defaults to `false`, which is the official WebGL default. This improves compatibility with out-of-date drivers and remote desktop sessions. Cesium will run slower in these cases instead of simply failing to load. ### 1.14 - 2015-10-01 From bb839efdb4a5a41891e5f7e38910f44b0bd12c7e Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 21 Oct 2015 17:54:08 -0400 Subject: [PATCH 13/21] Changes after review. --- gulpfile.js | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ea1c4508de31..98401ec61e53 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -107,30 +107,32 @@ gulp.task('clean', function(done) { }); gulp.task('cloc', ['build'], function() { - var glsl = globby.sync(['Source/Shaders/*.glsl', 'Source/Shaders/**/*.glsl', 'Source/main.js']); - glsl = glsl.join(' '); - - var clockPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); + var cmdLine; + var clokPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); var cloc_definitions = path.join('Tools', 'cloc-1.60', 'cloc_definitions'); - var cmdLine; - return Promise.join( - new Promise(function(resolve, reject) { - cmdLine = 'perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + - ' Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + glsl; - child_process.exec(cmdLine, function(error, stdout, stderr) { - if (error) { - console.log(stderr); - return reject(error); - } - console.log('Source:'); - console.log(stdout); - return resolve(); - }); - }), + //Run cloc on primary Source files only + var source = new Promise(function(resolve, reject) { + var glsl = globby.sync(['Source/Shaders/*.glsl', 'Source/Shaders/**/*.glsl']).join(' '); - new Promise(function(resolve, reject) { - cmdLine = 'perl ' + clockPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/'; + cmdLine = 'perl ' + clokPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + + ' Source/main.js Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + glsl; + + child_process.exec(cmdLine, function(error, stdout, stderr) { + if (error) { + console.log(stderr); + return reject(error); + } + console.log('Source:'); + console.log(stdout); + resolve(); + }); + }); + + //If running cloc on source succeeded, also run it on the tests. + return source.then(function() { + return new Promise(function(resolve, reject) { + cmdLine = 'perl ' + clokPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/'; child_process.exec(cmdLine, function(error, stdout, stderr) { if (error) { console.log(stderr); @@ -138,9 +140,10 @@ gulp.task('cloc', ['build'], function() { } console.log('Specs:'); console.log(stdout); - return resolve(); + resolve(); }); - })); + }); + }); }); gulp.task('combine', ['generateStubs'], function() { From f789a73e6e8c6eb52fffcfd375d56c5e47c6afa1 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 21 Oct 2015 17:55:46 -0400 Subject: [PATCH 14/21] Remove unecessary type casting. --- gulpfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 98401ec61e53..ce6a4d8ccf02 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -296,7 +296,7 @@ gulp.task('generateStubs', ['build'], function(done) { var baseName = path.basename(file); var propertyName = baseName.substring(0, baseName.lastIndexOf('.')); - propertyName = "['" + String(propertyName) + "']"; + propertyName = "['" + propertyName + "']"; contents += '\ define(\'' + moduleId + '\', function() {\n\ @@ -747,7 +747,7 @@ function createGalleryList() { globby.sync(fileList).forEach(function(file) { var demo = file.substring(24, file.lastIndexOf('.')).replace('\\', '/'); var demoObject = { - name : String(demo), + name : demo, date : fs.statSync(file).mtime.getTime() }; From 79b230b11a6bba74dbe6adcd6183299098fc0a27 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 21 Oct 2015 18:08:57 -0400 Subject: [PATCH 15/21] Fix shader minification. --- gulpfile.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index ce6a4d8ccf02..2c97eb563d39 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -25,8 +25,10 @@ var packageJson = require('./package.json'); //Gulp doesn't seem to have a way to get the currently running tasks for setting //per-task variables. We use the command line argument here to detect which task is being run. -var noDevelopmentGallery = process.argv[2] === 'release' || process.argv[2] === 'makeZipFile'; -var copyUnminified = process.argv[2] === 'combine' || process.argv[2] === 'default' || process.argv[2] === undefined; +var taskName = process.argv[2]; +var noDevelopmentGallery = taskName === 'release' || taskName === 'makeZipFile'; +var copyUnminified = taskName === 'combine' || taskName === 'default' || taskName === undefined; +var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile'; var version = packageJson.version; if (/\.0$/.test(version)) { @@ -86,7 +88,7 @@ gulp.task('default', ['combine']); gulp.task('build', function(done) { mkdirp.sync('Build'); - glslToJavaScript(false, 'Build/minifyShaders.state'); + glslToJavaScript(minifyShaders, 'Build/minifyShaders.state'); createCesiumJs(); createSpecList(); createGalleryList(); From 1cfa1bee45d89e670d21b18638b95f33a95f73b5 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 21 Oct 2015 18:22:10 -0400 Subject: [PATCH 16/21] Changes after review Clean up file path handling. --- gulpfile.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 2c97eb563d39..f9a82216b9d5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -296,8 +296,7 @@ gulp.task('generateStubs', ['build'], function(done) { file = path.relative('Source', file); var moduleId = filePathToModuleId(file); - var baseName = path.basename(file); - var propertyName = baseName.substring(0, baseName.lastIndexOf('.')); + var propertyName = path.basename(file, path.extname(file)); propertyName = "['" + propertyName + "']"; contents += '\ @@ -694,8 +693,7 @@ function createCesiumJs() { var moduleId = file; moduleId = filePathToModuleId(moduleId); - var baseName = path.basename(file); - var assignmentName = baseName.substring(0, baseName.lastIndexOf('.')); + var assignmentName = path.basename(file, path.extname(file)); assignmentName = "['" + assignmentName + "']"; if (moduleId.indexOf('Source/Shaders/') === 0) { assignmentName = '._shaders' + assignmentName; @@ -729,8 +727,7 @@ function createSpecList() { var specs = []; specFiles.forEach(function(file) { - var spec = file.substring(0, file.lastIndexOf('.')).replace('\\', '/'); - specs.push("'" + spec + "'"); + specs.push("'" + filePathToModuleId(file) + "'"); }); var contents = 'var specs = [' + specs.join(',') + '];'; @@ -747,7 +744,7 @@ function createGalleryList() { } globby.sync(fileList).forEach(function(file) { - var demo = file.substring(24, file.lastIndexOf('.')).replace('\\', '/'); + var demo = filePathToModuleId(path.relative('Apps/Sandcastle/gallery', file)); var demoObject = { name : demo, date : fs.statSync(file).mtime.getTime() From a3df692dbddf4f3be04f4b52d75e0c099b79d730 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 22 Oct 2015 11:03:54 -0400 Subject: [PATCH 17/21] Fix typo, again. --- gulpfile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index f9a82216b9d5..835d180ef1bf 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -110,14 +110,14 @@ gulp.task('clean', function(done) { gulp.task('cloc', ['build'], function() { var cmdLine; - var clokPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); + var clocPath = path.join('Tools', 'cloc-1.60', 'cloc-1.60.pl'); var cloc_definitions = path.join('Tools', 'cloc-1.60', 'cloc_definitions'); //Run cloc on primary Source files only var source = new Promise(function(resolve, reject) { var glsl = globby.sync(['Source/Shaders/*.glsl', 'Source/Shaders/**/*.glsl']).join(' '); - cmdLine = 'perl ' + clokPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + + cmdLine = 'perl ' + clocPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Source/main.js Source/Core/ Source/DataSources/ Source/Renderer/ Source/Scene/ Source/Widgets/ Source/Workers/ ' + glsl; child_process.exec(cmdLine, function(error, stdout, stderr) { @@ -134,7 +134,7 @@ gulp.task('cloc', ['build'], function() { //If running cloc on source succeeded, also run it on the tests. return source.then(function() { return new Promise(function(resolve, reject) { - cmdLine = 'perl ' + clokPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/'; + cmdLine = 'perl ' + clocPath + ' --quiet --progress-rate=0 --read-lang-def=' + cloc_definitions + ' Specs/'; child_process.exec(cmdLine, function(error, stdout, stderr) { if (error) { console.log(stderr); From d855fe5544061d385c7c22d726da523b571d199c Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 22 Oct 2015 13:30:43 -0400 Subject: [PATCH 18/21] Minify shaders when running `buildApps` --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 835d180ef1bf..23cb65b32efa 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -28,7 +28,7 @@ var packageJson = require('./package.json'); var taskName = process.argv[2]; var noDevelopmentGallery = taskName === 'release' || taskName === 'makeZipFile'; var copyUnminified = taskName === 'combine' || taskName === 'default' || taskName === undefined; -var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile'; +var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile' || taskName === 'buildApps'; var version = packageJson.version; if (/\.0$/.test(version)) { From 6061d19f9bf9b07a331c35414a0765b187304542 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 22 Oct 2015 13:33:59 -0400 Subject: [PATCH 19/21] Include Shaders subdirectories. --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 23cb65b32efa..a51935aa8d01 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -59,7 +59,7 @@ var jsHintFiles = ['Source/**/*.js', var filesToClean = ['Source/Cesium.js', 'Build', 'Instrumented', - 'Source/Shaders/**.js', + 'Source/Shaders/**/*.js', 'Specs/SpecList.js', 'Apps/Sandcastle/.jshintrc', 'Apps/Sandcastle/jsHintOptions.js', From fd1169cef6812990fa406733f5ee262f36f62be2 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 22 Oct 2015 15:26:55 -0400 Subject: [PATCH 20/21] More changes after review. --- gulpfile.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a51935aa8d01..30d68e47d195 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,6 +22,10 @@ var Promise = require('bluebird'); var requirejs = require('requirejs'); var packageJson = require('./package.json'); +var version = packageJson.version; +if (/\.0$/.test(version)) { + version = version.substring(0, version.length - 2); +} //Gulp doesn't seem to have a way to get the currently running tasks for setting //per-task variables. We use the command line argument here to detect which task is being run. @@ -30,11 +34,6 @@ var noDevelopmentGallery = taskName === 'release' || taskName === 'makeZipFile'; var copyUnminified = taskName === 'combine' || taskName === 'default' || taskName === undefined; var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile' || taskName === 'buildApps'; -var version = packageJson.version; -if (/\.0$/.test(version)) { - version = version.substring(0, version.length - 2); -} - var sourceFiles = ['Source/**/*.js', '!Source/*.js', '!Source/Workers/**', @@ -695,7 +694,7 @@ function createCesiumJs() { var assignmentName = path.basename(file, path.extname(file)); assignmentName = "['" + assignmentName + "']"; - if (moduleId.indexOf('Source/Shaders/') === 0) { + if (moduleId.indexOf('Shaders/') === 0) { assignmentName = '._shaders' + assignmentName; } @@ -712,7 +711,7 @@ define([' + moduleIds.join(', ') + '], function(' + parameters.join(', ') + ') { "use strict";\n\ /*jshint sub:true*/\n\ var Cesium = {\n\ - VERSION : "' + packageJson.version + '",\n\ + VERSION : "' + version + '",\n\ _shaders : {}\n\ };\n\ ' + assignments.join('\n ') + '\n\ From 798774f565684a01dd2c1546edf3ca178fdf4fee Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 22 Oct 2015 15:48:00 -0400 Subject: [PATCH 21/21] Hopefully last review comment. --- gulpfile.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 30d68e47d195..1b56b5dc6794 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -227,6 +227,10 @@ gulp.task('jsHint-watch', function() { }); gulp.task('makeZipFile', ['release'], function() { + //For now we regenerate the JS glsl to force it to be unminified in the release zip + //See https://github.com/AnalyticalGraphicsInc/cesium/pull/3106#discussion_r42793558 for discussion. + glslToJavaScript(false, 'Build/minifyShaders.state'); + var builtSrc = gulp.src([ 'Build/Apps/**', 'Build/Cesium/**',