Permalink
Browse files

fix build process for new minification

  • Loading branch information...
1 parent d906369 commit a818a60722cc32e3a42bbbd7c5e1b90d04c87ab7 @amccollum amccollum committed Feb 11, 2014
View
5 lib/main-build.js
@@ -43,7 +43,7 @@ var builder = require('ender-builder')
enderPackage.walkDependencies(ids, true, true, function (err, packages) {
if (err) return callback(err) // wrapper in ender-package
- builder(options, packages, function (err, outputFilename) {
+ builder(options, packages, function (err, files, filenames) {
if (err) return callback(err) // wrapped in write.js
out.finishedAssembly()
@@ -53,9 +53,10 @@ var builder = require('ender-builder')
if (!options.quiet) {
mainInfo.generateAndPrint(
out
- , outputFilename
+ , filenames.build
, options
, ids
+ , files
, callback
)
}
View
71 lib/main-info-util.js
@@ -1,71 +0,0 @@
-/*!
- * ENDER - The open module JavaScript framework
- *
- * Copyright (c) 2011-2012 @ded, @fat, @rvagg and other contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is furnished
- * to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-/******************************************************************************
- * Utility functions for the main-info module.
- */
-
-var zlib = require('zlib')
- , fs = require('fs')
- , async = require('async')
- , enderBuilder = require('ender-builder')
- , FilesystemError = require('./errors').FilesystemError
-
- // given a filename, return the 'raw', 'minified' and 'gzipped' sizes
- , sizes = function (options, filename, callback) {
- var sizes = {}
- , jobs = []
- // make a function that async.waterfall() can use
- , mkcb = function (prop, callback, errType) {
- return function (err, data) {
- if (err) return callback(errType ? new errType(err) : err)
- sizes[prop] = data.length
- callback(null, data)
- }
- }
-
- jobs.push(function (callback) {
- fs.readFile(filename, 'utf-8', mkcb('raw', callback, FilesystemError))
- })
-
- if (options.minifier != 'none') {
- jobs.push(function (data, callback) {
- enderBuilder.minify(options, data, mkcb('minify', callback))
- })
- jobs.push(function (data, callback) {
- zlib.gzip(data, mkcb('gzip', callback))
- })
- }
-
- // note we have to use waterfall cause each one depends on the data of the previous
- async.waterfall(
- jobs
- , function (err) {
- err ? callback(err) : callback(null, sizes)
- }
- )
- }
-
-module.exports.sizes = sizes
View
70 lib/main-info.js
@@ -31,31 +31,66 @@
*/
var async = require('async')
+ , fs = require('fs')
+ , zlib = require('zlib')
+
, enderPackage = require('ender-package')
- , util = require('./util')
, mainBuildUtil = require('./main-build-util')
- , mainInfoUtil = require('./main-info-util')
, parseContext = require('./parse-context')
+ , util = require('./util')
+
+ , CompressionError = require('./errors').CompressionError
+ , FilesystemError = require('./errors').FilesystemError
+
+ , generateAndPrint = function (out, buildName, options, ids, files, callback) {
+ var sizes = {}
+
+ , finish = function (callback) {
+ // build an `archy` tree representing the packages in the build
+ enderPackage.buildArchyTree(ids, true, function (err, archyTree) {
+ if (err) return callback(err) // wrapped in ender-package
+ out.buildInfo(buildName, options, sizes, archyTree)
+ callback()
+ })
+ }
+
+ , calculateSizes = function (callback) {
+ sizes.build = files.build.length
+
+ if (!files.minifiedBuild) return callback()
+ sizes.minifiedBuild = files.minifiedBuild.length
- , generateAndPrint = function (out, filename, options, ids, callback) {
- var loadSizesAndFinish = function (callback) {
- mainInfoUtil.sizes(options, filename, function (err, sizes) {
- if (err) return callback(err) // wrapped in main-info-util.js
-
- // build an `archy` tree representing the packages in the build
- enderPackage.buildArchyTree(ids, true, function (err, archyTree) {
- if (err) return callback(err) // wrapped in ender-package
- out.buildInfo(filename, options, sizes, archyTree)
- callback()
- })
+ zlib.gzip(files.minifiedBuild, function (err, data) {
+ if (err) return callback(new CompressionError(err))
+
+ sizes.gzippedMinifiedBuild = data.length
+ callback()
+ })
+ }
+
+ , loadFiles = function (callback) {
+ if (files) return callback()
+
+ var tasks = {}
+
+ tasks.build = fs.readFile.bind(null, buildName, 'utf-8')
+
+ if (options.minifier != 'none') {
+ tasks.minifiedBuild = fs.readFile.bind(null, buildName.replace(/\.js$/, '.min.js'), 'utf-8')
+ }
+
+ async.parallel(tasks, function (err, _files) {
+ if (err) return callback(new FilesystemError(err))
+ files = _files
+ callback()
})
}
, loadOptions = function (callback) {
if (options && ids) return callback()
// read 'Build: ...' and 'Packages: ...' from the head of the build file
- parseContext(filename, function (err, context) {
+ parseContext(buildName, function (err, context) {
if (err) return callback(err) // wrapped in source-build.js
options = context.options
@@ -67,7 +102,9 @@ var async = require('async')
async.series(
[
loadOptions
- , loadSizesAndFinish
+ , loadFiles
+ , calculateSizes
+ , finish
]
, callback
)
@@ -78,7 +115,8 @@ var async = require('async')
out
, util.getInputFilenameFromOptions(args)
, null // no options, read them from build file
- , null // no packages, read them from build file
+ , null // no package ids, read them from build file
+ , null // no files, read them from disk
, callback
)
}
View
7 lib/output/main-info-output.js
@@ -37,9 +37,10 @@ var archy = require('archy')
this.log('Your current build command is: ' + ('ender ' + argsParser.toContextString(options)).yellow)
this.log(
'Your current build size is: '
- + toKb(sizes.raw).yellow + ' raw'
- + (sizes.minify
- ? ', ' + toKb(sizes.minify).yellow + ' minified and ' + toKb(sizes.gzip).yellow + ' gzipped'
+ + toKb(sizes.build).yellow + ' raw'
+ + (sizes.minifiedBuild
+ ? ', ' + toKb(sizes.minifiedBuild).yellow + ' minified and '
+ + toKb(sizes.gzippedMinifiedBuild).yellow + ' gzipped'
: ''
)
View
3 package.json
@@ -18,10 +18,9 @@
, "ender-installer" : "ender-js/ender-installer#beta"
, "ender-package" : "ender-js/ender-package#beta"
, "ender-repository" : "ender-js/ender-repository#beta"
- , "ender-minify" : "~0.1.1"
, "colors" : "~0.6.0"
- , "async" : "~0.1.22"
+ , "async" : "~0.2.10"
, "hogan.js" : "~2.0.0"
, "archy" : "~0.0.2"
, "colors-tmpl" : "~0.1.0"
View
9 test/unit/main-build-test.js
@@ -53,7 +53,8 @@ buster.testCase('Build', {
, installedIdsArg = [ 'foobar@0.0.1' ]
, packagesArg = [ 'foobarDepPkg', 'foobarPkg' ]
, installResultsArg = [ 1, 2, 3 ]
- , filenameArg = { filename: 1 }
+ , buildFilesArg = { build: 'build' }
+ , buildFilenamesArg = { build: 'ender.js' }
// setup our stubs and mocks
mainBuildUtilMock
@@ -72,14 +73,14 @@ buster.testCase('Build', {
.withArgs(installedIdsArg, true, true)
.callsArgWith(3, null, packagesArg)
- builderStub.callsArgWith(2, null, filenameArg)
+ builderStub.callsArgWith(2, null, buildFilesArg, buildFilenamesArg)
outMock.expects('finishedAssembly').once()
mainInfoMock
.expects('generateAndPrint')
.once()
- .withArgs(out, filenameArg, optionsArg, installedIdsArg)
- .callsArg(4)
+ .withArgs(out, buildFilenamesArg.build, optionsArg, installedIdsArg, buildFilesArg)
+ .callsArg(5)
// subvert single-function modules
requireSubvert.subvert('ender-builder', builderStub)
View
25 test/unit/main-info-test.js
@@ -30,15 +30,17 @@ var buster = require('bustermove')
buster.testCase('Info', {
'setUp': function () {
- var enderPackage = require('ender-package')
+ var fs = require('fs')
+ , zlib = require('zlib')
+ , enderPackage = require('ender-package')
, mainBuildUtil = require('../../lib/main-build-util')
- , mainInfoUtil = require('../../lib/main-info-util')
, out = require('../../lib/output/main-info-output').create()
this.runTest = function (options, expectedFilename, done) {
- var enderPackageMock = this.mock(enderPackage)
+ var fsMock = this.mock(fs)
+ , zlibMock = this.mock(zlib)
+ , enderPackageMock = this.mock(enderPackage)
, mainBuildUtilMock = this.mock(mainBuildUtil)
- , mainInfoUtilMock = this.mock(mainInfoUtil)
, outMock = this.mock(out)
, parseContextStub = this.stub()
, mainInfo
@@ -57,11 +59,16 @@ buster.testCase('Info', {
.withExactArgs(contextArg.options)
.returns(packageIdsArg)
- mainInfoUtilMock
- .expects('sizes')
+ fsMock
+ .expects('readFile')
+ .twice()
+ .callsArgWith(2, null, 'file contents')
+
+ zlibMock
+ .expects('gzip')
.once()
- .withArgs(contextArg.options, expectedFilename)
- .callsArgWith(2, null, sizesArg)
+ .withArgs('file contents')
+ .callsArgWith(1, null, 'gzipped contents')
enderPackageMock
.expects('buildArchyTree')
@@ -72,7 +79,7 @@ buster.testCase('Info', {
outMock
.expects('buildInfo')
.once()
- .withExactArgs(expectedFilename, contextArg.options, sizesArg, archyTreeArg)
+ .withExactArgs(expectedFilename, contextArg.options, { build: 13, minifiedBuild: 13, gzippedMinifiedBuild: 16 }, archyTreeArg)
// subvert single-function modules
requireSubvert.subvert('../../lib/parse-context', parseContextStub)
View
97 test/unit/main-info-util-test.js
@@ -1,97 +0,0 @@
-/*!
- * ENDER - The open module JavaScript framework
- *
- * Copyright (c) 2011-2012 @ded, @fat, @rvagg and other contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is furnished
- * to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-var buster = require('bustermove')
- , assert = require('referee').assert
- , refute = require('referee').refute
- , enderBuilder = require('ender-builder')
- , fs = require('fs')
- , zlib = require('zlib')
- , infoUtil = require('../../lib/main-info-util')
- , FilesystemError = require('../../lib/errors').FilesystemError
-
- , _i = 100
-
-buster.testCase('Info util', {
- 'test sizes': function (done) {
- var fsMock = this.mock(fs)
- , zlibMock = this.mock(zlib)
- , enderBuilderMock = this.mock(enderBuilder)
- , filenameArg = { filename: 1 }
- , optionsArg = { options: 1 }
- , fileContentsArg = { fileContents: 1, length: _i++ }
- , minifyContentsArg = { minifyContents: 1, length: _i++ }
- , gzipContentsArg = { gzipContents: 1, length: _i++ }
- , expectedSizes = {
- raw : fileContentsArg.length
- , minify : minifyContentsArg.length
- , gzip : gzipContentsArg.length
- }
-
- fsMock.expects('readFile').once().withArgs(filenameArg, 'utf-8').callsArgWith(2, null, fileContentsArg)
- enderBuilderMock.expects('minify').once().withArgs(optionsArg, fileContentsArg).callsArgWith(2, null, minifyContentsArg)
- zlibMock.expects('gzip').once().withArgs(minifyContentsArg).callsArgWith(1, null, gzipContentsArg)
-
- infoUtil.sizes(optionsArg, filenameArg, function (err, sizes) {
- refute(err)
- assert.equals(sizes, expectedSizes)
- done()
- })
- }
-
- , 'test sizes with --minifier none': function (done) {
- var fsMock = this.mock(fs)
- , filenameArg = { filename: 1 }
- , optionsArg = { minifier: 'none' }
- , fileContentsArg = { fileContents: 1, length: _i++ }
- , expectedSizes = { raw: fileContentsArg.length }
-
- fsMock.expects('readFile').once().withArgs(filenameArg, 'utf-8').callsArgWith(2, null, fileContentsArg)
-
- infoUtil.sizes(optionsArg, filenameArg, function (err, sizes) {
- refute(err)
- assert.equals(sizes, expectedSizes)
- done()
- })
- }
-
- , 'test sizes fs error': function (done) {
- var fsMock = this.mock(fs)
- , filenameArg = { filename: 1 }
- , optionsArg = { options: 1 }
- , errArg = new Error('this is an error')
-
- fsMock.expects('readFile').once().withArgs(filenameArg, 'utf-8').callsArgWith(2, errArg)
-
- infoUtil.sizes(optionsArg, filenameArg, function (err, sizes) {
- assert(err)
- refute(sizes)
- assert(err instanceof FilesystemError)
- assert.same(err.cause, errArg)
- assert.same(err.message, errArg.message)
- done()
- })
- }
-})

0 comments on commit a818a60

Please sign in to comment.