Dynamic filename in gulp-zip - gulp

I try to generate multiple zip files with gulp-zip
packages
- package-1
- package-2
to
build
- package-1.zip
- package-2.zip
At the moment my task looks like this:
gulp.task('zip', function () {
return gulp.src("packages/*")
.pipe(zip("archive.zip"))
.pipe(gulp.dest("build"));
});
This generates a single zip file names archive.zip which contains my two packages.
How to get 2 separate zipfiles?
How to pass the folder name to the zip function?

You can call the zip command twice in your zip task, like so:
gulp.task('zip', function () {
gulp.src("packages/package-1/**")
.pipe(zip("archive-1.zip"))
.pipe(gulp.dest("build"));
return gulp.src("packages/package-2
.pipe(zip("archive-2.zip"))
.pipe(gulp.dest("build"));
});
This will result in 2 zip-files in your build folder. Hope this helps.

Related

How to build a list of links to html files in Gulp?

How can you use Gulp to gather in one html file a list of all the pages that are in the directory?
For example, in the build directory I have two files contact.html with title "Contacts" and faq.html with the title "Frequently asked questions", I need to get them and create a ui.html which would be a list of links to files of the form:
Frequently asked questions
Contacts
Well, with the addition of step your design (a connected css file).
Found the gulp-listing module, but it can not be customized, there it is as follows:
gulp.task('scripts', function() {
return gulp.src('./src/*.html')
.pipe(listing('listing.html'))
.pipe(gulp.dest('./src/'));
});
I used two gulp modules for do this.
gulp-filelist - for create file list
gulp-modify-file - for update this file
gulp
.src(['./html/**/*.html'])
.pipe(require('gulp-filelist')('filelist.js', { relative: true }))
.pipe(require('gulp-modify-file')((content) => {
const start = 'var list = '
return `${start}${content}`
}))
.pipe(gulp.dest('js'))
After run gulp, you got in js/filelist.js something like this:
var list = [
"Cancellation/template.html",
"Cancellation/email.html",
]
You can add this script in your html file, and with js display all info.

How to push a gulp pipeline onto another

I would like to process a series of folders through the build pipeline. For each folder I start another gulp pipeline that will create some source files. Finally I'd like to pipe them all together through the zip() plugin to produce a final artifact.
The following pseudocode shows my approach. However, I cannot push the result of the gulp.src to the current pipeline.
return gulp.src(someFolder)
.pipe(through(function(folder, enc, cb){
// how to add the result of the following line to my
// own pipeline????
this.push(gulp.src(path.join(folder, "whatever"))
.pipe(somePlugin()));
}))
.pipe(zip(....))
.pipe(gulp.dest(....));
Any hints how to combine those pipelines together?
This is exactly what gulp-foreach is intended for. Using that the equivalent of the code you posted would look like this:
var foreach = require('gulp-foreach');
return gulp.src(someFolder)
.pipe(foreach(function(stream, folder) {
return gulp.src(path.join(folder.path, "whatever"))
.pipe(somePlugin());
}))
.pipe(zip(....))
.pipe(gulp.dest(....));
Note that the above will discard all files from the original gulp.src(someFolder). They will not be included in the ZIP. If you want to keep those around as well you can use merge-stream:
var foreach = require('gulp-foreach');
var merge = require('merge-stream');
return gulp.src(someFolder)
.pipe(foreach(function(stream, folder) {
return merge(stream,
gulp.src(path.join(folder.path, "whatever"))
.pipe(somePlugin()));
}))
.pipe(zip(....))
.pipe(gulp.dest(....));

How to zip multiple folders generating multiple .zip files in gulp?

My folder structure looks like this:
- /projects
- /projects/proj1
- /projects/proj2
- /projects/proj3
- /zips
For each folder in projects (proj1, proj2 and proj3) I want to zip contents of each of those folders and generate proj1.zip, proj2.zip and proj3.zip in /zips folder.
Following example function generates single zip file from proj1 folder
zip = require('gulp-zip');
gulp.task('default', function () {
return gulp.src('./projects/proj1/*')
.pipe(zip('proj1.zip'))
.pipe(gulp.dest('./zips'));
});
But how I can execute such task for each folder in projects? I can get all folders to zip by gulp.src('./projects/*') but what then?
Old question I know and I am pretty new to gulp so this might be considered a hack but I have just been trying to do what you are after and I ended up with this.
My file structure is this:
proj
proj/dist
proj/dist/sub01
proj/dist/sub02
proj/dist/sub03
proj/zipped
And my task ended up like this:
var gulp = require("gulp");
var foreach = require("gulp-foreach");
var zip = require("gulp-zip");
gulp.task("zip-dist", function(){
return gulp.src("./dist/*")
.pipe(foreach(function(stream, file){
var fileName = file.path.substr(file.path.lastIndexOf("/")+1);
gulp.src("./dist/"+fileName+"/**/*")
.pipe(zip(fileName+".zip"))
.pipe(gulp.dest("./zipped"));
return stream;
}));
});
It grabs all the first level contents of ./dist as its source and then pipes it to gulp-foreach.
gulp-foreach looks at each item and I use a plain javascript substr() to get the name of the current item which I store as a variable.
Finally I set a new src using the stored fileName var and pipe the result to gulp-zip using the stored var again as the name of the zipped file.
The result is a structure that looks like this:
proj
proj/dist
proj/dist/sub01
proj/dist/sub02
proj/dist/sub03
proj/zipped
proj/zipped/sub01.zip
proj/zipped/sub02.zip
proj/zipped/sub03.zip
Again, I am a million miles from being an expert but this worked for me and if I understand the question might work for you as well or at least give you some ideas.

How to make gulp-newer work with gulp-rev?

The setup is as simple as this:
gulp.task('rev-js', function() {
return gulp.src('/js/main.js, {base: '.'})
.pipe(newer('_build'))
.pipe(rev())
.pipe(gulp.dest('_build'))
.pipe(rev.manifest())
.pipe(gulp.dest('_build/rev/js'));
});
gulp-newer obviously doesn't work here since the destination file gets a different name. Any workaround to make gulp-newer (or gulp-changed) work in this case?
In the gulp-newer options documentation I read that it supports passing in a configuration object instead of the destination. In that configuration object you can specify a mapping function from old to new files. So instead of
newer('_build')
you can write
newer({dest: '_build', map: mappingFn})
The mapping function takes the relative name of the file and expects it to return a translated name - see the index.js file. You can define a function that uses the previously generated rev-manifest.json manifest to look up the correct filename. Id put something along these lines in your build script (not tested):
gulp.task('rev-js', function() {
// get the existing manifest
// todo: add logic to skip this if file doesn't exist
var currentManifest = JSON.parse(fs.readFileSync('rev-manifest.json', 'utf8'));
// mapping function for gulp-newer
function mapToRevisions(relativeName) {
return currentManifest[relativeName]
}
return gulp.src('/js/main.js, {base: '.'})
.pipe(newer({dest: '_build', map: mapToRevisions}))
.pipe(rev())
.pipe(gulp.dest('_build'))
.pipe(rev.manifest())
.pipe(gulp.dest('_build/rev/js'));
});
May I suggest gulp-newy in which you can manipulate the path and filename in your own function. Then, just use the function as the callback to the newy(). This gives you complete control of the files you would like to compare.
This will allow 1:1 or many to 1 compares.
newy(function(projectDir, srcFile, absSrcFile) {
// do whatever you want to here.
// construct your absolute path, change filename suffix, etc.
// then return /foo/bar/filename.suffix as the file to compare against
}

How to zip up zip files using Gulp Zip

I've started using Gulp JS and must admit I'm finding it really useful.
One of the tasks I need to perform is zip up a collection of folders into individual zip files, one for each folder and then zip all this zipped files up into one single zip file. Using Gulp-Zip I've managed to get this far:
var modelFolders = [
'ELFH_Check',
'ELFH_DDP',
'ELFH_Free'
];
gulp.task('zipModels', function () {
for (var i = 0; i < modelFolders.length; i++) {
var model = modelFolders[i];
gulp.src('**/*', {cwd: path.join(process.cwd(), '/built_templates/' + model) })
.pipe(zip(model + '.zip'))
.pipe(gulp.dest('./built_templates'));
};
});
This works and outputs ELFH_Check.zip, ELFH_DDP.zip and ELFH_Free.zip. However, I then need to zip up these zip files into one zip file called "Templates.zip" and I've not managed to get this task to work:
// zip up model files
gulp.task('zipTemplate', ['zipModels'], function () {
gulp.src('*.zip', {cwd: path.join(process.cwd(), './built_templates/') })
.pipe(zip('Templates_.zip'))
.pipe(gulp.dest('./built_templates'));
});
Does anyone know if this is possible or what I'm doing wrong?
I saw the problem as well, and it seems to be related to the cwd option somehow. I'll investigate further.
After #OverZealous comment, I investigated further and found two issues:
As he said, you need to hint gulp to wait until the end of the dependency task (zipModels), by returning a stream from it. As you have multiple streams, you can use event-stream.merge to return a bundle stream.
The reason why the bundle zip wouldn't work, is because you cwd points to /built_templates/, and the second slash is causing some problem. To work properly, you need to remove the trailing slash, so it should be path.join(process.cwd(), '/built_templates').
IMPORTANT
Anyway, you should avoid temporary files. Gulp philosophy is to try using pipes to avoid IO. In that direction, what you want to do is to cut the intermediary dest steps, merge the streams, zip them, and finally, output them.
Something like that:
var es = require('event-stream');
var modelFolders = [
'ELFH_Check',
'ELFH_DDP',
'ELFH_Free'
];
gulp.task('zipModels', function () {
var zips = [],
modelZip;
for (var i = 0; i < modelFolders.length; i++) {
var model = modelFolders[i];
modelZip = gulp.src('**/*', {cwd: path.join(process.cwd(), '/built_templates/' + model) })
.pipe(zip(model + '.zip'));
// notice we removed the dest step and store the zip stream (still in memory)
zips.push(modelZip);
};
// we finally merge them (the zips), zip them again, and output.
return es.merge.apply(null, zips)
.pipe(zip('templates.zip'))
.pipe(gulp.dest('./'));
});
By the name of your folder (built_templates), it seems you have some other task that will generate the temporary built files. Preferably, you don't want these as well. You should pipe their streams directly to the ZIP stream, a finally, to the bundle-zip stream. By doing that, you would have a simple stream flow, with one disk read, and one disc write at the end, with no temporary files.
If you need them to be different tasks, consider having a function that will generate the stream up to the step before the gulp.dest pipe, and use this function on all subtasks.
Additionally, always try to hint your async tasks by returning a stream, a promise or receiving a callback function, and advise the end of the task.