pax_global_header00006660000000000000000000000064127030025510014505gustar00rootroot0000000000000052 comment=c783f54c8a9e7f3991c5e7a5ddcba1c23e9d89ff node-tar-pack-3.1.3/000077500000000000000000000000001270300255100141365ustar00rootroot00000000000000node-tar-pack-3.1.3/.gitignore000066400000000000000000000001341270300255100161240ustar00rootroot00000000000000lib-cov *.seed *.log *.csv *.dat *.out *.pid pids logs results npm-debug.log node_modules node-tar-pack-3.1.3/.travis.yml000066400000000000000000000002241270300255100162450ustar00rootroot00000000000000sudo: false language: node_js node_js: - stable - "0.10" - "0.8" before_install: if [[ `npm --version` != 3* ]]; then npm install -g npm; fi; node-tar-pack-3.1.3/LICENSE000066400000000000000000000024221270300255100151430ustar00rootroot00000000000000Copyright (c) 2014, Forbes Lindesay All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-tar-pack-3.1.3/README.md000066400000000000000000000067431270300255100154270ustar00rootroot00000000000000# Tar Pack Package and un-package modules of some sort (in tar/gz bundles). This is mostly useful for package managers. Note that it doesn't check for or touch `package.json` so it can be used even if that's not the way you store your package info. [![Build Status](https://img.shields.io/travis/ForbesLindesay/tar-pack/master.svg)](https://travis-ci.org/ForbesLindesay/tar-pack) [![Dependency Status](https://img.shields.io/david/ForbesLindesay/tar-pack.svg)](https://david-dm.org/ForbesLindesay/tar-pack) [![NPM version](https://img.shields.io/npm/v/tar-pack.svg)](https://www.npmjs.com/package/tar-pack) ## Installation $ npm install tar-pack ## API ### pack(folder|packer, [options]) Pack the folder at `folder` into a gzipped tarball and return the tgz as a stream. Files ignored by `.gitignore` will not be in the package. You can optionally pass a `fstream.DirReader` directly, instead of folder. For example, to create an npm package, do: ```js pack(require("fstream-npm")(folder), [options]) ``` Options: - `noProprietary` (defaults to `false`) Set this to `true` to prevent any proprietary attributes being added to the tarball. These attributes are allowed by the spec, but may trip up some poorly written tarball parsers. - `ignoreFiles` (defaults to `['.gitignore']`) These files can specify files to be excluded from the package using the syntax of `.gitignore`. This option is ignored if you parse a `fstream.DirReader` instead of a string for folder. - `filter` (defaults to `entry => true`) A function that takes an entry and returns `true` if it should be included in the package and `false` if it should not. Entryies are of the form `{path, basename, dirname, type}` where (type is "Directory" or "File"). This function is ignored if you parse a `fstream.DirReader` instead of a string for folder. Example: ```js var write = require('fs').createWriteStream var pack = require('tar-pack').pack pack(process.cwd()) .pipe(write(__dirname + '/package.tar.gz')) .on('error', function (err) { console.error(err.stack) }) .on('close', function () { console.log('done') }) ``` ### unpack(folder, [options,] cb) Return a stream that unpacks a tarball into a folder at `folder`. N.B. the output folder will be removed first if it already exists. The callback is called with an optional error and, as its second argument, a string which is one of: - `'directory'`, indicating that the extracted package was a directory (either `.tar.gz` or `.tar`) - `'file'`, incating that the extracted package was just a single file (extracted to `defaultName`, see options) Basic Options: - `defaultName` (defaults to `index.js`) If the package is a single file, rather than a tarball, it will be "extracted" to this file name, set to `false` to disable. Advanced Options (you probably don't need any of these): - `gid` - (defaults to `null`) the `gid` to use when writing files - `uid` - (defaults to `null`) the `uid` to use when writing files - `dmode` - (defaults to `0777`) The mode to use when creating directories - `fmode` - (defaults to `0666`) The mode to use when creating files - `unsafe` - (defaults to `false`) (on non win32 OSes it overrides `gid` and `uid` with the current processes IDs) Example: ```js var read = require('fs').createReadStream var unpack = require('tar-pack').unpack read(process.cwd() + '/package.tar.gz') .pipe(unpack(__dirname + '/package/', function (err) { if (err) console.error(err.stack) else console.log('done') })) ``` ## License BSDnode-tar-pack-3.1.3/index.js000066400000000000000000000162641270300255100156140ustar00rootroot00000000000000"use strict" var debug = require('debug')('tar-pack') var uidNumber = require('uid-number') var rm = require('rimraf') var tar = require('tar') var once = require('once') var fstream = require('fstream') var packer = require('fstream-ignore') var PassThrough = require('stream').PassThrough || require('readable-stream').PassThrough var zlib = require('zlib') var path = require('path') var win32 = process.platform === 'win32' var myUid = process.getuid && process.getuid() var myGid = process.getgid && process.getgid() if (process.env.SUDO_UID && myUid === 0) { if (!isNaN(process.env.SUDO_UID)) myUid = +process.env.SUDO_UID if (!isNaN(process.env.SUDO_GID)) myGid = +process.env.SUDO_GID } exports.pack = pack exports.unpack = unpack function pack(folder, options) { options = options || {} if (typeof folder === 'string') { var filter = options.filter || function (entry) { return true; } folder = packer({ path: folder, type: 'Directory', isDirectory: true, ignoreFiles: options.ignoreFiles || ['.gitignore'], filter: function (entry) { // {path, basename, dirname, type} (type is "Directory" or "File") var basename = entry.basename // some files are *never* allowed under any circumstances // these files should always be either temporary files or // version control related files if (basename === '.git' || basename === '.lock-wscript' || basename.match(/^\.wafpickle-[0-9]+$/) || basename === 'CVS' || basename === '.svn' || basename === '.hg' || basename.match(/^\..*\.swp$/) || basename === '.DS_Store' || basename.match(/^\._/)) { return false } //custom excludes return filter(entry) } }) } // By default, npm includes some proprietary attributes in the // package tarball. This is sane, and allowed by the spec. // However, npm *itself* excludes these from its own package, // so that it can be more easily bootstrapped using old and // non-compliant tar implementations. var tarPack = tar.Pack({ noProprietary: options.noProprietary || false }) var gzip = zlib.Gzip() folder .on('error', function (er) { if (er) debug('Error reading folder') return gzip.emit('error', er) }) tarPack .on('error', function (er) { if (er) debug('tar creation error') gzip.emit('error', er) }) return folder.pipe(tarPack).pipe(gzip) } function unpack(unpackTarget, options, cb) { if (typeof options === 'function' && cb === undefined) cb = options, options = undefined var tarball = new PassThrough() if (typeof cb === 'function') { cb = once(cb) tarball.on('error', cb) tarball.on('close', function () { cb() }) } var parent = path.dirname(unpackTarget) var base = path.basename(unpackTarget) options = options || {} var gid = options.gid || null var uid = options.uid || null var dMode = options.dmode || 0x0777 //npm.modes.exec var fMode = options.fmode || 0x0666 //npm.modes.file var defaultName = options.defaultName || (options.defaultName === false ? false : 'index.js') // figure out who we're supposed to be, if we're not pretending // to be a specific user. if (options.unsafe && !win32) { uid = myUid gid = myGid } var pending = 2 uidNumber(uid, gid, function (er, uid, gid) { if (er) { tarball.emit('error', er) return tarball.end() } if (0 === --pending) next() }) rm(unpackTarget, function (er) { if (er) { tarball.emit('error', er) return tarball.end() } if (0 === --pending) next() }) function next() { // gzip {tarball} --decompress --stdout \ // | tar -mvxpf - --strip-components=1 -C {unpackTarget} gunzTarPerm(tarball, unpackTarget, dMode, fMode, uid, gid, defaultName) } return tarball } function gunzTarPerm(tarball, target, dMode, fMode, uid, gid, defaultName) { debug('modes %j', [dMode.toString(8), fMode.toString(8)]) function fixEntry(entry) { debug('fixEntry %j', entry.path) // never create things that are user-unreadable, // or dirs that are user-un-listable. Only leads to headaches. var originalMode = entry.mode = entry.mode || entry.props.mode entry.mode = entry.mode | (entry.type === 'Directory' ? dMode : fMode) entry.props.mode = entry.mode if (originalMode !== entry.mode) { debug('modified mode %j', [entry.path, originalMode, entry.mode]) } // if there's a specific owner uid/gid that we want, then set that if (!win32 && typeof uid === 'number' && typeof gid === 'number') { entry.props.uid = entry.uid = uid entry.props.gid = entry.gid = gid } } var extractOpts = { type: 'Directory', path: target, strip: 1 } if (!win32 && typeof uid === 'number' && typeof gid === 'number') { extractOpts.uid = uid extractOpts.gid = gid } extractOpts.filter = function () { // symbolic links are not allowed in packages. if (this.type.match(/^.*Link$/)) { debug('excluding symbolic link: ' + this.path.substr(target.length + 1) + ' -> ' + this.linkpath) return false } return true } type(tarball, function (err, type) { if (err) return tarball.emit('error', err) var strm = tarball if (type === 'gzip') { strm = strm.pipe(zlib.Unzip()) strm.on('error', function (er) { if (er) debug('unzip error') tarball.emit('error', er) }) type = 'tar' } if (type === 'tar') { strm .pipe(tar.Extract(extractOpts)) .on('entry', fixEntry) .on('error', function (er) { if (er) debug('untar error') tarball.emit('error', er) }) .on('close', function () { tarball.emit('close') }) return } if (type === 'naked-file' && defaultName) { var jsOpts = { path: path.resolve(target, defaultName) } if (!win32 && typeof uid === 'number' && typeof gid === 'number') { jsOpts.uid = uid jsOpts.gid = gid } strm .pipe(fstream.Writer(jsOpts)) .on('error', function (er) { if (er) debug('copy error') tarball.emit('error', er) }) .on('close', function () { tarball.emit('close') }) return } return cb(new Error('Unrecognised package type')); }) } function type(stream, callback) { stream.on('error', handle) stream.on('data', parse) function handle(err) { stream.removeListener('data', parse) stream.removeListener('error', handle) } function parse(chunk) { // detect what it is. // Then, depending on that, we'll figure out whether it's // a single-file module, gzipped tarball, or naked tarball. // gzipped files all start with 1f8b08 if (chunk[0] === 0x1F && chunk[1] === 0x8B && chunk[2] === 0x08) { callback(null, 'gzip') } else if (chunk.toString().match(/^package\/\u0000/)) { // note, this will only pick up on tarballs with a root directory called package callback(null, 'tar') } else { callback(null, 'naked-file') } // now un-hook, and re-emit the chunk stream.removeListener('data', parse) stream.removeListener('error', handle) stream.unshift(chunk) } } node-tar-pack-3.1.3/package.json000066400000000000000000000011611270300255100164230ustar00rootroot00000000000000{ "name": "tar-pack", "version": "3.1.3", "description": "Package and un-package modules of some sort (in tar/gz bundles).", "scripts": { "test": "mocha -R list" }, "repository": { "type": "git", "url": "https://github.com/ForbesLindesay/tar-pack.git" }, "license": "BSD-2-Clause", "dependencies": { "debug": "~2.2.0", "fstream": "~1.0.8", "fstream-ignore": "~1.0.3", "once": "~1.3.3", "readable-stream": "~2.0.4", "rimraf": "~2.5.1", "tar": "~2.2.1", "uid-number": "~0.0.6" }, "devDependencies": { "mocha": "*", "rfile": "*", "mkdirp": "*" } } node-tar-pack-3.1.3/test/000077500000000000000000000000001270300255100151155ustar00rootroot00000000000000node-tar-pack-3.1.3/test/fixtures/000077500000000000000000000000001270300255100167665ustar00rootroot00000000000000node-tar-pack-3.1.3/test/fixtures/packed-file.txt000066400000000000000000000000031270300255100216640ustar00rootroot00000000000000barnode-tar-pack-3.1.3/test/fixtures/packed.tar000066400000000000000000000070001270300255100207220ustar00rootroot00000000000000package/ 40777 0 0 0 12137017516 5473 5package/bar.txt100777 0 0 3 12137015264 7007 0bazpackage/foo.txt100777 0 0 3 12137015252 7023 0barnode-tar-pack-3.1.3/test/fixtures/packed.tar.gz000066400000000000000000000002301270300255100213370ustar00rootroot00000000000000|Qto-pack.tar= A %P3?I3+XEj}_^xip+,ow!Đ\F5'cRr?G,~[\#6'~Ժk _C7node-tar-pack-3.1.3/test/fixtures/to-pack/000077500000000000000000000000001270300255100203245ustar00rootroot00000000000000node-tar-pack-3.1.3/test/fixtures/to-pack/bar.txt000066400000000000000000000000031270300255100216220ustar00rootroot00000000000000baznode-tar-pack-3.1.3/test/fixtures/to-pack/foo.txt000066400000000000000000000000031270300255100216410ustar00rootroot00000000000000barnode-tar-pack-3.1.3/test/index.js000066400000000000000000000050741270300255100165700ustar00rootroot00000000000000var tar = require('../') var path = require('path') var rfile = require('rfile') var rimraf = require('rimraf').sync var mkdir = require('mkdirp').sync var read = require('fs').createReadStream var write = require('fs').createWriteStream var assert = require('assert') beforeEach(function () { rimraf(__dirname + '/output') }) afterEach(function () { rimraf(__dirname + '/output') }) describe('tarball.pipe(unpack(directory, callback))', function () { it('unpacks the tarball into the directory', function (done) { read(__dirname + '/fixtures/packed.tar').pipe(tar.unpack(__dirname + '/output/unpacked', function (err) { if (err) return done(err) assert.equal(rfile('./output/unpacked/bar.txt'), rfile('./fixtures/to-pack/bar.txt')) assert.equal(rfile('./output/unpacked/foo.txt'), rfile('./fixtures/to-pack/foo.txt')) done() })) }) }) describe('gziptarball.pipe(unpack(directory, callback))', function () { it('unpacks the tarball into the directory', function (done) { read(__dirname + '/fixtures/packed.tar.gz').pipe(tar.unpack(__dirname + '/output/unpacked', function (err) { if (err) return done(err) assert.equal(rfile('./output/unpacked/bar.txt'), rfile('./fixtures/to-pack/bar.txt')) assert.equal(rfile('./output/unpacked/foo.txt'), rfile('./fixtures/to-pack/foo.txt')) done() })) }) }) describe('file.pipe(unpack(directory, callback))', function () { it('copies the file into the directory', function (done) { read(__dirname + '/fixtures/packed-file.txt').pipe(tar.unpack(__dirname + '/output/unpacked', function (err) { if (err) return done(err) assert.equal(rfile('./output/unpacked/index.js'), rfile('./fixtures/packed-file.txt')) done() })) }) }) describe('pack(directory).pipe(tarball)', function () { it('packs the directory into the output', function (done) { var called = false mkdir(__dirname + '/output/') tar.pack(__dirname + '/fixtures/to-pack').pipe(write(__dirname + '/output/packed.tar.gz')) .on('error', function (err) { if (called) return called = true done(err) }) .on('close', function () { if (called) return called = true read(__dirname + '/output/packed.tar.gz').pipe(tar.unpack(__dirname + '/output/unpacked', function (err) { if (err) return done(err) assert.equal(rfile('./output/unpacked/bar.txt'), rfile('./fixtures/to-pack/bar.txt')) assert.equal(rfile('./output/unpacked/foo.txt'), rfile('./fixtures/to-pack/foo.txt')) done() })) }) }) })