Rename file based on regex in Gulp - gulp

Say I have a LESS CSS directory structure like this:
less/
core/
_main.less
header.less
body.less
footer.less
contact/
_main.less
form.less
details.less
I want to write a Gulp task that will look for the _main.less files in each subdirectory of the less/ dir, pass this to gulp-less and write the output to the css/ dir like this:
css/
core.css
contact.css
Because _main.less includes the other files in it's directory, only the _main.less files will have to be parsed, but I want the output file to have the name of the directory it's in.
So far I have this:
gulp.src('less/*/*/_main.less')
.pipe(less())
.pipe(gulp.dest('css'));
But this will create a directory structure like this:
css/
core/
_main.css
contact/
_main.css
But that's not what I want. I was thinking to use a regex to match the directory name, get this back in a matches var, and rename the file accordingly. Something like this:
gulp.src(/less\/[^\/]+\/([^\/]+)\/_main.less/)
.pipe(less())
.pipe(rename(function(context) {
context.src.matches[1] + '.css'
}))
.pipe(gulp.dest('css'));
This code is just an example. I can't figure out how to do something like this, or if it's even possible.
Is this possible? If so, how?

You look like you already have this, but maybe didn't see the gulp-rename plugin?
I don't even think you'll need to use a RegExp, something like this should work:
var rename = require('gulp-rename'),
path = require('path'); // node Path
//...
gulp.src('less/**/_main.less')
.pipe(less())
.pipe(rename(function(filepath) {
// replace file name to that of the parent directory
filepath.basename = path.basename(filepath.dirname);
// remove parent directory from relative path
filepath.dirname = path.dirname(filepath.dirname);
// leave extension as-is
}))
.pipe(gulp.dest('css'));

Related

How to exlude target directory in Gulp task

My file structure looks like this
app
src
target
file.txt
anotherfile.txt
I have the following Gulp task and I want to keep everything from the src directory and root level files and exclude the entire target directory:
return gulp.src([pathToSourceCode + '/**/*', '!' + pathToSourceCode + '/target/**}'])
... Some other tasks ...
// Output to /dist directory
.pipe(gulp.dest('./dist'));
I'm able to grab everything in src and file parallel to src, but I'm not able to exclude the target directory using this method. Why doesn't this work? The target directory and all its contents appear in the /dist output.
this should work perfectly
return gulp.src(['app/**/*', '!app/target/**/*'])
also there is a "}" in your gulp.src , it might be causing the problem
return gulp.src([pathToSourceCode + '/**/*', '!' + pathToSourceCode + '/target/**}'])

Gulp src ignore part of glob path for recursive copy

