Merge files only if they go deeper than two levels - gulp

I have this file structure:
Root
Folder1
Subfolder1.1
Subfolder1.1.1
file_1.1.1.1.js
file_1.1.1.2.js
file_1.1.1.js
file_1.1.2.js
Subfolder1.2
Folder2
Folder3
I'm trying to accomplish the following gulp task that will take the root directory, in this case, the Root folder, and generate the following structure:
Root
Folder1
Subfolder1.1
Subfolder1.1.1.min.js
file_1.1.1.min.js
file_1.1.2.min.js
Subfolder1.2
Folder2
Folder3
As you can see, the files that are directly in the second level, e.g. Subfolder1.1, are just minified. All the files that go deeper than two levels will be concatenated and named after the second level folder containing them.
Is this possible to accomplish in gulp, and if it is, can anybody give me a clue on how to do it?

Maybe this can help you to run some tasks by folder.
Or maybe you can find some help on building such a thing yourself by iterating over directories.

Okay, I was able to do it, here is the code:
gulp.task('task',
function() {
// The input root dir
var root = 'root_in';
// The output root dir
var rootOut = 'root_out'
// first get all the folders in the in the root directory
var folders = fs.readdirSync(root)
.filter(function(file) {
return fs.statSync(path.join(root, file)).isDirectory();
});
return folders.map(function(folder) {
// get the files inside each folder
var files = fs.readdirSync(path.join(root, folder));
files.map(function(file) {
// in case it is a directory, concat all the files
if (fs.statSync(path.join(root, folder, file)).isDirectory()) {
return gulp.src(path.join(root, folder, file, '/**/*.js'))
.pipe(uglify())
.pipe(gulp_concat(file + '.js'))
.pipe(gulp.dest(path.join(root, folder)))
}
// if it is a regular file, just uglify it and output
else {
return gulp.src(path.join(root, folder, file))
.pipe(uglify())
.pipe(gulp.dest(path.join(rootOut, folder)));
}
});
});
});

Related

How to find all files in one directory that match files in other directory in gulp using del?

Basically, as part of my clean task, I'd like to delete in the root folder all files that are present in my src folder, automatically. Because there are files in the root that aren't in src, I can't just delete all of them, and I'd like to keep the process dynamic (automatically determine matching files) rather than manual (explicitly listing the files to delete).
Right now, I'm doing this manually:
const deleteViewFiles = done => {
del.sync([
'./page-*.php',
'./header.php',
]);
done();
}
But what I'd like is, look at ./src/views/, find all direct descendants of ./src/views/ (not subfolders), and delete them at the root.
eg. Let's say in ./src/views/ I have page-1.php, header.php, my-dog.php, mermaid.html, I want to delete all those files from root without listing them in my delete task.
OK. Here's what I ended up doing.
I used glob to store all files in my src directory into an array.
Then, I replaced the view folder base path with root base path. Then I used this array as an argument for my del function.
(I stored paths in a config file, here's a snippet (the real object is much bigger):)
paths = {
views: {
src: `${dirs.src}views/`,
dest: `${dirs.base}views/`,
rootFiles: `${dirs.src}views/*.*`,
folders: `${dirs.src}views/*/*`
}
}
import { paths } from '../config';
const clean = done => {
// get all files at root of views directory
const viewsDirRootFiles = glob.sync(paths.views.rootFiles);
// replace views dir in base of filepaths with root
const rootFiles = viewsDirRootFiles.map(f => f.replace(paths.views.src, paths.dirs.base));
// combine root view files with other folders/files to delete to generate final deletion-target array
const filesToDelete = [
...rootFiles,
'./views',
];
del.sync(filesToDelete);
done();
}

gulp src - exclude folders from being copied on task execution

I know this might sound like a pretty easy question, but I've been struggling for quite a while with no real result.
I'm trying to exclude some folders from being copied with a watch command in the gulp.
I've followed this example (among others) but it doesn't seem to behave like expected.
Basically, the folder structure is as following:
- src
| - assets
| - - _scripts/*
| - - _styles/*
| - - fonts/*
| - - images/*
| - index.html
| - favicon.ico
And the task I'm trying to run is as below:
gulp.task('copy', () => {
return gulp.src(['src/**/*', '!src/assets/_*/**/*'])
.pipe(gulp.dest('./www'))
});
I'd like to copy all the files inside src/ except for ./src/assets/_styles and ./src/assets/_scripts, but when the task runs, these two folders are copied as empty folders (which they shouldn't, as from the article above).
For future reference, the article above says this:
---> for this folder structure:
file.txt
folder
folder/file.txt
folder/_subfolder
folder/_subfolder/file.txt
folder/subfolder
folder/subfolder/file.txt
_folder
_folder/file.txt
_folder/_subfolder
_folder/_subfolder/file.txt
_folder/subfolder
_folder/subfolder/file.txt
---> when using this task:
gulp.task('default', function() {
return gulp.src([
'src/**/*', //select all files
'!src/**/_*/', //exclude folders starting with '_'
'!src/**/_*/**/*', //exclude files/subfolders in folders starting with '_'
])
.pipe(gulp.dest('dist'));
});
---> the result will be:
file.txt
folder
folder/file.txt
folder/subfolder
folder/subfolder/file.txt
The version of gulp is the one below:
CLI version 3.9.1
Local version 3.9.1
I do I prevent them from being copied over?
Thanks
Try:
gulp.task('copy', () => {
return gulp.src(['src/**/*.*', '!src/assets/_*/**/*.*'])
.pipe(gulp.dest('dist'))
});
[Edit]: You can also use the nodir option with your original glob:
gulp.task('copy', () => {
// return gulp.src(['src/**/*.*', '!src/assets/_*/**/*.*'])
return gulp.src(['src/**/*', '!src/assets/_*/**'], {nodir: true})
.pipe(gulp.dest('dist'))
});
glob options including nodir
You should use both this !src/**/_*' and this !src/assets/_*/**/*
Try this:
gulp.task('copy', () => {
return gulp.src(['src/**/*', '!src/**/_*/', '!src/assets/_*/**/*'])
.pipe(gulp.dest('./www'))
});
Hope this may help you.

