Gulp: copy file to multiple folders starting with specific string - gulp

I'm working to copy a file style.scss from specific directory to multiple folders that start with skin-.
In fact, i don't know how to tell gulp to choose folders that start with this string skin-.
Here is my gulp code:
// Copy Files
gulp.task( "copyFiles" , function() {
return gulp.src( "app/scss/style.scss" )
.pipe( gulp.dest( "app/scss/skins/skin-*" ) );
});
At command prompt, it says that the task is running but with no result.
I have searched a lot around for that, but i didn't find a method. I found this question here which near to my question context, but it didn't help! Gulp copy single file (src pipe dest) with wildcarded directory

Modifying only slightly #davidmdem's answer at saving to multiple destinations:
const gulp = require("gulp");
const glob = require("glob");
const destinationFolders = glob.sync("app/scss/skins/skin-*");
gulp.task('copyFiles', function () {
var stream = gulp.src("app/scss/style.scss");
destinationFolders.forEach(function (skinFolder) {
stream = stream.pipe(gulp.dest(skinFolder));
});
return stream;
});
You cannot put a glob into gulp.dest as you are trying in your question.

Related

Seeking wrapper to run Gulp pipe operations in parallel

I've got a fairly simple Gulp task that simply scoops some files that match a glob and uploads them to Google Cloud via the gulp-gcloud-publish package as in the following:
const gcloud = require('gulp-gcloud-publish');
function publish() {
return src(dest + '/*/app.*')
.pipe(gcloud({
//options
}));
}
This works fine, but it uploads the files sequentially. There are a few of them, so this takes a little while and I'd rather be able to upload them all in parallel sets.
I tried instead to glob it myself:
const glob = require('glob');
const gcloud = require('gulp-gcloud-publish');
const { src } = require('gulp');
function publish() {
const files = glob.sync(path);
let stream;
files.forEach(function(file) {
stream = src(file)
.pipe(gcloud({
//...
}));
return stream;
});
}
This worked great - the task still runs sequentially, but the uploads start without waiting on the last to complete. However, for whatever reason, while glob captures the relative path to the file, when I put that file path into src, gulp drops it down to just the file name itself (as seen if I tap the pipe before gcloud).
So I tried setting the base option instead:
const glob = require('glob');
const gcloud = require('gulp-gcloud-publish');
const { src } = require('gulp');
function publish() {
const files = glob.sync(path);
let stream;
files.forEach(function(file) {
stream = src(file, {base: '.')
.pipe(gcloud({
//...
}));
return stream;
});
}
Unfortunately, now src captures the absolute path to the file instead of just the file and its relative parent. I also just noticed that my glob is removing periods from file names that contain more than one (e.g. app.map.js is turning into appmap.js), so that's not right either.
Scrapping the last two attempts then, is there any way to run the pipe of an operation that otherwise works perfectly fine and run the pipes within a task in parallel?

Check if file contains a specific string in GULP

I am attempting to use GULP4 to compress a series of HTML and PHP files. A problem I am running into is some of the files contain a <pre> tag. I do not want to compress those files because it would mess up that file. Is there a way using GULP I can evaluate if a file contains the string <pre> and if it does, avoid running compression on that file?
Here is my relevant code:
const gulp = require('gulp');
const {src, series, parallel, dest} = require('gulp');
const GulpReplace = require('gulp-replace');
function no_2_spaces_purchasingdemand_php()
{
console.log("no 2 spaces purchasingdemand_php")
return gulp.src
(
'dist/purchasingdemand/**/*.php'
, { base: "./" }
)
.pipe
(
GulpReplace(' ','☺☻')
)
.pipe
(
GulpReplace('☻☺','')
)
.pipe
(
GulpReplace('☺☻',' ')
)
.pipe(gulp.dest('./'))
}
exports.default = series(no_2_spaces_purchasingdemand_html)
I don't know what you are using to compress files, but here is a general example:
const gulp = require('gulp');
const filter = require('gulp-filter');
const minify = require('gulp-htmlmin');
gulp.task("preFilterTask", function () {
// return true if want the file in the stream
const preFilter = filter(function (file) {
let contents = file.contents.toString();
return !contents.match('<pre>');
});
return gulp.src("./*.html")
.pipe(preFilter)
.pipe(minify({ collapseWhitespace: true }))
.pipe(gulp.dest('filtered'));
});
gulp.task('default', gulp.series('preFilterTask'));
gulp-htmlmin by itself - for html files only - will not minify the <pre>...</pre> portion of an html file. So if you use gulp-htmlmin for html minification, you don't need to filter out those with <pre> tags.
I still showed how to filter based on file content using the gulp-filter plugin. It can access each file's contents. Return false from the filter function if you do not want that file to pass to the next pipe.

How to unzip multiple files in the same folder with Gulp

I'd like to unzip multiple zip files that are inside a single folder. Every unzipped file will be unpacked into a folder with the same name as the original zip file and added as a sub folder to the original folder containing the original zips.
Something like this:
parent(folder)
-a.zip
-b.zip
-c.zip
would become:
parent(folder)
-a(folder)
--a.zip contents here
-b(folder)
--b.zip contents here
-c(folder)
--c.zip contents here
I believe the code i have so far is a nice try but seems like it's executing asynchronously in the pipeline (i'm obviously not a Gulp expert). All the zip files are being looked at but only the last one seems to get all the content, and then some from other zips. Run it with one zip file in the folder and it works perfectly.
var zipsPath = 'src/';
var currentZipFileName;
function getZips(dir) {
return fs.readdirSync(dir)
.filter(function (file) {
return file.indexOf(".zip") > 0;
});
}
gulp.task('init', function (done) {
var zips = getZips(zipsPath);
var tasks = zips.map(function (zip) {
console.log("zip", zip, path.join(zipsPath, zip));
return gulp.src(path.join(zipsPath, zip), {
base: '.'
})
.pipe(tap(function (file, t) {
currentZipFileName = path.basename(file.path);
}))
.pipe(unzip({ keepEmpty : true }))
.pipe(gulp.dest(function (path) {
var folderName = currentZipFileName.replace(".zip", "");
var destination = "./src/" + folderName;
//console.log("destination", destination);
return destination;
}))
.on('end', function() {
console.log('done');
done();
});
});
return tasks;
});
Expected results: all the zip files should be unpacked.
Actual results: most of the content is being dumped into the last zip file looked at.
Thanks for the help
Your problem lies here:
.pipe(tap(function (file, t) {
currentZipFileName = path.basename(file.path);
}))
You are trying to set a variable in one pipe to use in a later pipe. That doesn't work, there are a few questions here about it, but it just doesn't work - your variable will probably have the last value in it when the gulp.dests start firing or undefined - I think it is based on unpredictable timing.
In any case you don't need to set that variable - you already have the value of the desired folder name in your zips.map(zip) {} the zip item. You can use that in the gulp.dest just fine.
gulp.task('init', function (done) {
var zips = getZips(zipsPath);
var tasks = zips.map(function (zip) {
return gulp.src(zipsPath + "/" + zip)
// .pipe(tap(function (file, t) {
// currentZipFileName = path.basename(file.path);
// }))
.pipe(unzip({ keepEmpty: true }))
.pipe(gulp.dest(path.join("src", path.basename(zip, ".zip"))))
.on('end', function() {
done();
});
});
return tasks;
});
Also avoid using path.join in your gulp.src for the reasons stated here: gulpjs docs on glob separators:
The separator in a glob is always the / character - regardless of the operating system - even in Windows where the path separator is \\. In a glob, \\ is reserved as the escape character.
Avoid using Node's path methods, like path.join, to create globs. On Windows, it produces an invalid glob because Node uses \\ as the separator. Also avoid the __dirname global, __filename global, or process.cwd() for the same reasons.

