Gulp partially remove directories structure - gulp

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;
}))

Related

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.

Merge files only if they go deeper than two levels

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)));
}
});
});
});

How to export (dest) in multiple folder [duplicate]

I am trying to copy files from one folder to another folder using Gulp:
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
]).pipe(gulp.dest('./public/assets/css/'));
});
The above code is copying one.css & two.css to the public/assets/css folder.
And if I use gulp.src('./source/css/*.css') it will copy all CSS files to the public/assets/css folder which is not what I want.
How do I select multiple files and keep the folder structure?
To achieve this please specify base.
¶ base - Specify the folder relative to the cwd. Default is where the glob begins. This is used to determine the file names when saving in .dest()
In your case it would be:
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
], {base: './source/'})
.pipe(gulp.dest('./public/assets/'));
});
Folder structure:
.
├── gulpfile.js
├── source
│ ├── css
│ └── other
│ └── css
└── public
└── assets
I use gulp-flatten and use this configuration:
var gulp = require('gulp'),
gulpFlatten = require('gulp-flatten');
var routeSources = {
dist: './public/',
app: './app/',
html_views: {
path: 'app/views/**/*.*',
dist: 'public/views/'
}
};
gulp.task('copy-html-views', task_Copy_html_views);
function task_Copy_html_views() {
return gulp.src([routeSources.html_views.path])
.pipe(gulpFlatten({ includeParents: 1 }))
.pipe(gulp.dest(routeSources.html_views.dist));
}
And there you can see the documentation about gulp-flatten: Link
gulp.task('move-css',function(){
return gulp
.src([ 'source/**'], { base: './' })
.pipe(gulp.dest('./public/assets/css/'));
});
Your own code didn't include the entire dir tree of source 'source/**' and the base {base:'./'} when calling to gulp.src which caused the function to fail.
The other parts where fine.
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
]).pipe(gulp.dest('./public/assets/css/'));
});

Include parent directory in gulp src task

I would like to create a resources.zip file which will contain css/styles.css.
So far I have got most of this working, the only problem is the archive only contains the styles.css file and not its parent directory css.
gulpfile.js
const gulp = require('gulp');
const zip = require('gulp-zip');
gulp.task('default', () => {
return gulp.src('css/*')
.pipe(zip('resources.zip'))
.pipe(gulp.dest('build'));
});
I think you need to setup the base for the gulp.src:
gulp.src('css/*', {base: '.'})
This is because the default base is:
Default: everything before a glob starts (see glob2base)
source. Zipped file path: zip.

gulp if one file changes, compile the rest

I'm using gulp-watch to watch for changes
and right now I have it ignore layout files. The problem is that whenever I update a layout file, I have to change some other file for it to compile. Is there any way using gulp-watch to watch everything and then compile a part of it? I saw this relevant link but it did not use gulp-watch.
I misread this question. I've left my original answer at the bottom for reference anyway.
You could use gulp-if.
gulp.task('stream', function () {
return gulp.src('dir/**/*.*')
.pipe(watch('dir/**/*.*'))
.pipe(gulpif(function (file) {
return file.ext != ".layout"//your excluded extension
}, processIfTrue()))
.pipe(gulp.dest('build'));
});
That link does use gulp-watch. In fact, as I understand, that link explains exactly what you want to do.
The gulp-watch and whatever task you run on change take separate gulp.src instances.
You can, for example, use gulp.src('**/*.*') for your gulp.watch, and then gulp.src('**/*.less') for your compilation task.
You can set 2 separate watchers to run, and modifying each respective file listed below in src would trigger the respective task for that filename:
$ tree -I node_modules
.
├── gulpfile.js
├── package.json
└── src
├── layout-file-1.html
├── layout-file-2.html
├── other-file-1.html
└── other-file-2.html
1 directory, 6 files
gulpfile.js - gulp.watch() function
var gulp = require('gulp')
// files with the word "layout" in them
var layoutFiles = 'src/**/*layout*';
// files without the word "layout" in them
var otherFiles = ['src/**/*', '!'+layoutFiles];
// these tasks will show as completed in console output
gulp.task('build-layout-files');
gulp.task('build-other-files');
gulp.task('watch', function(cb) {
// watch only layoutFiles
gulp.watch(layoutFiles, ['build-layout-files'])
// watch only otherFiles
gulp.watch(otherFiles, ['build-other-files'])
})
gulp.task('default', ['watch'])
gulpfile.js - gulp-watch module
var gulp = require('gulp')
var watch = require('gulp-watch')
// use print to debug watch processes
var print = require('gulp-print')
// files with the word "layout" in them
var layoutFiles = 'src/**/*layout*';
// files without the word "layout" in them
var otherFiles = ['src/**/*', '!'+layoutFiles];
gulp.task('watch:layout-files', function(cb) {
watch(layoutFiles, function () {
gulp.src(layoutFiles)
.pipe(print(function(fileName) {
return "Compiling Layout File: "+fileName;
}))
.pipe(gulp.dest('build/layout-files'))
});
})
gulp.task('watch:other-files', function(cb) {
watch(otherFiles, function () {
gulp.src(otherFiles)
.pipe(print(function(fileName) {
return "Compiling Other File: "+fileName;
}))
.pipe(gulp.dest('build/other-files'))
});
})
gulp.task('default', ['watch:layout-files', 'watch:other-files'])