How to exlude target directory in Gulp task - gulp

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/**}'])

Related

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

Rename file based on regex in 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'));

build haml to html with sublime

I want to build the haml in the sublime text 2 without switch to the iterm. So I build a simple plugin for the sublime, just like this.
import os
import sublime, sublime_plugin
class HamlToHtmlCommand(sublime_plugin.TextCommand):
def run(self,edit):
source = self.view.file_name()
filefullname = source.split('/')[-1]
filename = filefullname.split('.')[0]
target = "/".join(source.split('/')[0:-1])
com = "haml " + source + " > " + target + "/" + filename +'.html'
os.system(com)
def is_enabled(self):
return True
But the problem is that, when i build in the sublime, the target html file is empty.
for example, the "com" is "haml /Users/latpaw/login_register/login.haml /Users/latpaw/login_register/login.html". But if do the os.system(com) in the python cli, it is right.
So what really happens here
By the way, I really don't know Haml, so at first I just tried to fix your code. But I think you can build Haml directly from ST, by going to Tools→Build (⌥B). Or create a new build system Tools→Build Systems→New build system. Apparently you have the following variables that you could use:
$file The full path to the current file, e. g., C:\Files\Chapter1.txt.
$file_path The directory of the current file, e. g., C:\Files.
$file_name The name portion of the current file, e. g., Chapter1.txt.
$file_extension The extension portion of the current file, e. g., txt.
$file_base_name The name only portion of the current file, e. g., Document.
$packages The full path to the Packages folder.
$project The full path to the current project file.
$project_path The directory of the current project file.
$project_name The name portion of the current project file.
$project_extension The extension portion of the current project file.
$project_base_name The name only portion of the current project file.
Apparently you have an issue with path escaping. You must have, like me when I tried, a space somewhere in the path of your file. Or you probably know that commands like cat ~/Sublime Text/test do not work well. You can either:
cat ~/Sublime\ Text/test
cat ~/'Sublime Text/test'
I would advise the later and do this:
com = "haml '" + source + "' > '" + target + "/" + filename +"'.html"
PS: arguably, a better solution would be to add these single quotes directly when defining source, target and filename.