diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 647a0062c57..44d6142a5a3 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -327,6 +327,12 @@ function packageTask(platform, arch, opts) { .pipe(rename('bin/' + product.applicationName))); } + // submit all stats that have been collected during + // the build phase + if (opts.stats) { + result.on('end', () => require('./lib/stats').submitAllStats()); + } + return result.pipe(vfs.dest(destination)); }; } @@ -342,14 +348,14 @@ gulp.task('clean-vscode-linux-arm', util.rimraf(path.join(buildRoot, 'VSCode-lin gulp.task('vscode-win32-ia32', ['optimize-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32')); gulp.task('vscode-win32-x64', ['optimize-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64')); -gulp.task('vscode-darwin', ['optimize-vscode', 'clean-vscode-darwin'], packageTask('darwin')); +gulp.task('vscode-darwin', ['optimize-vscode', 'clean-vscode-darwin'], packageTask('darwin', null, { stats: true })); gulp.task('vscode-linux-ia32', ['optimize-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32')); gulp.task('vscode-linux-x64', ['optimize-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64')); gulp.task('vscode-linux-arm', ['optimize-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm')); gulp.task('vscode-win32-ia32-min', ['minify-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32', { minified: true })); gulp.task('vscode-win32-x64-min', ['minify-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64', { minified: true })); -gulp.task('vscode-darwin-min', ['minify-vscode', 'clean-vscode-darwin'], packageTask('darwin', null, { minified: true })); +gulp.task('vscode-darwin-min', ['minify-vscode', 'clean-vscode-darwin'], packageTask('darwin', null, { minified: true, stats: true })); gulp.task('vscode-linux-ia32-min', ['minify-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32', { minified: true })); gulp.task('vscode-linux-x64-min', ['minify-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64', { minified: true })); gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm', { minified: true })); diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 4eda9210c1a..da0f48f0b55 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -19,6 +19,7 @@ var gulp = require("gulp"); var path = require("path"); var File = require("vinyl"); var vsce = require("vsce"); +var stats_1 = require("./stats"); var util2 = require("./util"); var assign = require("object-assign"); var remote = require("gulp-remote-src"); @@ -114,7 +115,7 @@ function fromLocal(extensionPath, sourceMappingURLBase) { filesStream.pipe(result); } }).catch(function (err) { return result.emit('error', err); }); - return result; + return result.pipe(stats_1.createStatsStream(path.basename(extensionPath))); } exports.fromLocal = fromLocal; function error(err) { diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 115adaca5df..48c01f152c6 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -11,6 +11,7 @@ import * as path from 'path'; import { Stream } from 'stream'; import * as File from 'vinyl'; import * as vsce from 'vsce'; +import { createStatsStream } from './stats'; import * as util2 from './util'; import assign = require('object-assign'); import remote = require('gulp-remote-src'); @@ -131,7 +132,7 @@ export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): }).catch(err => result.emit('error', err)); - return result; + return result.pipe(createStatsStream(path.basename(extensionPath))); } function error(err: any): Stream { diff --git a/build/lib/optimize.js b/build/lib/optimize.js index 60169cf1892..044780ba7fd 100644 --- a/build/lib/optimize.js +++ b/build/lib/optimize.js @@ -4,23 +4,24 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); -var path = require("path"); +var es = require("event-stream"); var gulp = require("gulp"); -var sourcemaps = require("gulp-sourcemaps"); -var filter = require("gulp-filter"); +var concat = require("gulp-concat"); var minifyCSS = require("gulp-cssnano"); +var filter = require("gulp-filter"); +var flatmap = require("gulp-flatmap"); +var sourcemaps = require("gulp-sourcemaps"); var uglify = require("gulp-uglify"); var composer = require("gulp-uglify/composer"); +var gulpUtil = require("gulp-util"); +var path = require("path"); +var pump = require("pump"); var uglifyes = require("uglify-es"); -var es = require("event-stream"); -var concat = require("gulp-concat"); var VinylFile = require("vinyl"); var bundle = require("./bundle"); -var util = require("./util"); -var gulpUtil = require("gulp-util"); -var flatmap = require("gulp-flatmap"); -var pump = require("pump"); var i18n_1 = require("./i18n"); +var stats_1 = require("./stats"); +var util = require("./util"); var REPO_ROOT_PATH = path.join(__dirname, '../..'); function log(prefix, message) { gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message); @@ -101,7 +102,8 @@ function toConcatStream(src, bundledFileHeader, sources, dest) { }); return es.readArray(treatedSources) .pipe(useSourcemaps ? util.loadSourcemaps() : es.through()) - .pipe(concat(dest)); + .pipe(concat(dest)) + .pipe(stats_1.createStatsStream(dest)); } function toBundleStream(src, bundledFileHeader, bundles) { return es.merge(bundles.map(function (bundle) { diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts index 038cf09dd21..8a35523dbe2 100644 --- a/build/lib/optimize.ts +++ b/build/lib/optimize.ts @@ -5,24 +5,25 @@ 'use strict'; -import * as path from 'path'; +import * as es from 'event-stream'; import * as gulp from 'gulp'; -import * as sourcemaps from 'gulp-sourcemaps'; -import * as filter from 'gulp-filter'; +import * as concat from 'gulp-concat'; import * as minifyCSS from 'gulp-cssnano'; +import * as filter from 'gulp-filter'; +import * as flatmap from 'gulp-flatmap'; +import * as sourcemaps from 'gulp-sourcemaps'; import * as uglify from 'gulp-uglify'; import * as composer from 'gulp-uglify/composer'; -import * as uglifyes from 'uglify-es'; -import * as es from 'event-stream'; -import * as concat from 'gulp-concat'; -import * as VinylFile from 'vinyl'; -import * as bundle from './bundle'; -import * as util from './util'; import * as gulpUtil from 'gulp-util'; -import * as flatmap from 'gulp-flatmap'; +import * as path from 'path'; import * as pump from 'pump'; import * as sm from 'source-map'; -import { processNlsFiles, Language } from './i18n'; +import * as uglifyes from 'uglify-es'; +import * as VinylFile from 'vinyl'; +import * as bundle from './bundle'; +import { Language, processNlsFiles } from './i18n'; +import { createStatsStream } from './stats'; +import * as util from './util'; const REPO_ROOT_PATH = path.join(__dirname, '../..'); @@ -121,10 +122,11 @@ function toConcatStream(src: string, bundledFileHeader: string, sources: bundle. return es.readArray(treatedSources) .pipe(useSourcemaps ? util.loadSourcemaps() : es.through()) - .pipe(concat(dest)); + .pipe(concat(dest)) + .pipe(createStatsStream(dest)); } -function toBundleStream(src:string, bundledFileHeader: string, bundles: bundle.IConcatFile[]): NodeJS.ReadWriteStream { +function toBundleStream(src: string, bundledFileHeader: string, bundles: bundle.IConcatFile[]): NodeJS.ReadWriteStream { return es.merge(bundles.map(function (bundle) { return toConcatStream(src, bundledFileHeader, bundle.sources, bundle.dest); })); diff --git a/build/lib/stats.js b/build/lib/stats.js new file mode 100644 index 00000000000..2b305db9911 --- /dev/null +++ b/build/lib/stats.js @@ -0,0 +1,92 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +var es = require("event-stream"); +var util = require("gulp-util"); +var Entry = /** @class */ (function () { + function Entry(name, totalCount, totalSize) { + this.name = name; + this.totalCount = totalCount; + this.totalSize = totalSize; + } + Entry.prototype.toString = function (pretty) { + if (!pretty) { + if (this.totalCount === 1) { + return this.name + ": " + this.totalSize + " bytes"; + } + else { + return this.name + ": " + this.totalCount + " files with " + this.totalSize + " bytes"; + } + } + else { + if (this.totalCount === 1) { + return "Stats for '" + util.colors.grey(this.name) + "': " + Math.round(this.totalSize / 1204) + "KB"; + } + else { + var count = this.totalCount < 100 + ? util.colors.green(this.totalCount.toString()) + : util.colors.red(this.totalCount.toString()); + return "Stats for '" + util.colors.grey(this.name) + "': " + count + " files, " + Math.round(this.totalSize / 1204) + "KB"; + } + } + }; + return Entry; +}()); +var _entries = new Map(); +function createStatsStream(group, log) { + var entry = new Entry(group, 0, 0); + _entries.set(entry.name, entry); + return es.through(function (data) { + var file = data; + if (typeof file.path === 'string') { + entry.totalCount += 1; + if (Buffer.isBuffer(file.contents)) { + entry.totalSize += file.contents.length; + } + else if (file.stat && typeof file.stat.size === 'number') { + entry.totalSize += file.stat.size; + } + else { + // funky file... + } + } + this.emit('data', data); + }, function () { + if (log) { + if (entry.totalCount === 1) { + util.log("Stats for '" + util.colors.grey(entry.name) + "': " + Math.round(entry.totalSize / 1204) + "KB"); + } + else { + var count = entry.totalCount < 100 + ? util.colors.green(entry.totalCount.toString()) + : util.colors.red(entry.totalCount.toString()); + util.log("Stats for '" + util.colors.grey(entry.name) + "': " + count + " files, " + Math.round(entry.totalSize / 1204) + "KB"); + } + } + this.emit('end'); + }); +} +exports.createStatsStream = createStatsStream; +function submitAllStats() { + var sorted = []; + // move entries for single files to the + // front + _entries.forEach(function (value) { + if (value.totalCount === 1) { + sorted.unshift(value); + } + else { + sorted.push(value); + } + }); + // todo@ramya/joh - send the data as telemetry event + // so that it can be stored in the datawarehouse + for (var _i = 0, sorted_1 = sorted; _i < sorted_1.length; _i++) { + var entry = sorted_1[_i]; + console.log(entry.toString(true)); + } +} +exports.submitAllStats = submitAllStats; diff --git a/build/lib/stats.ts b/build/lib/stats.ts new file mode 100644 index 00000000000..19dce0147d8 --- /dev/null +++ b/build/lib/stats.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as es from 'event-stream'; +import * as util from 'gulp-util'; +import * as File from 'vinyl'; + +class Entry { + constructor(readonly name: string, public totalCount: number, public totalSize: number) { } + + toString(pretty?: boolean): string { + if (!pretty) { + if (this.totalCount === 1) { + return `${this.name}: ${this.totalSize} bytes`; + } else { + return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`; + } + } else { + if (this.totalCount === 1) { + return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`; + + } else { + let count = this.totalCount < 100 + ? util.colors.green(this.totalCount.toString()) + : util.colors.red(this.totalCount.toString()); + + return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`; + } + } + } +} + +const _entries = new Map(); + +export function createStatsStream(group: string, log?: boolean): es.ThroughStream { + + const entry = new Entry(group, 0, 0); + _entries.set(entry.name, entry); + + return es.through(function (data) { + let file = data as File; + if (typeof file.path === 'string') { + entry.totalCount += 1; + if (Buffer.isBuffer(file.contents)) { + entry.totalSize += file.contents.length; + } else if (file.stat && typeof file.stat.size === 'number') { + entry.totalSize += file.stat.size; + } else { + // funky file... + } + } + this.emit('data', data); + }, function () { + if (log) { + if (entry.totalCount === 1) { + util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`); + + } else { + let count = entry.totalCount < 100 + ? util.colors.green(entry.totalCount.toString()) + : util.colors.red(entry.totalCount.toString()); + + util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`); + } + } + + this.emit('end'); + }); +} + +export function submitAllStats(): void { + let sorted: Entry[] = []; + // move entries for single files to the + // front + _entries.forEach(value => { + if (value.totalCount === 1) { + sorted.unshift(value); + } else { + sorted.push(value); + } + }); + // todo@ramya/joh - send the data as telemetry event + // so that it can be stored in the datawarehouse + for (const entry of sorted) { + console.log(entry.toString(true)); + } +}