Gulp - Handle read-only permissions for dest files? - javascript

I have image files with read-only attribute set in source folder. I need to copy them to destination folder in most cases several times in gulpfile.js.
I am trying to copy src-to-dest files like this:
gulp.task('copy-images', function () {
gulp.src(path_resource_images + '**/*.jpg')
.pipe(gulp.dest(path_app_images));
});
It works once when the dest folder in empty. But for all next calls I've got an exception that file is read-only in dest folder. How can I remove file attr read-only to make image-copy works every time I call it?

You can use gulp-chmod to handle permissions on your files.
So if you want to set your images readable and writable for everybody, you could go with something like:
var chmod = require('gulp-chmod');
gulp.task('copy-images', function() {
gulp.src(path_resource_images + '**/*.jpg')
.pipe(chmod(666))
.pipe(gulp.dest(path_app_images));
});

By passing options attribute. Set mode value to specify permission for any folders that need to be created as output.
gulp.dest("destination-path-here", {"mode": "0777"})
cheers :-)

rimraf can be used to avoid issues with TFS permissions (by deleting destination files before copying files)
var rimraf = require("rimraf");
gulp.task("images_clean", function (cb) {
rimraf(imagesDest, cb);
});

Related

How to get access to directory/subdirectories/subdirectories?

I have a function that can observe files in directory and subdirectories, but it can't get access to files in the level 3 of subdirectories .
I just need to observe some file changes and modify them so I need to touch all file in the directory recursively
Example: get access to home and home/directories, but can't touch home/sub (sub)directories. How to make that possible?
I want to see all files in the folder
The code I have is:
co(function* () {
let close = yield awatch("./*", (event, filename) => {
//Observing any single changement in file of ext ".html" in local directory
if (cropping_extension(filename) == ".html") {
/**
* Reading the contain of a file and keep it inside a string
*/
console.log(cropping_path(filename));
To have access to all the files in the folder you just need to change ./* to => ./**/*
So in your code you just need to change this part :
let close = yield awatch(" ./**/* ", (event, filename)
How are you hosting the directories? For example, if you're using Express (NodeJS) you'd want to elect a static directory to host all of your assets.

how to remove templateCache with gulp?

i use angular-template-cache.
follow code exist for remove template cache in app module but i need to remove all templateCache with gulp on dev machine.
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
The best way to avoid template caching is revisioning your files.
Since you are using gulp, you can revision your files using gulp-rev or gulp-rev-all.
What is revisioning?
Static asset revisioning by appending content hash to filenames unicorn.css → unicorn-d41d8cd98f.css.
i.e., On every builds the filename changes and that way avoiding template caching.
You can revision every file including .html, .css, .js, images, videos etc.
Since gulp-rev-all is the latest and forked from gulp-rev, let's talk about gulp-rev-all only.
Revisioning using gulp-rev-all:
var revAll = require('gulp-rev-all');
if you want to neglect some files from revisioning, you can do that like this.
var rev = new revAll({dontRenameFile: [/^\/favicon.ico$/g, /^\/index.html/g]})
Consider all your files are in the folder dist and save the new revisioned files in the folder www.(You can save them in dist also. Considering www is your build directory.)
return gulp.src('dist/**')
.pipe(rev.revision())
.pipe(gulp.dest('www'))
Next, create a manifest file to map your files with the revisioned one. for that use .manifestFile() function. which returns a transform function that will filter out any existing files going through the pipe and will emit a new manifest file. Must be called after .revision().
.pipe(rev.manifest())
.pipe(gulp.dest('www/manifest'));
An asset manifest, mapping the original paths to the revisioned paths, will be written to www/manifest/rev-manifest.json:
{
"css/unicorn.css": "css/unicorn.098f6bcd.css",
"js/unicorn.js": "js/unicorn.273c2cin.js"
.....
.....
}
Complete code:
gulp.task('rev', () => {
var revAll = require('gulp-rev-all'),
rev = new revAll({dontRenameFile: [/^\/favicon.ico$/g, /^\/index.html/g]});
return gulp.src('dist/**')
.pipe(rev.revision())
.pipe(gulp.dest('www'))
.pipe(rev.manifest())
.pipe(gulp.dest('www/manifest'));
});
Read more about gulp-rev-all here

How to rename the original files of scripts in index.html using gulp?

I've written a gulp task to rename files so that they can be versioned. The problem is that the filenames of the files that the index.html scripts reference are not changed.
For example, in my index.html:
<script src=pub/main_v1.js"></script>
But if you actually navigate through the build folder to the subdirectory pub, you will find main.js.
Here is the custom gulp task:
const gulpConcat = require('gulp-concat');
const gulpReplace = require('gulp-replace');
const version = require('./package.json').version;
gulp.task('version', function () {
var vsn = '_' + version + '.js';
gulp.src('scripts/**/*.js')
.pipe(gulpConcat(vsn))
.pipe(gulp.dest('./prodBuild'));
return gulp.src('./prodBuild/index.html', { base: './prodBuild' })
.pipe(gulpReplace(/* some regex */, /* append vsn */))
.pipe(gulp.dest('./prodBuild'));
});
What do I need to fix/add so that the original filename changes to match that in the script tag?
Note: According to the gulp-concat docs, I should be able to find the concated files at prodBuild/[vsn], where [vsn] is _v1.js. However, it is no where to be found.
Update: The files rename properly in index.html, but I can't seem to get the renaming of the original files to work. Here's a snapshot of my build directory:
prodBuild/
pub/
main.js
someDir/
subDirA/
// unimportant stuff
subDirB/
file2.js
file3.js
// ...other files and folders...
EDIT:
The issue is that you return only one of the two tasks. The first task is simply ignored by gulp, since it is not returned. A simple solutions: Split it into two tasks, and reference the one from the other, like in this SO answer.
Old Answer
This looks like a perfect case for the gulp-rename. You could simply pipe your scripts through gulp-rename, like this:
.pipe(rename(function (path) {
path.basename += vsn;
path.extname = ".js"
}))
Gulp concat is, AFAIK, made for the concatination of files, not particularly for the renaming of them.

Gulp copy list of folders with contents

I would like to copy a list of folders to a destination with gulp
So far i've come up with a working solution, but its far from performant.
The structure of my directory is like this:
App
src
web
some files...
and i would like to copy it to
build
src
web
the files
The code i am using to accomplish this is:
var paths = [path.app + '/src/', path.app + '/app/'].concat(path.assets);
paths.forEach(function(value, index){
// value.replace(path.app, path.build);
gulp.src(value + '/**/*')
.pipe(gulp.dest(value.replace(path.app, path.build)));
});
Where the assets are my files (or other directories)
However there is a loop and no clear return value. I am wondering if there is a more performant way of doing this
I'm not sure I understand what you're trying to do here (where is your gulp task definition for example?), but it seems like you just want to copy everything below App to the build folder while preserving directory structure.
If that's the case, you don't have to loop over the files and replace folder names yourself. Gulp does it for you:
gulp.task('default', function () {
return gulp.src('App/**')
.pipe( gulp.dest('build') );
});
Everything before the ** is automatically stripped from the path of files written to build, so you end up with build/src, build/web, etc ...

grunt-init: How can I copy or create an empty directory?

I want copy an empty directory from my root folder into the new initialized project. I want do this, to provide an initial directory structure for new projects.
I have such empty directories in the folder 'my-template/root/' but that will not be copied by:
// Files to copy (and process).
var files = init.filesToCopy(props);
// Actually copy (and process) files.
init.copyAndProcess(files, props);
I tried this:
// to copy also the empty directories
init.copy('myDir1/');
init.copy('myDir2/');
But than grunt-init crashes with:
Error: Unable to read "grunt-init-example/root/myDir1/" file (Error code: EISDIR).
What have I to do, to get an empty directory to the destination folder?
I use grunt#0.4.0 and grunt-init#0.2.0.
Inspired by the answer of Nick Mitchinson, I use this workaround:
// module dependencies
var join = require("path").join;
// empty directories will not be copied, so we need to create them manual
grunt.file.mkdir( join(init.destpath(), 'myDir1') );
grunt.file.mkdir( join(init.destpath(), 'myDir2') );
Update:
Alternative solution is to add .gitkeep files to the empty directories. Than the directories are no more empty and will be listed with filesToCopy().
For more details about .gitkeep look here: https://stackoverflow.com/a/7229996/496587
Try taking a look this this article
The part relevant to creating a directory is:
var root = path.normalize(__dirname+"/relative/path/you/want");
grunt.file.mkdir(root);
however, reading the whole this would probably be good.
I create an empty __empty_file.txt file inside the empty folders which I want to get copied.
Inside my template.js file I do the following:
Store files which matches with our (__empty_file.txt) by iterating over files object returned by init.filesToCopy(props) to an array.
Create directories using grunt.file.mkdir for each item in the above array and remove this file from files reference which was returned by init.filesToCopy. This has to be called before the call to init.copyAndProcess.

Categories