Copy new and modified files to different folder with Gulp

I'm trying to set up a gulp task which scans my development folder for any new or changed files, and then copies them to my local server with the same folder structure. And it should also do this every time I edit or change a file.
I seem to have something that kinda works, but it's extremely slow up to the point where I don't know if it actually works at all. (The notification message doesn't show up at all after 30+ minutes)
Could someone point in the right direction on how to set this up correctly?
// Server folder
var projectWWW = 'C:/wamp64/www/myproject';
// Files to be copied (everything excluding scss files)
var copySRC = ['./**/*', '!./**/*.{scss}'];
// Require gulp & plugins
var gulp = require('gulp');
var newer = require('gulp-newer');
var notify = require('gulp-notify');
// Copy files task
gulp.task( 'copyFiles', function() {
gulp.src( copySRC )
.pipe( newer( projectWWW ) )
.pipe( gulp.dest( projectWWW ) )
.pipe( notify( { message: 'TASK: "copyFiles" Completed!', onLast: true } ) );
});
// Watch tasks
gulp.task( 'default', ['copyFiles'], function () {
gulp.watch( copySRC, [ 'copyFiles' ] ); // Copy on file changes.
});
i ran the same code on my local for a test app and it works.
var copySRC = ['./**/*', '!./node_modules/**'];

Gulp: concatenate a file to each separate sass process

I wrote a gulp task to process all scss files in one folder into separate css files.
gulp.task('process', function () {
gulp.src(['./base.scss', './layout/*.scss'])
.pipe(sass())
.pipe(gulp.dest('dist'))
});
Now I want to concatenate one file (base.scss) to each scss process; how can I do this?
This should help you but I didn't test it. Gulp-foreach is good for you, it will treat each file from gulp.src as its own stream which you can manipulate separately. The code below then appends your base.scss to each stream, then concatenates them and then they go through the sass pipe.
var foreach = require('gulp-foreach');
var concat = require('gulp-concat');
var addsrc = require('gulp-add-src');
gulp.task('default', function () {
return gulp.src('./layout/*.scss')
// treats each file in gulp.src as a separate stream
.pipe(foreach(function (stream, file) {
return stream
// append or prepend
.pipe(addsrc.append('./base.scss'))
// you do have access to the 'file' parameter here if you need to rename
.pipe(sass())
.pipe(concat(path.basename(file.path)))
.pipe(gulp.dest('dist'));
}));
});
Let me know if it works for you.