pax_global_header00006660000000000000000000000064120532632200014505gustar00rootroot0000000000000052 comment=2cc3e3d8b32463260a4f8dcf4bc78a3985e9338f dryice-0.4.10/000077500000000000000000000000001205326322000130465ustar00rootroot00000000000000dryice-0.4.10/.gitignore000066400000000000000000000003701205326322000150360ustar00rootroot00000000000000# Junk that could exist anywhere: .DS_Store *.swp *.tmp # Project files that should not be in the repo .project .settings/ .settings.xml .settings.xml.old .*.gz # A handy place to put stuff that git should ignore: /ignore/ /build/ /node_modules/ dryice-0.4.10/LICENSE000066400000000000000000000261361205326322000140630ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. dryice-0.4.10/README.md000066400000000000000000000226321205326322000143320ustar00rootroot00000000000000DryIce ====== DryIce is a CommonJS/RequireJS packaging tool for browser scripts. It is basically just a copy function. It takes input from a set of input files, which can be specified in various ways, optionally filters them and outputs them to something else. DryIce is licensed under the Apache License version 2 Why? ---- RequireJS has a build tool which is nice and works well, but it requires Rhino and therefore Java. With DryIce, your whole build process can be in JavaScript. DryIce produces a single file output that can include binary files (by base64 encoding them) How to install DryIce --------------------- sudo npm install dryice How does it work? ----------------- To copy a single file: copy({ source: 'foo.txt', dest: 'bar.txt' }); To cat a bunch of files together: copy({ source: [ 'file1.js', 'file2.js' ], dest: 'output.js' }); To cat together all the files in a directory: copy({ source: { root:'src' }, dest: 'built.js' }); As above, but only use the JavaScript files: copy({ source: { root:'src', include:/.*\.js$/ }, dest: 'built.js' }); As above, but exclude tests: copy({ source: { root:'src', include:/.*\.js$/: exclude:/test/ }, dest: 'built.js' }); If your set of files is very custom: copy({ source: function() { var files = [ 'file1.js' ]; if (baz) files.push('file2.js'); return files; }, dest: 'built.js' }); We can filter the files on the way: copy({ source: /src/.*\.js$/, filter: copy.filter.uglifyjs, dest: 'built.js' }); This includes running multiple custom filters: copy({ source: 'src/index.html', filter: [ function(data) { return data.replace(/Sun/, 'Oracle'); }, htmlCompressor ], dest: 'war/index.html' }); Results can be stored and then used/reused: var sources = copy.createDataObject(); copy({ source: { root: 'src1' }, dest: sources }); copy({ source: { root: 'src2' }, dest: sources }); copy({ source: sources, dest: 'sources-uncompressed.js' }); copy({ source: sources, filter: copy.filter.uglifyjs, dest: 'sources.js' }); Data objects are just JS objects with a 'value' member, so you can do all sorts of things with them: var test = copy.createDataObject(); copy({ source: 'README.txt', dest: test }); console.log(test.value); Or: copy({ source: { value: 'Hello, World!' }, dest: 'basic.txt' }); And you can mix and match your inputs: copy({ source: [ 'somefile.txt', thingDataObject, { root: 'src', include: /.*\.js$/ }, function() { return 'wibble.sh'; } ], dest: 'mess.bin' }); Common JS project dependency tracking: var project = copy.createCommonJsProject({ roots: [ '/path/to/source/tree/lib', '/some/other/project/lib' ] }); copy({ source: copy.source.commonjs({ project: project, require: [ 'main', 'plugin/main' ] }), dest: '' }); This digs around in the project source trees specified in the project for modules named in the 'require' statement. When it finds them it looks through them for require statements, and finds those, and so on. Formal Parameter Description ---------------------------- The copy function takes a single parameter which is an object with 2 or 3 members: `source`, `dest` and optionally `filter`. ### source There are 6 ways to specify the input source(s) * A *string* is expected to point to a filename. At some stage we may allow them to point at directories too, however this can be achieved today using a find object (see below) * A *find object* points to a directory with 2 optional RegExps specifying what to exclude and include. e.g. { root: '/' } -> The entire filesystem { root: 'src', include: /.*\.js$/ } -> All the JavaScript files in 'src' { root: 'src', exclude: /test/ } -> All non-test files under 'src' * A *data object* - something with a 'value' property. The implementation of `copy.createDataObject()` is simply `return { value: '' };`. We've batted around some ideas which involve making `copy.createDataObject()` smarter than it currently is, so it is advised to use this method rather than doing it yourself. * A *based object*. A based object is one with `base` and `path` members. They are roughly the same as the string baseObj.base + baseObj.path. Based objects are important when using CommonJS filters, because it tells the filter where the root of the hierarchy is, which lets us know the module name. For example: { base: '/etc', path:PATH } where BASE+PATH = filename * An *array* containing input source entries. The array does not have to be homogeneous. * A *function* which returns any input source entries. ### filter The filter member is optional. If it exists, it should contain either a function or an array of functions. The function should have the following signature: function filter(value, location) { .. return 'some string'; } Where the parameters are as follows: * value. Either a string or a node Buffer. Most filters will work only with strings, so they should begin: if (typeof value !== 'string') { value = value.toString(); } Some filters will only work with Buffers (for example the base64 encoding filter) so they should begin: if (typeof value === 'string') { throw new Error('base64 filter needs to be the first in a filter set'); } At some stage we may allow filters to be marked up as to their requirements. * location. This will be (where possible) a based object or it could be a string if a based object is not available. It will be common to use one of the following idioms to work on a filename: if (location.base) { location = location.path; } or if (location.base) { location = location.base + location.path; } There are 2 points in a copy run where filters could be used, either before the individual sources are concatenated, or after. Some filters should be used in before (like common-js munging filters) and some afterwards (like compressors). The default is to run filters after concatenation (when the location parameter will be undefined). To run filters before concatenation, the filter should be marked with `onRead = true`. For example: function makeBlank(value, location) { return ''; } makeBlank.onRead = true; DryIce currently comes with 4 filters: * _copy.filter.uglifyjs_: Calls uglify on the input. * _copy.filter.addDefines_: Wraps the input to inline files fetched using RequireJSs text import feature. * _copy.filter.base64_: Similar to addDefines, but assumes the input is binary and should be base64 encoded. * _copy.filter.moduleDefines_: Replaces define lines to include the module name e.g. `define(function(export, require, module) { ... });` is turned into `define('module/name', function(export, require, module) { ... });` ### dest The dest property should be either a filename to which the output should be written (existing files will be over-written without warning), or a data object to which the data should be appended. CommonJS Projects ----------------- CommonJS projects take a single object with the following properties: * `roots`: This is required. An array of directories that should be searched for your required modules and dependencies. * `ignores`: This is optional. An array of modules or dependencies that are required by your project that you would not like to be included in the build. For example, if you were making a build which did not need to support IE, you could do something like the following copy.createCommonJsProject({ roots: [ '/path/to/project' ], ignores: [ 'dom/ie-compat', 'event/ie-compat' ] }); then wherever you had `require('dom/ie-compat')` or `require('event/ie-compat')` inside your build, `undefined` would be returned by `require`. Where (is the project going)? ----------------------------- DryIce is useful in combining scripts for the browser, but it could also be used in a similar role on the server, we just need to enable 'pass through requires'. There are some tweaks we'd still like to make to enable more filters and multiple destinations: To recursively copy a directory: copy({ source: 'foo', destDir: 'bar' }); To rename files as we copy them: copy({ source: { root:'src', include:/.*\.png$/ }, destDir: { root:'built', replace:/png$/, with:'png.bak' } }); To create a tarball (this is only missing the targz filter): var version = copy.createDataObject(); copy({ source: 'VERSION.txt', dest: version }); copy({ source: { root:'.' }, filter: [ targz ], dest: 'scp://example.com/upload/myproject-' + version + '.tar.gz' }); I don't suppose you would ever actually want to do this, but in theory you could even do this: copy({ source: { root:'src', include:/.*\.java$/ }, filter: javac, destDir: { root:'classes', replace:/java$/, with:'class' } }); (Actually there would be issues with ordering that would make this hard, and Ant/Maven/etc is probably better. This is an illustration dammit!) dryice-0.4.10/lib/000077500000000000000000000000001205326322000136145ustar00rootroot00000000000000dryice-0.4.10/lib/dryice/000077500000000000000000000000001205326322000150735ustar00rootroot00000000000000dryice-0.4.10/lib/dryice/index.js000066400000000000000000000731271205326322000165520ustar00rootroot00000000000000/* * Copyright 2012, Mozilla Foundation and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require("fs"); var path = require("path"); var ujs = require("uglify-js"); if (!fs.existsSync) { fs.existsSync = path.existsSync; } /** * See https://github.com/mozilla/dryice for usage instructions. */ function copy(obj) { var filters = copy.filterFactory(obj.filter); var source = copy.sourceFactory(obj.source, filters); var dest = copy.destFactory(obj.dest, filters); dest.processSource(source); } /** * A Location is a base and a path which together point to a file or directory. * It's useful to be able to know in copy operations relative to some project * root to be able to remember where in a destination the file should go */ function Location(base, somePath) { if (base == null) { throw new Error('base == null'); } this.base = base; this.path = somePath; } Location.prototype.isLocation = true; Object.defineProperty(Location.prototype, 'fullname', { get: function() { return path.join(this.base, this.path); } }); Object.defineProperty(Location.prototype, 'dirname', { get: function() { return path.dirname(this.fullname); } }); /** * Select the correct implementation of Source for the given source property */ copy.sourceFactory = function(source, filters) { if (source == null) { throw new Error('Missing source'); } if (source.isSource) { return source; } if (typeof source === 'string') { if (copy.isDirectory(source)) { return new copy.DirectorySource(source, null, null, filters); } else { return new copy.FileSource(new Location('', source), filters); } } if (Array.isArray(source)) { return new copy.ArraySource(source, filters); } if (typeof source === 'function') { return new copy.FunctionSource(source, filters); } if (source.root != null) { if (source.require != null) { var project = new CommonJsProject([ source.root ]); return new copy.CommonJsSource(project, source.require, filters); } return new copy.DirectorySource(source.root, source.include, source.exclude, filters); } if (source.base != null && source.path != null) { return new copy.FileSource(new Location(source.base, source.path), filters); } if (typeof source.value === 'string') { return new copy.ValueSource(source.value, null, filters); } if (source.project != null && source.require != null) { return new copy.CommonJsSource(source.project, source.require, filters); } throw new Error('Can\'t handle type of source: ' + typeof source); }; copy.debug = false; /** * Abstract Source. * Concrete implementations of Source should define the 'get' property. */ copy.Source = function() { }; /** * @return Either another source, an array of other sources or a string value * when there is nothing else to dig into */ Object.defineProperty(copy.Source.prototype, 'get', { get: function() { throw new Error('Source.get is not implemented'); } }); copy.Source.prototype.isSource = true; copy.Source.prototype._runFilters = function(value, location) { this._filters.forEach(function(filter) { if (filter.onRead) { value = filter(value, location); } }, this); return value; }; /** * Default encoding for all sources */ copy.Source.prototype.encoding = 'utf8'; /** * An ArraySource is simply an array containing things that can resolve to * implementations of Source when passed to copy.sourceFactory() */ copy.ArraySource = function(array, filters) { copy.Source.call(this); this._array = array; this._filters = filters; }; copy.ArraySource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.ArraySource.prototype, 'get', { get: function() { return this._array.map(function(member) { return copy.sourceFactory(member, this._filters); }, this); } }); /** * A FunctionSource is something that can be called to resolve to another * Source implementation */ copy.FunctionSource = function(func, filters) { copy.Source.call(this); this._func = func; this._filters = filters; }; copy.FunctionSource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.FunctionSource.prototype, 'get', { get: function() { return copy.sourceFactory(this._func(), this._filters); } }); /** * A Source that finds files under a given directory with specified include / * exclude patterns. * @param root The root in the filesystem under which the files exist * @param filterOrInclude */ copy.DirectorySource = function(root, filterOrInclude, exclude, filters) { copy.Source.call(this); this._filters = filters; this.root = root; if (this.root instanceof CommonJsProject) { this.root = this.root.roots; } if (Array.isArray(this.root)) { this.root.map(function(r) { return ensureTrailingSlash(r); }); } if (typeof filterOrInclude === 'function') { this._searchFilter = filterOrInclude; } else { this._searchFilter = this._createFilter(filterOrInclude, exclude); } }; copy.DirectorySource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.DirectorySource.prototype, 'get', { get: function() { return this._findMatches(this.root, '/'); } }); copy.DirectorySource.prototype._findMatches = function(root, path) { var sources = []; if (Array.isArray(root)) { root.forEach(function(r) { var matches = this._findMatches(r, path); sources.push.apply(sources, matches); }, this); return sources; } root = ensureTrailingSlash(root); path = ensureTrailingSlash(path); if (copy.isDirectory(root + path)) { fs.readdirSync(root + path).forEach(function(entry) { var stat = fs.statSync(root + path + entry); if (stat.isFile()) { if (this._searchFilter(path + entry)) { var location = new Location(root, path + entry); sources.push(new copy.FileSource(location, this._filters)); } } else if (stat.isDirectory()) { var matches = this._findMatches(root, path + entry); sources.push.apply(sources, matches); } }, this); } return sources; }; copy.DirectorySource.prototype._createFilter = function(include, exclude) { return function(pathname) { function noPathMatch(pattern) { return !pattern.test(pathname); } if (include instanceof RegExp) { if (noPathMatch(include)) { return false; } } if (typeof include === 'string') { if (noPathMatch(new RegExp(include))) { return false; } } if (Array.isArray(include)) { if (include.every(noPathMatch)) { return false; } } function pathMatch(pattern) { return pattern.test(pathname); } if (exclude instanceof RegExp) { if (pathMatch(exclude)) { return false; } } if (typeof exclude === 'string') { if (pathMatch(new RegExp(exclude))) { return false; } } if (Array.isArray(exclude)) { if (exclude.some(pathMatch)) { return false; } } return true; }; }; /** * A FileSource gets data directly from a file. It has 2 parts to the filename, * a base and path members, where filename = base + path. * FileSources are important when using CommonJS filters, because it tells the * filter where the root of the hierarchy is, which lets us know the module * name. * If there is no base to the filename, use a base of ''. */ copy.FileSource = function(location, filters) { copy.Source.call(this); this.location = location; this.name = location.fullname; this._filters = filters; }; copy.FileSource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.FileSource.prototype, 'get', { get: function() { var read = fs.readFileSync(this.name); return this._runFilters(read, this.location); } }); /** * */ copy.ValueSource = function(value, location, filters) { copy.Source.call(this); this._value = value; this._location = location; this._filters = filters; }; copy.ValueSource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.ValueSource.prototype, 'get', { get: function() { return this._runFilters(this._value, this._location); } }); /** * Read modules from a CommonJS Project using a require property. */ copy.CommonJsSource = function(project, require, filters) { copy.Source.call(this); this._project = project; this._filters = filters; if (!project instanceof CommonJsProject) { throw new Error('commonjs project should be a CommonJsProject'); } if (typeof require === 'string') { this._require = [ require ]; } else if (Array.isArray(require)) { this._require = require; } else { throw new Error('Expected commonjs args to have string/array require.'); } }; copy.CommonJsSource.prototype = Object.create(copy.Source.prototype); Object.defineProperty(copy.CommonJsSource.prototype, 'get', { get: function() { this._require.forEach(function(moduleName) { this._project.require(moduleName); }, this); return this._project.getCurrentModules().map(function(location) { return new copy.FileSource(location, this._filters); }.bind(this)); } }); //////////////////////////////////////////////////////////////////////////////// copy.filterFactory = function(filter) { if (filter == null) { return []; } if (typeof filter === 'function') { return [ filter ]; } if (Array.isArray(filter)) { return filter; } }; //////////////////////////////////////////////////////////////////////////////// /** * Select the correct implementation of Destination for the given dest property */ copy.destFactory = function(dest, filters) { if (dest == null) { throw new Error('Missing dest'); } if (dest.isDestination) { return dest; } if (dest.value != null) { return new copy.ValueDestination(dest, filters); } if (typeof dest === 'string') { if (copy.isDirectory(dest)) { return new copy.DirectoryDestination(dest, filters); } else { return new copy.FileDestination(dest, filters); } } if (Array.isArray(dest)) { return new copy.ArrayDestination(dest, filters); } throw new Error('Can\'t handle type of dest: ' + typeof dest); }; /** * Abstract Destination. * Concrete implementations of Destination should define the 'processSource' * function. */ copy.Destination = function() { }; copy.Destination.prototype.isDestination = true; /** * @return Either another dest, an array of other sources or a string value * when there is nothing else to dig into */ copy.Destination.prototype.processSource = function(source) { throw new Error('Destination.processSource() is not implemented'); }; /** * Helper function to convert an input source to a single string value */ copy.Destination.prototype._sourceToOutput = function(source) { var data = source.get; if (data.isSource) { return this._sourceToOutput(data); } if (Array.isArray(data)) { var value = ''; data.forEach(function(s) { value += this._sourceToOutput(s); }, this); return value; } if (typeof data === 'string') { return data; } // i.e. a Node Buffer if (typeof data.toString === 'function') { return data.toString(); } throw new Error('Unexpected value from source.get'); }; copy.Destination.prototype._runFilters = function(value) { this._filters.forEach(function(filter) { if (!filter.onRead) { value = filter(value); } }, this); return value; }; /** * A Destination that concatenates the sources and writes them to a single * output file. */ copy.FileDestination = function(filename, filters) { this._filename = filename; this._filters = filters; }; copy.FileDestination.prototype = Object.create(copy.Destination.prototype); copy.FileDestination.prototype.processSource = function(source) { var data = this._sourceToOutput(source); data = this._runFilters(data); copy._writeToFile(this._filename, data); }; /** * A Destination that copies the sources to new files in an alternate directory * structure. */ copy.DirectoryDestination = function(dirname, filters) { this.name = dirname; this._filters = filters; }; copy.DirectoryDestination.prototype = Object.create(copy.Destination.prototype); copy.DirectoryDestination.prototype.processSource = function(source) { var data = source.get; if (typeof data === 'string') { throw new Error('Can\'t write raw data to a directory'); } else if (data.isSource) { var destfile = path.join(this.name, data.location.path); var output = this._runFilters(data.get); copy._writeToFile(destfile, output, data.encoding); } else if (Array.isArray(data)) { data.forEach(function(s) { var destfile = path.join(this.name, s.location.path); var output = this._runFilters(s.get); copy._writeToFile(destfile, output, s.encoding); }, this); } else { throw new Error('data is not a source, string, nor can it be converted'); } }; /** * ArrayDestination is a Destination that can feed sources to a number of child * Destinations. */ copy.ArrayDestination = function(array, filters) { this._array = array; this._filters = filters; }; copy.ArrayDestination.prototype = Object.create(copy.Destination.prototype); copy.ArrayDestination.prototype.processSource = function(source) { this._array.forEach(function(member) { var dest = copy.destFactory(member, this._filters); dest.processSource(source); }, this); }; /** * A Destination that concatenates the sources and writes them to a single * value object. */ copy.ValueDestination = function(value, filters) { this._value = value; this._filters = filters; }; copy.ValueDestination.prototype = Object.create(copy.Destination.prototype); copy.ValueDestination.prototype.processSource = function(source) { var data = this._sourceToOutput(source); data = this._runFilters(data); this._value.value += data; }; //////////////////////////////////////////////////////////////////////////////// /** * Check to see if fullPath refers to a directory */ copy.isDirectory = function(fullPath) { return fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory(); }; copy._writeToFile = function(filename, data, encoding) { if (fs.existsSync(filename)) { if (!fs.statSync(filename).isFile()) { throw new Error('Refusing to remove non file: ' + filename); } fs.unlinkSync(filename); } var parent = path.dirname(filename); if (!fs.existsSync(parent)) { copy.mkdirSync(parent, 0755); } fs.writeFileSync(filename, data, encoding); if (copy.debug) { console.log('- wrote ' + data.length + ' bytes to ' + filename); } }; copy.mkdirSync = function(dirname, mode) { if (copy.isDirectory(dirname)) { return; } var parent = path.dirname(dirname); if (!fs.existsSync(parent)) { copy.mkdirSync(parent, mode); } if (!fs.existsSync(dirname)) { fs.mkdirSync(dirname, mode); } }; //////////////////////////////////////////////////////////////////////////////// /** * A holder is an in-memory store of a result of a copy operation. *
 * var holder = copy.createDataObject();
 * copy({ source: 'x.txt', dest: holder });
 * copy({ source: 'y.txt', dest: holder });
 * copy({ source: holder, dest: 'z.txt' });
 * 
