You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.6 KiB
163 lines
4.6 KiB
# tar-fs |
|
|
|
filesystem bindings for [tar-stream](https://github.com/mafintosh/tar-stream). |
|
|
|
``` |
|
npm install tar-fs |
|
``` |
|
|
|
[![build status](https://secure.travis-ci.org/mafintosh/tar-fs.png)](http://travis-ci.org/mafintosh/tar-fs) |
|
|
|
## Usage |
|
|
|
tar-fs allows you to pack directories into tarballs and extract tarballs into directories. |
|
|
|
It doesn't gunzip for you, so if you want to extract a `.tar.gz` with this you'll need to use something like [gunzip-maybe](https://github.com/mafintosh/gunzip-maybe) in addition to this. |
|
|
|
``` js |
|
var tar = require('tar-fs') |
|
var fs = require('fs') |
|
|
|
// packing a directory |
|
tar.pack('./my-directory').pipe(fs.createWriteStream('my-tarball.tar')) |
|
|
|
// extracting a directory |
|
fs.createReadStream('my-other-tarball.tar').pipe(tar.extract('./my-other-directory')) |
|
``` |
|
|
|
To ignore various files when packing or extracting add a ignore function to the options. `ignore` |
|
is also an alias for `filter`. Additionally you get `header` if you use ignore while extracting. |
|
That way you could also filter by metadata. |
|
|
|
``` js |
|
var pack = tar.pack('./my-directory', { |
|
ignore: function(name) { |
|
return path.extname(name) === '.bin' // ignore .bin files when packing |
|
} |
|
}) |
|
|
|
var extract = tar.extract('./my-other-directory', { |
|
ignore: function(name) { |
|
return path.extname(name) === '.bin' // ignore .bin files inside the tarball when extracing |
|
} |
|
}) |
|
|
|
var extractFilesDirs = tar.extract('./my-other-other-directory', { |
|
ignore: function(_, header) { |
|
// pass files & directories, ignore e.g. symlinks |
|
return header.type !== 'file' && header.type !== 'directory' |
|
} |
|
}) |
|
``` |
|
|
|
You can also specify which entries to pack using the `entries` option |
|
|
|
```js |
|
var pack = tar.pack('./my-directory', { |
|
entries: ['file1', 'subdir/file2'] // only the specific entries will be packed |
|
}) |
|
``` |
|
|
|
If you want to modify the headers when packing/extracting add a map function to the options |
|
|
|
``` js |
|
var pack = tar.pack('./my-directory', { |
|
map: function(header) { |
|
header.name = 'prefixed/'+header.name |
|
return header |
|
} |
|
}) |
|
|
|
var extract = tar.extract('./my-directory', { |
|
map: function(header) { |
|
header.name = 'another-prefix/'+header.name |
|
return header |
|
} |
|
}) |
|
``` |
|
|
|
Similarly you can use `mapStream` incase you wanna modify the input/output file streams |
|
|
|
``` js |
|
var pack = tar.pack('./my-directory', { |
|
mapStream: function(fileStream, header) { |
|
if (path.extname(header.name) === '.js') { |
|
return fileStream.pipe(someTransform) |
|
} |
|
return fileStream; |
|
} |
|
}) |
|
|
|
var extract = tar.extract('./my-directory', { |
|
mapStream: function(fileStream, header) { |
|
if (path.extname(header.name) === '.js') { |
|
return fileStream.pipe(someTransform) |
|
} |
|
return fileStream; |
|
} |
|
}) |
|
``` |
|
|
|
Set `options.fmode` and `options.dmode` to ensure that files/directories extracted have the corresponding modes |
|
|
|
``` js |
|
var extract = tar.extract('./my-directory', { |
|
dmode: parseInt(555, 8), // all dirs should be readable |
|
fmode: parseInt(444, 8) // all files should be readable |
|
}) |
|
``` |
|
|
|
It can be useful to use `dmode` and `fmode` if you are packing/unpacking tarballs between *nix/windows to ensure that all files/directories unpacked are readable. |
|
|
|
Alternatively you can set `options.readable` and/or `options.writable` to set the dmode and fmode to readable/writable. |
|
|
|
``` js |
|
var extract = tar.extract('./my-directory', { |
|
readable: true, // all dirs and files should be readable |
|
writable: true, // all dirs and files should be writable |
|
}) |
|
``` |
|
|
|
Set `options.strict` to `false` if you want to ignore errors due to unsupported entry types (like device files) |
|
|
|
To dereference symlinks (pack the contents of the symlink instead of the link itself) set `options.dereference` to `true`. |
|
|
|
## Copy a directory |
|
|
|
Copying a directory with permissions and mtime intact is as simple as |
|
|
|
``` js |
|
tar.pack('source-directory').pipe(tar.extract('dest-directory')) |
|
``` |
|
|
|
## Interaction with [`tar-stream`](https://github.com/mafintosh/tar-stream) |
|
|
|
Use `finalize: false` and the `finish` hook to |
|
leave the pack stream open for further entries (see |
|
[`tar-stream#pack`](https://github.com/mafintosh/tar-stream#packing)), |
|
and use `pack` to pass an existing pack stream. |
|
|
|
``` js |
|
var mypack = tar.pack('./my-directory', { |
|
finalize: false, |
|
finish: function(sameAsMypack) { |
|
mypack.entry({name: 'generated-file.txt'}, "hello") |
|
tar.pack('./other-directory', { |
|
pack: sameAsMypack |
|
}) |
|
} |
|
}) |
|
``` |
|
|
|
|
|
## Performance |
|
|
|
Packing and extracting a 6.1 GB with 2496 directories and 2398 files yields the following results on my Macbook Air. |
|
[See the benchmark here](https://gist.github.com/mafintosh/8102201) |
|
|
|
* tar-fs: 34.261 ms |
|
* [node-tar](https://github.com/isaacs/node-tar): 366.123 ms (or 10x slower) |
|
|
|
## License |
|
|
|
MIT
|
|
|