I want to synchronize a directory, which contains a symbolic link. This link should be transferred as symbolic link.
The documentation of gulp-rsync explains the option links
which seems to cover this.
First problem with gulp.src
(which does not support symbolic links) can be solved by using vinyl-fs. Works fine except the symbolic link, which is ignored, although listed by gulpDebug()
.
The used gulpfile.js
task looks like:
const gulp = require('gulp'),
gulpDebug = require('gulp-debug'),
merge = require('merge-stream'),
rsync = require('gulp-rsync'),
vfs = require('vinyl-fs');
gulp.task('rsyncFiles', function (done) {
const rsyncSrcClient =
vfs.src('src/**')
.pipe(gulpDebug())
.pipe(rsync({
root: 'src/',
hostname: remoteHostname,
destination: remoteTargetDir + '/src/',
links: true
}));
return merge(rsyncSrcClient);
});
Using rsync --link ...
manually from shell works as desired, the symbolic link is transferred as symbolic link.
Adding the option emptyDirectories: true
solves the problem.
The gulpfile.js
is now:
gulp.task('rsyncFiles', function (done) {
const rsyncSrcClient =
vfs.src('src/**')
.pipe(gulpDebug())
.pipe(rsync({
root: 'src/',
hostname: remoteHostname,
destination: remoteTargetDir + '/src/',
links: true,
emptyDirectories: true
}));
return merge(rsyncSrcClient);
});
Reason is the filtering mechanism inside the file node_modules/gulp-rsync/index.js.
On index.js#L49 there is the following source-snippet which is always false
for symbolic links:
sources = sources.filter(function(source) {
return !source.isNull() ||
options.emptyDirectories ||
(source.path === cwd && options.recursive);
});
Adding the option emptyDirectories: true
changes this behavior to result true
for symbolic links. Symbolic links are not longer filtered out and rsync is transferring the link as desired.