I would like to copy some openui5 resource files into my output folder from bower packages. They have all a common prefix (openui5-). They all have a subfolder called "resources". I would like to copy that content from that subfolder to one common "resources" folder in my output.
I would like to use a glob to copy them with gulp. For now I have to explicitly give each path
['bower_components/openui5-sap.m/resources/**/*',
'bower_components/openui5-sap.ui.core/resources/**/*',
'bower_components/openui5-themelib_sap_belize/resources/**/*']
I would like to use a pattern like this:
'bower_components/openui5-*/resources/**/*'
But if I do this, I get the full module name copied, too, so my resource folder looks like this:
out/resources/
+ -- openui5-sap.m/resources/...
+ -- openui5-sap.ui.core/resources/...
+ -- openui5-themelib_sap_belize/resources/...
As I came to understand this is because per default gulp.src takes the first glob (which is in the module name) and makes the recursive structure from there.
Is there a way to ignore parts of the glob pattern for the output or trim the output paths using another glob?
I played around and searched for any solutions, but I cannot find anything.
gulp-rename seems to flatten the whole hierarchy:
gulp.task('copyui5resources', function() {
gulp.src('bower_components/openui5-*/**/*')
.pipe(rename({ dirname: '' }))
.pipe(gulp.dest('out/resources'));
});
And using the base option does not help either. It seems to copy just a part of it:
gulp.task('copyui5resources', function() {
gulp.src('bower_components/openui5-*/**/*', {base: 'bower_components/openui5-*'})
.pipe(gulp.dest('out/resources'));
});
Here is a screenshot with my input folder structure and my gulp task so far. Thank you for your help!
You're on the right track trying to use gulp-rename. However the dirname option isn't powerful enough for what you're trying to accomplish, since it can only replace the entire directory structure. You want to replace just a part of it.
For cases like these gulp-rename can be supplied with a function, which allows you to alter dirname using everything JavaScript has to offer including string.replace().
That means you can do this:
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('default', function() {
return gulp.src('bower_components/openui5-*/resources/**/*')
.pipe(rename(f => f.dirname = f.dirname.replace(/openui5-.*?\//, '')))
.pipe(gulp.dest('out/'));
});
Thank you for your help Sven,
I just stumbled on that hint this morning in another post before I read your post :( I removed the first two parts of the path and got the desired result. It has the advantage, that you can skip as many parts you want and the regex solution has the advantage catching even more similar path parts.
For completion: Here is the solution I came up with:
var gulp = require('gulp'),
rename = require('gulp-rename'),
path = require('path');
gulp.task('copyui5resources', function() {
gulp.src('bower_components/openui5-*/resources/**/*')
.pipe(rename(function(p) {
var nda = p.dirname.split(/[\\\/]/);
nda.splice(0, 2);
p.dirname = nda.length > 0 ? path.join.apply(null, nda) : "";
}))
.pipe(gulp.dest('out/resources'));
});
I used path to rejoin the paths indipendent from the OS. Splice removes the first two parts with the package name and the resources directory. You have to use path.join.apply, as it flattens the array, otherwise you get an error.

Gulp, css is saving to dist/css/less, should be dist/css

trying to setup my gulp file for a project, I want to compile the less, and then minify it and have it save this to a new folder.
My less file is saved in app/less/styles.less, the compiled css file should save to dist/css/styles.css but it's saving to dist/css/less/styles.css.
What am I doing wrong here?
var app = 'app/',
dist = 'dist/',
appStyles = app + '**/*.less';
gulp.task('compilecssremote', function(){
return gulp.src(appStyles)
.pipe(plumber({
errorHandler: onError
}))
.pipe(changed(dist)) //must be dist
.pipe(urladjuster({
prepend: '/' + project + '/dist/' //based on location of CSS files
}))
.pipe(less())
.pipe(minifycss({keepBreaks: false}))
.pipe(gulp.dest(dist + 'css'))
});
This is the expected behavior when you use a gulp.src like 'app/**/*.less (aka your appStyles) to match source files with paths like app/less/styles.less. There are two pieces to understand here:
By default everything before the first glob in your gulp.src path will be omitted from the output path. In this case that's everything before the **, which is to say the app/. That's why the your output css file isn't going to 'dest/app/…. (For a more detailed discussion of this, see this answer)
The path matched by the first glob and on is preserved in the output path. In this case, that's the less/ in the matched file 'app/less/styles.less' (that is, the part of 'app/**/*.less' represented by **). (It's beside the point in the case of your problem, but this feature is very useful for preserving relative file structures.)
Using #1 & #2, one quick fix would be to trim less/ from the output path by putting it before the first glob in the gulp.src. For example, change appStyles = app + 'less/**/*.less'.

Gulp: Include folder tree, except one folder

I want gulp.src to include all file and folders in src directory, except for src/devpackages directory, so that the src/devpackages directory is not copied with gulp.dest. How can I do that? I tried with gulp.src(['src/**/*', '!src/devpackages/**']), but the gulp.dest creates the src/devpackages, but leaves it empty.
gulp.src([
baseDir + '/**', // Include all
'!' + baseDir + '/src/devpackages{,/**}', // Exclude devpackages
], { dot: true });
See the discussion here : [excluding folders from globs][1]. You can do it by
this:
gulp.src(['src/**/*', '!src/devpackages{,/**}'])
That is shorthand for exclude the folder and exclude the files it contains, you need to do both.
[EDIT] Oops, sorry - I missed that the previous answer had this idea already (although a little over-complicated).
1]: https://github.com/gulpjs/gulp/issues/165

Using widcards in gulp base path

Is it possible to use wildcards in the gulp.src() base path. For instance:
gulp.src('./src/**/*.dll'. {base:'./src/**/bin/'})
Say I have these two files:
/src/someMiddleFolder/bin/my.dll
/src/someMiddleFolder/bin/someBinFolder/second.dll
The result I'm after is (with the dist folder set to /dist/bin)
/dist/bin/my.dll
/dist/bin/someBinFolder/second.dll
Can I achieve this with base option?