Gulp partially remove directories structure

My directories structure is similar to this:
app/
directory1/
assets/
images/
js/
directory2/
assets/
images/
dist/
assets/
images/
js/
What I try to achieve using Gulp is to "gather" assets from directories 1, 2, ... and place them into the dist/assets/ so I wrote this:
gulp.task('gather-assets', function() {
gulp.src('app/*/assets/**').pipe(gulp.dest('dist/assets/'));
});
The problem is that after running this function it will create a path like this:
dist/assets/directory1/assets/images
Following the recommendations from this question I tried to use gulp-rename, but my case is different, and if I use gulp-rename like this:
gulp.task('gather-assets', function() {
gulp.src('app/*/assets/**').pipe(rename({dirname: ''})).pipe(gulp.dest('dist/assets/'));
});
it will surely remove unnecessary path at the place of * asterisk, but it will remove the ** path as well. So files from both images/ and js/ will be copied to assets/ without subdirectories. What solution is available for me for this scenario?
Gulp-flatten will work for you.
var flatten = require('gulp-flatten');
gulp.task('gather-assets', function() {
return gulp.src('app/*/assets/**')
// .pipe(rename({ dirname: '' }))
// -2 will keep the last two parents : assets/images or assets/js
.pipe(flatten({ includeParents: -2 }))
.pipe(gulp.dest('dist'));
});
And if you wanted to use gulp-rename: [both gulp-flatten and gulp-rename are just doing string manipulations of each file's directory structure]
// .pipe(flatten({ includeParents: -2 }))
.pipe(rename(function (file) {
let tempArray = file.dirname.split(path.sep);
// remove the first array item : directory1 or directory2
// rejoin the remaining array items into a directory string
let temp = tempArray.slice(1).join(path.sep);
file.dirname = temp;
}))

How to dynamically specify destination folder to gulp

I have a folder structure where I keep all my assets similar to this.
-page1
-page1.html
-stylesheets
-page1
-page1style.css
-page2
page2.html
stylesheets
page2
page1style.css
I realize that this isn't the best folder structure but I choose it this way before I could have predicted problems. In my .html files I reference a stylesheet like so /stylesheets/name-of-page/foo.css. Now I am having problems writing a gulp script since all the minified files are being placed at the specified destination folder but have the following structure.
-build
-page1
-stylesheets
-page1.css
when I would like to have something like this
-build
-page1
-page.css
TL;DR or if my question is logic is scrambled : I would like to see the src path of the file at runtime and then perform some string manipulation to calculate its destination.
What you're looking for is gulp-rename:
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('default', function() {
gulp.src('src/**/*')
.pipe(rename(function(file) {
if (file.extname === '.css') {
file.dirname = //change directory to something else
file.basename = //change file name (without extension) to something else
}
}));
});
I also suggest you look into the path module instead of direct string manipulation to adjust the paths of your files.

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.