index.js
// Plugin level function(dealing with files)
Plugin level function(dealing with files)
Plugin level function ( dealing with files )
function gulpSymlink(dest, options) {
  options = typeof options == 'object' ? options : {}
  options.force = options.force === undefined ? false : options.force
  if (!dest) {
    throw new PluginError({plugin: PLUGIN_NAME, message: "Missing destination link"})
  }
  if(dest instanceof Array) {
    var destinations = dest.slice()
  }
  var stream = through.obj(function(source, enc, callback) {
    var self = this, symlink
    source.path = p.resolve(source.cwd, source.path)
    symlink = destinations !== undefined ? destinations.shift() : dest
    symlink = typeof dest == 'function' ? dest(source) : symlink
    symlink = symlink instanceof File ? symlink : new File({path: symlink})
    symlink.path = p.resolve(symlink.cwd, symlink.path)
    var relative_symlink_source = p.relative(p.dirname(symlink.path), source.path)
    var exists = existsSync(symlink.path)
    if(exists && !options.force) {
      this.emit('error', new PluginError({plugin: PLUGIN_NAME, message: 'Destination file exists ('+dest+') - use force option to replace'}))
      this.push(source)
      return callback()
    }
    if(exists && options.force === true)
      rm.sync(symlink.path) 
    if(!fs.existsSync(p.dirname(symlink.path)))
      mkdirp.sync(p.dirname(symlink.path))
    source.stat = fs.statSync(source.path)
    fs.symlink(options.relative ? relative_symlink_source : source.path, symlink.path, source.stat.isDirectory() ? 'dir' : 'file', function(err) {
      if(err)
        self.emit('error', new PluginError({plugin: PLUGIN_NAME, message: err}))
      else
        gutil.log(PLUGIN_NAME + ':', gutil.colors.yellow(symlink.path), '→', gutil.colors.blue(options.relative ? relative_symlink_source : source.path))
      self.push(source)
      callback()
    })
  })
  return stream
}
function gulpSymlink ( dest , options ) { options = typeof options == 'object' ? options : { } options . force = options . force === undefined ? false : options . force if ( ! dest ) { throw new PluginError ( { plugin : PLUGIN_NAME , message : "Missing destination link" } ) } if ( dest instanceof Array ) { var destinations = dest . slice ( ) } var stream = through . obj ( function ( source , enc , callback ) { var self = this , symlink source . path = p . resolve ( source . cwd , source . path ) symlink = destinations !== undefined ? destinations . shift ( ) : dest symlink = typeof dest == 'function' ? dest ( source ) : symlink symlink = symlink instanceof File ? symlink : new File ( { path : symlink } ) symlink . path = p . resolve ( symlink . cwd , symlink . path ) var relative_symlink_source = p . relative ( p . dirname ( symlink . path ) , source . path ) var exists = existsSync ( symlink . path ) if ( exists && ! options . force ) { this . emit ( 'error' , new PluginError ( { plugin : PLUGIN_NAME , message : 'Destination file exists (' + dest + ') - use force option to replace' } ) ) this . push ( source ) return callback ( ) } if ( exists && options . force === true ) rm . sync ( symlink . path ) if ( ! fs . existsSync ( p . dirname ( symlink . path ) ) ) mkdirp . sync ( p . dirname ( symlink . path ) ) source . stat = fs . statSync ( source . path ) fs . symlink ( options . relative ? relative_symlink_source : source . path , symlink . path , source . stat . isDirectory ( ) ? 'dir' : 'file' , function ( err ) { if ( err ) self . emit ( 'error' , new PluginError ( { plugin : PLUGIN_NAME , message : err } ) ) else gutil . log ( PLUGIN_NAME + ':' , gutil . colors . yellow ( symlink . path ) , '→',  g til.c o lors.b l ue(o p tions.r e lative ? r lative_symlink_source : s urce.p a th)) self . push ( source ) callback ( ) } ) } ) return stream }
Plugin level function(dealing with files)
Plugin level function ( dealing with files )
//copy array because we'll shift values //resolving absolute path from source // source.relative = p.relative(source.cwd, source.path) //Array of destinations is passed //if dest is a function simply call it //is the previous result a File instance ? //resolving absolute path from dest //relative path between source and link //check if the destination path exists //No force option, we can't override! //remove destination if force option //I'm aware that this is bad \o/ //create destination directories //this is a windows check as specified in http://nodejs.org/api/fs.html#fs_fs_symlink_srcpath_dstpath_type_callback