*/ copy.createDataObject = function() { return { value: '' }; }; /** * Read mini_require.js to go with the required modules. */ copy.getMiniRequire = function() { return { value: fs.readFileSync(__dirname + '/mini_require.js').toString('utf8') }; }; /** * Keep track of the files in a project */ function CommonJsProject(opts) { this.roots = opts.roots; this.aliases = opts.aliases; this.textPluginPattern = opts.textPluginPattern || /^text!/; opts.roots = this.roots.map(function(root) { if (!copy.isDirectory(root)) { throw new Error('Each commonjs root should be a directory: ' + root); } return ensureTrailingSlash(root); }, this); // A module is a Location that also has dep this.currentModules = {}; this.ignoredModules = {}; } CommonJsProject.prototype.report = function() { var reply = 'CommonJS project at ' + this.roots.join(', ') + '\n'; reply += '- Required modules:\n'; var moduleNames = Object.keys(this.currentModules); if (moduleNames.length > 0) { moduleNames.forEach(function(module) { var deps = Object.keys(this.currentModules[module].deps).length; reply += ' - ' + module + ' (' + deps + (deps === 1 ? ' dependency' : ' dependencies') + ')\n'; }, this); } else { reply += ' - None\n'; } reply += '- Ignored modules:\n'; var ignoredNames = Object.keys(this.ignoredModules); if (ignoredNames.length > 0) { ignoredNames.forEach(function(moduleName) { reply += ' - ' + moduleName + '\n'; }, this); } else { reply += ' - None\n'; } return reply; }; /** * Create an experimental GraphML string declaring the node dependencies. */ CommonJsProject.prototype.getDependencyGraphML = function() { var nodes = ''; var edges = ''; var moduleNames = Object.keys(this.currentModules); moduleNames.forEach(function(moduleName) { nodes += ' \n'; nodes += ' \n'; nodes += ' \n'; nodes += ' ' + moduleName + '\n'; nodes += ' \n'; nodes += ' \n'; nodes += ' \n'; var deps = Object.keys(this.currentModules[moduleName].deps); deps.forEach(function(dep) { edges += ' \n'; }); }, this); var reply = '\n'; reply += ' 0 && filename.substr(-1) !== '/') { filename += '/'; } return filename; } exports.copy = copy; dryice-0.4.10/lib/dryice/mini_require.js000066400000000000000000000123261205326322000201250ustar00rootroot00000000000000/* * Copyright 2012, Mozilla Foundation and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Define a module along with a payload. * @param moduleName Name for the payload * @param deps Ignored. For compatibility with CommonJS AMD Spec * @param payload Function with (require, exports, module) params */ function define(moduleName, deps, payload) { if (typeof moduleName != "string") { throw new Error("Error: Module name is not a string"); } if (arguments.length == 2) { payload = deps; } else { payload.deps = deps; } if (define.debugDependencies) { console.log("define: " + moduleName + " -> " + payload.toString() .slice(0, 40).replace(/\n/, '\\n').replace(/\r/, '\\r') + "..."); } if (moduleName in define.modules) { throw new Error("Error: Redefining module: " + moduleName); } // Mark the payload so we know we need to call it to get the real module payload.__uncompiled = true; define.modules[moduleName] = payload; } /** * The global store of un-instantiated modules */ define.modules = {}; /** * Should we console.log on module definition/instantiation/requirement? */ define.debugDependencies = false; (function() { /** * We invoke require() in the context of a Domain so we can have multiple * sets of modules running separate from each other. * This contrasts with JSMs which are singletons, Domains allows us to * optionally load a CommonJS module twice with separate data each time. * Perhaps you want 2 command lines with a different set of commands in each, * for example. */ function Domain() { this.modules = {}; if (define.debugDependencies) { this.depth = ""; } } /** * Lookup module names and resolve them by calling the definition function if * needed. * There are 2 ways to call this, either with an array of dependencies and a * callback to call when the dependencies are found (which can happen * asynchronously in an in-page context) or with a single string an no * callback where the dependency is resolved synchronously and returned. * The API is designed to be compatible with the CommonJS AMD spec and * RequireJS. * @param deps A name, or array of names for the payload * @param callback Function to call when the dependencies are resolved * @return The module required or undefined for array/callback method */ Domain.prototype.require = function(config, deps, callback) { if (arguments.length <= 2) { callback = deps; deps = config; config = undefined; } if (Array.isArray(deps)) { var params = deps.map(function(dep) { return this.lookup(dep); }, this); if (callback) { callback.apply(null, params); } return undefined; } else { return this.lookup(deps); } }; /** * Lookup module names and resolve them by calling the definition function if * needed. * @param moduleName A name for the payload to lookup * @return The module specified by aModuleName or null if not found */ Domain.prototype.lookup = function(moduleName) { if (moduleName in this.modules) { var module = this.modules[moduleName]; if (define.debugDependencies) { console.log(this.depth + " Using module: " + moduleName); } return module; } if (!(moduleName in define.modules)) { throw new Error("Missing module: " + moduleName); } var module = define.modules[moduleName]; if (define.debugDependencies) { console.log(this.depth + " Compiling module: " + moduleName); } if (module.__uncompiled) { if (define.debugDependencies) { this.depth += "."; } var exports = {}; try { var params = module.deps.map(function(dep) { if (dep === "require") { return this.require.bind(this); } if (dep === "exports") { return exports; } if (dep === "module") { return { id: moduleName, uri: "" }; } return this.lookup(dep); }.bind(this)); var reply = module.apply(null, params); module = (reply !== undefined) ? reply : exports; } catch (ex) { console.error("Error using module: " + moduleName, ex); throw ex; } if (define.debugDependencies) { this.depth = this.depth.slice(0, -1); } } // cache the resulting module object for next time this.modules[moduleName] = module; return module; }; /** * Expose the Domain constructor and a global domain (on the define function * to avoid exporting more than we need. This is a common pattern with * require systems) */ define.Domain = Domain; define.globalDomain = new Domain(); })(); /** * Expose a default require function which is the require of the global * sandbox to make it easy to use. */ var require = define.globalDomain.require.bind(define.globalDomain); dryice-0.4.10/package.json000066400000000000000000000013131205326322000153320ustar00rootroot00000000000000{ "name": "dryice", "description": "A CommonJS/RequireJS packaging tool for browser scripts", "keywords": [ "build", "commonjs", "requirejs" ], "version": "0.4.10", "homepage": "https://github.com/joewalker/dryice", "author": "Joe Walker ", "contributors": [ ], "repository": { "type": "git", "url": "http://github.com/mozilla/dryice.git" }, "bugs": { "url": "http://github.com/mozilla/dryice/issues" }, "directories": { "lib" : "./lib" }, "main": "./lib/dryice/index.js", "engines": { "node" : ">=0.6.0" }, "licenses": [ { "type": "Apache-2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ], "dependencies": { "uglify-js": "~1.3.4" } }