New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

gulp-symlink

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gulp-symlink - npm Package Compare versions

Comparing version

to
2.0.0

test/fixtures/test

5

gulpfile.js

@@ -9,7 +9,6 @@ /* jshint node:true */

mocha = require('gulp-mocha'),
jshint = require('gulp-jshint'),
stylish = require('jshint-stylish');
jshint = require('gulp-jshint');
gulp.task('lint', function () {
gulp.src('*.js')
gulp.src(['*.js', 'test/**/*.js'])
.pipe(jshint())

@@ -16,0 +15,0 @@ .pipe(jshint.reporter('jshint-stylish'))

201

index.js

@@ -10,84 +10,169 @@ /* jshint node:true */

fs = require('fs'),
async = require('async'),
PluginError = gutil.PluginError,
File = gutil.File,
debug;
PLUGIN_NAME = 'gulp-symlink';
var PLUGIN_NAME = 'gulp-symlink';
function localPath(absolutePath) {
var cwd = process.cwd();
return absolutePath.indexOf(cwd) === 0 ? absolutePath.substr(cwd.length + 1) : absolutePath;
}
/**
* Wrapper to log when debug === true
* it's basically a console.log
*/
var log = function() {
if(debug === true) {
console.log.apply(console, [].slice.call(arguments));
return console.log;
} else {
return function() { };
}
var symlinker = function(symlink, resolver) {
return through.obj(function(file, encoding, cb) {
var self = this,
sym = null;
};
if (typeof symlink === 'undefined') {
this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'An output destination is required.'));
return cb();
}
/**
* Error wrapper - this is called in the through context
* @param {Error} error The error
* @return {Function} cb The through callback
*/
var errored = function(error, cb) {
this.emit('error', new PluginError(PLUGIN_NAME, error));
//Push the file so that the stream is piped to the next task even if it has errored
//might be discussed
this.push(this.source);
return cb();
};
var out = function(file) {
return (typeof symlink === 'string') ? symlink : symlink(file);
};
var symlinker = function(destination, resolver, options) {
var destination = resolver.call(this, process.cwd(), out(file));
if(typeof resolver === 'object') {
options = resolver;
resolver = 'relative';
}
// Check whether the destination is a directory
if (path.extname(out(file)) === '') {
sym = path.join(destination, path.basename(file.path));
} else {
sym = destination;
destination = destination.replace(path.basename(destination), '');
}
options = typeof options === 'object' ? options : {};
options.force = options.force === undefined ? false : options.force;
var source = resolver.call(this, destination, file.path);
//Handling array of destinations, this test is because "instance of" isn't safe
if( Object.prototype.toString.call( destination ) === '[object Array]' ) {
//copy array because we'll shift values
var destinations = destination.slice();
}
var finish = function(err) {
if (err && err.code !== 'EEXIST') {
self.emit('error', new gutil.PluginError(PLUGIN_NAME, err));
return cb();
return through.obj(function(source, encoding, callback) {
var self = this, symlink;
this.source = source; //error binding
//else if we've got an array from before take the next element as a destination path
symlink = destinations !== undefined ? destinations.shift() : symlink;
//if destination is a function pass the source to it
if(symlink === undefined) {
symlink = typeof destination === 'function' ? destination(source) : destination;
}
//if symlink is still undefined there is a problem!
if (symlink === undefined) {
return errored.call(self, 'An output destination is required.', callback);
}
// Convert the destination path to a new vinyl instance
symlink = symlink instanceof File ? symlink : new File({ path: symlink });
log('Before resolving')('Source: %s – dest: %s', source.path, symlink.path);
symlink.directory = path.dirname(symlink.path); //this is the parent directory of the symlink
// Resolve the path to the symlink
if(resolver === 'relative' || options.relative === true) {
source.resolved = path.relative(symlink.directory, source.path);
} else {
//resolve the absolute path from the source. It need to be from the current working directory to handle relative sources
source.resolved = path.resolve(source.cwd, source.path);
}
log('After resolving')(source.resolved + ' in ' + symlink.path);
fs.exists(symlink.path, function(exists) {
//No force option, we can't override!
if(exists && !options.force) {
return errored.call(self, 'Destination file exists ('+destination+') - use force option to replace', callback);
} else {
async.waterfall([
function(next){
//remove destination if it exists already
if(exists && options.force === true) {
fs.unlink(symlink.path, function(err) {
if(err) {
return errored.call(self, err, callback);
}
next();
});
} else {
next();
}
self.push(file);
if (symlinker.prototype.debug === false) {
gutil.log(gutil.colors.magenta(localPath(file.path)), 'symlinked to', gutil.colors.magenta(localPath(sym)));
},
//checking if the parent directory exists
function(next) {
mkdirp(symlink.directory, function(err) {
//ignoring directory err if it exists
if(err && err.code !== 'EEXIST') {
return errored.call(self, err, callback);
}
next();
});
}
], function () {
//this is a windows check as specified in http://nodejs.org/api/fs.html#fs_fs_symlink_srcpath_dstpath_type_callback
fs.stat(source.path, function(err, stat) {
if(err) {
return errored.call(self, err, callback);
}
cb();
};
fs.symlink(source, sym, function(err) {
// Most likely there's no directory there...
if (err && err.code === 'ENOENT') {
// Recursively make directories in case we want a nested symlink
return mkdirp(destination, function(err) {
if (err) {
self.emit('error', new gutil.PluginError(PLUGIN_NAME, err), file);
return cb();
}
fs.symlink(source, sym, finish);
});
}
finish(err);
source.stat = stat;
fs.symlink(source.resolved, symlink.path, source.stat.isDirectory() ? 'dir' : 'file', function(err) {
if(err) {
return errored.call(self, err, callback);
} else {
gutil.log(PLUGIN_NAME + ':' + gutil.colors.magenta(source.path), 'symlinked to', gutil.colors.magenta(symlink.path));
self.push(source);
return callback();
}
});
});
});
}
});
};
var relativesymlinker = function(symlink) {
return symlinker(symlink, path.relative);
});
};
var absolutesymlinker = function(symlink) {
return symlinker(symlink, path.resolve);
var relativesymlinker = function(symlink, options) {
return symlinker(symlink, 'relative', options);
};
var _setDebug = function(value) {
symlinker.prototype.debug = value;
var absolutesymlinker = function(symlink, options) {
return symlinker(symlink, 'absolute', options);
};
_setDebug(false);
// Expose main functionality under relative, for convenience
module.exports = relativesymlinker;
module.exports.relative = relativesymlinker;
module.exports.absolute = absolutesymlinker;
module.exports._setDebug = _setDebug;
module.exports._setDebug = function(value) {
debug = value;
};
{
"name": "gulp-symlink",
"version": "1.1.0",
"version": "2.0.0",
"description": "Create symlinks during your gulp build.",

@@ -24,17 +24,18 @@ "license": "MIT",

"dependencies": {
"gulp-util": "~2.2.14",
"mkdirp": "^0.4.0",
"through2": "^0.4.1"
"gulp-util": "~3.0.0",
"mkdirp": "~0.5.0",
"through2": "~0.5.1",
"async": "~0.9.0"
},
"devDependencies": {
"chai": "~1.9.0",
"chai": "~1.9.1",
"clear": "0.0.1",
"gulp": "~3.5.2",
"gulp-jshint": "~1.4.0",
"gulp-mocha": "~0.4.1",
"gulp-mocha": "~0.5.1",
"jshint-stylish": "~0.1.5",
"mocha": "~1.17.1",
"rimraf": "^2.2.6"
"mocha": "~1.20.1",
"gulp-jshint": "~1.7.1",
"gulp": "~3.8.6",
"rimraf": "~2.2.8"
},
"main": "index.js"
}

@@ -5,4 +5,2 @@ # [gulp](https://github.com/gulpjs/gulp)-symlink [![Build Status](https://travis-ci.org/ben-eb/gulp-symlink.svg?branch=master)](https://travis-ci.org/ben-eb/gulp-symlink) [![NPM version](https://badge.fury.io/js/gulp-symlink.svg)](http://badge.fury.io/js/gulp-symlink) [![Dependency Status](https://gemnasium.com/ben-eb/gulp-symlink.svg)](https://gemnasium.com/ben-eb/gulp-symlink)

**NOTE: Breaking changes are introduced in 1.0.0. gulp-symlink has been rewritten with a simpler API, that takes the output directory and renamed file as a single parameter. Existing gulpfiles using the old API will break if this module is substituted for the 0.4.x releases. Please take care to read the new API docs for migrating over from older versions. Thank you.**
## Installation

@@ -19,9 +17,8 @@

```js
var gulp = require('gulp');
var symlink = require('gulp-symlink');
gulp.task('default', function() {
return gulp.src('assets/some-large-video.mp4')
.pipe(symlink('build/videos')) // Write to the destination folder
.pipe(symlink('build/videos/renamed-video.mp4')) // Write a renamed symlink to the destination folder
return gulp.src('assets/some-large-video.mp4')
.pipe(symlink('build/videos')) // Write to the destination folder
.pipe(symlink('build/videos/renamed-video.mp4')) // Write a renamed symlink to the destination folder
});

@@ -32,21 +29,41 @@ ```

### symlink(symlinkpath) or symlink.relative(symlinkpath)
### symlink(path, [options]), symlink.relative(path, [options]) or symlink.absolute(path, [options])
Pass a `string` or a `function` to create the symlink. The function is passed the [vinyl](https://github.com/wearefractal/vinyl) object, so you can use `file.base`, `file.path` etc. Just make sure you return a string that is the location and or filename of the new symlink. For example:
Pass a `string` or a `function` to create the symlink.
The function is passed the [vinyl](https://github.com/wearefractal/vinyl) object, so you can use `file.base`, `file.path` etc.
For example:
```js
var path = require('path');
gulp.task('symlink', function() {
return gulp.src('assets/some-large-video.mp4')
.pipe(symlink(function(file) {
return path.join(file.base, 'build', file.relative.replace('some-large', ''));
}));
return gulp.src('assets/some-large-video.mp4')
.pipe(symlink(function(file) {
//here we return a path as string
return path.join(file.base, 'build', file.relative.replace('some-large', ''));
}));
});
gulp.task('symlink-vinyl', function() {
return gulp.src('assets/some-large-video.mp4')
.pipe(symlink.absolute(function(file) {
//here we return a Vinyl instance
return new gutil.File({
path: 'build/videos/video.mp4',
cwd: process.cwd()
}, {force: true});
}));
})
```
The string options work in the same way. If you pass a string like 'build/videos', the symlink will be created in that directory. If you pass 'build/videos/video.mp4', the symlink will also be renamed.
The function will be called as many times as there are sources.
### symlink.absolute(symlinkpath)
You might also want to give an array of destination paths:
The exact same as `symlink.relative` except this will create an *absolute symlink* instead.
```js
gulp.task('symlink', function() {
return gulp.src('modules/assets/', 'modules/client/')
.pipe(symlink(['./assets', './client']));
});
```
The default `symlink` performs a relative link. If you want an *absolute symlink* use `symlink.absolute` instead.

Sorry, the diff of this file is not supported yet