I am trying to create a gulp task responsible to :
1. clean dist folder previouly created
2. Copy some folder inside new dist folder
3. Edit a ini file inside dist folder to update a key
var destination = './dist/test/v2';
// Copy ini file to dist folder
gulp.task('prepareDelivery', function () {
gulp.src([source + '/ini/app_sample.ini']).pipe(gulp.dest(destination + '/ini/'));
});
// update version in ini file
gulp.task('prepareAppIni', ['prepareDelivery'], function () {
var config = ini.parse(fs.readFileSync(destination + '/ini/app_sample.ini', 'utf-8'))
config.DATA.version = '1.0'
fs.writeFileSync(destination + '/ini/app.ini', ini.stringify(config, { section: 'section' }))
});
// default task
gulp.task('default', ['clean', 'prepareDelivery', 'prepareAppIni']);
I get this error :
Error: ENOENT: no such file or directory, open './dist/test/v2/ini/app_sample.ini'
I don't understand why, because i am waiting that prepareDelivery task is terminated before executing prepareAppIni task...
Could you help me ?
I don't understand why, because i am waiting that prepareDelivery task is terminated before
That's not correct.
Your default task has multiple dependencies (clean, prepareDelivery, prepareAppIni), and all of them start at the same time.
Most likely you want want prepareAppIni to depend on prepareDelivery. Which, in turn, should depend on clean task. Having this implemented, default should depend only on prepareAppIni:
gulp.task('default', ['prepareAppIni']);
Also, you are missing return in prepareDelivery, so gulp doesn't know when it finishes. Should be
// Copy ini file to dist folder
gulp.task('prepareDelivery', function () {
return gulp.src([source + '/ini/app_sample.ini']).pipe(gulp.dest(destination + '/ini/'));
});
Related
I am currently trying to come up with a gulp task that will build the entire .csproj file associated with a particular .less file whenever that .less file changes.
I already have a working task that will do just that, however the restriction I am facing is that the .less file must be in a specific place relative to the .csproj file. If the .less file is one level deeper/higher in the directory, the method I am using to build the .csproj file wont be able to find the correct .csproj file to build.
My current task is based heavily off of one of the tasks found in Kamsar's Habitat repo for Sitecore: https://github.com/kamsar/Habitat
It is as follows:
gulp.task("Auto-Publish-Less",
function() {
var root = "./src";
var roots = [root + "/**/resources/styles", "!" + root + "/**/obj/**/resources/styles"];
var files = "/**/*.less";
gulp.src(roots, { base: root })
.pipe(
foreach(function (stream, rootFolder) {
console.log(rootFolder);
gulp.watch(rootFolder.path + files,
function(event) {
if (event.type === "changed") {
var dest = config.websiteRoot;
console.log("Build project associated with this file: " + event.path);
return gulp.src([event.path + "/../../../*.csproj"]).pipe(publishStream(stream,dest));
}
});
return stream;
}));
});
This works great so long as the .csproj file is 3 levels higher than the .less file. I could also add more wildcards for 2 levels higher, 1 level higher, etc. However, I was looking to see if there was a way in gulp.src to "find" the first matching file, moving up the directory structure, and then stopping once the first match is found. Is there a way to do this in gulp and/or plain-old js?
Check out this package:
Finds the first parent directory that contains a given file or directory:
https://www.npmjs.com/package/find-parent-dir
First of all, I would like to say that Gulp (for me) is creating more problems instead of solving them.
I wrote a gulpfile that concat some CSS files and put them inside a directory. The code for this task is the following:
var config = {
mainDir: 'app/assets'
};
config.stylesFiles = [
'bower_resources/admin-lte/dist/css/AdminLTE.min.css',
'bower_resources/admin-lte/dist/css/skins/_all-skins.min.css',
'css/app.css'
];
....
gulp.task('styles', function() {
return gulp
.src(config.stylesFiles, { cwd: config.mainDir })
.pipe(sourcemaps.init())
.pipe(concat('theme.css'))
.pipe(sourcemaps.write('../build/css'))
.pipe(gulp.dest('public/css/'))
.on('end', function() { gutil.log('Styles copied') });
});
It is very simple and works perfectly.
But, I would like to version this generated file. So I wrote a specific task to do it:
....
config.manifestFolder = process.cwd() + '/public/build';
gulp.task('versionCSS', function() {
return gulp
.src(['css/theme.css'], { cwd: 'public' })
.pipe(rev())
.pipe(gulp.dest('public/build/css'))
.pipe(rev.manifest(
{
base: config.manifestFolder,
cwd: config.manifestFolder,
merge: true
}
))
.pipe(gulp.dest(config.manifestFolder))
.on('end', function() { gutil.log('CSS files versioned') });
});
The problem is: when Gulp is going to run this task, it creates a folder inside the destination folder.
After running Gulp, I get this structure:
- public
- build
- css (destination folder for the versioned file)
- css (folder created by Gulp)
- versioned file that should be in the parent folder
- css
- concatenated file without version
I really don't know what to do anymore. I've already set the cwd and base options for the dest and src functions, changed the destinations, synchronized the tasks, etc. Nothing solves this stupid behavior.
I'm currently trying to develop a module that will allow node to run Grunt tasks from the command line. This Node module is installed globally :
C:\Users\pcharpin\AppData\Roaming\npm\node_modules\task-app
The goal is that the use of "Grunt" commands is transparent to the user. To better explain my approach, a simple example of the use of my node module:
C:\Users\pcharpin\Desktop\demo-app> task-app copy
In this example, my module will copy a source directory to a destination directory.
Unfortunately, when I run the task Grunt, my node module indicates to me that there is no file "Gruntfile.js" within the directory "demo-app". However, this file should be found by my Node module within its own directory.
My tree Node module:
Task app
node_modules
grunt
src
task-app.js
Gruntfile.js
package.json
README.md
...
My task-app.js file, here's the code:
#!/Usr/bin/env node
var grunt = require('grunt');
var args = process.argv.splice(2)
checkArguments(args);
checkArguments function(args) {
[...]
runCopy();
}
runCopy = function() {
var spawn = require('child_process') spawn.
var exec = spawn('cmd', ['/ c', 'grunt copy']);
exec.stdout.on("data", function (data) {
console.log('' + data);
});
exec.stderr.on('data', function (data) {
console.log('' + data);
});
}
Then in my "Gruntfile.js" file, I have the code to perform the copy of the source to the destination directory:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
copy {
srcWeb {
files: [{
cwd: '<%= pkg.srcWeb%>', //root to copy
src: '**/*', // copy all files and subfolders
dest: '<%= pkg.name%>/www/', // destination folder
expand: true // When required using cwd
}]
}
}
});
I don't understand why the Node module is not found in the "Gruntfile.js" file.
Is it required to have a file "Gruntfile.js" in this project directory? Is there another solution?
I would like to know too, is it possible that the file "Gruntfile.js" can read the file "package.json" in the project directory? This is to allow the user to configure this file to change the source path for example.
EDIT :
After some researches, I'm getting closer to the solution to my problem. To change the execution of "Gruntfile.js" which is the current directory by default, we can use --gruntfile option in command line.
As indicated in the source code grunt (grunt/lib/grunt/tasks.js) :
//Get any local Gruntfile or tasks that might exist. Use --gruntfile override
//if specified, otherwise search the current directory or any parent.
How can I specify the path of "Gruntfile.js" (found in my node module installed globally) for any Windows user ?
Here's an example :
C:\Users\username\projects\demo-app> task-app copy
In my source code, I execute the grunt task like this with --gruntfile option :
runCopy = function() {
var spawn = require('child_process').spawn;
var pathGruntfile = 'C:\Users\username\AppData\Roaming\npm\node_module\task-app';
var exec = spawn('cmd', ['/ c', 'grunt --gruntfile' + pathGruntfile + ' Gruntfile.js']);
exec.stdout.on("data", function (data) {
console.log('' + data);
});
exec.stderr.on('data', function (data) {
console.log('' + data);
});
}
EDIT 2 :
Pending a response, I found a temporary solution to get the "Gruntfiles.js" inside my Node module. But the disadvantage is to install all Node modules dependancies and my Node Module locally in the current directory.
var pathDirCurrent = process.cwd();
var pathGruntfile = pathDirCurrent.concat('\\node_modules\\task-app\\Gruntfile.js');
var spawn = require('child_process').spawn;
var exec = spawn('cmd', ['/c', 'grunt --gruntfile ' + pathGruntfile + ' create']);
exec.stdout.on("data", function(data) {
console.log('' + data);
});
Where are you running grunt from?
Your projects structure and grunt file looks OK. Maybe try and include a base task:
grunt.registerTask('default', ['copy']);
Finally, I understand the logic of using Grunt tasks. When you have a web project application which need to use tasks grunt, it must have the Gruntfile.js in current directory.
However, like as I said from my "edit 2", we can specified the Gruntfile.js with ---gruntfile option. So, it's not a disadvantage cause Grunt tool works with the Gruntfile.js in current directory where there is your web project application.
For each task grunt, I use the --gruntfile option to specify the path of Gruntfile.js as my example from "edit 2".
I'm extremely new to Gulp. I'm basically trying to watch for a modified JavaScript file, and then make a new copy of it with a new name. (eventually there'll be some processing on it, but Rome wasn't built in a day).
My (naive) attempt is this:
gulp.task('default', function() {
return gulp.watch('../**/**.js', function(obj){
gulp.src(obj.path)
.pipe(gulp.dest('foobar.js'));
});
});
This takes the modified file and successfully copies it into a folder now called foobar.js. Is there anything simple I can replace gulp.dest('foobar.js') with that will simply copy and rename the src file in place?
EDIT
By copy in place, I mean I want to take the modified file, and make a copy of it right where it currently is with a new name. The equivalent of clicking the file (in windows) and hitting control-c control-v, then renaming the resulting file.
I'm not 100% certain what you mean by
copy and rename ... in place
But, based on your current code, if you simply wish to:
Watch all .js files in the parent directory and
Copy them to the cwd (current working directory) and
Name all copies, regardless of source file, the same thing
Then you could use gulp-rename to do just that:
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('default', function() {
return gulp.watch('../**/**.js', function(obj) {
gulp.src(obj.path)
.pipe(rename('newFileName.js'))
.pipe(gulp.dest('.'));
});
});
In this case, the output filename is newFileName.js
In order to use the module, you'll need to install the gulp-rename package with npm (ie: npm install gulp-rename).
More examples are available on the package details page on npm # https://www.npmjs.com/package/gulp-rename#usage
It wasn't pretty getting there, but in the end it appears this is what I want (with some ES6 transpiling in the middle).
The key appears to be the options object with a base property in the call to src. That seems to be what's needed to maintain the path of the current file in the call to dest.
var gulp = require('gulp'),
rename = require('gulp-rename'),
babel = require('gulp-babel');
gulp.task('default', function() {
return gulp.watch('../**/$**.js', function(obj){
if (obj.type === 'changed') {
gulp.src(obj.path, { base: './' })
.pipe(babel())
.pipe(rename(function (path) {
path.basename = path.basename.replace('$', '');
}))
.pipe(gulp.dest(''));
}
});
});
20 lines of code to do 'cp file1 file2'
That's elegance.
I have a small application in express.js and i want to run a Grunt task, named "build", at the client request for now but i don't know how to pass sub-task configuration to Grunt module.
executeTask : function (components) {
// Other stuff
this.grunt = require("grunt");
components = components.join();
var file = require(this.parentDir + "/myProjectFolder/Gruntfile.js")(this.grunt);
this.grunt.option('target', components);
var result = this.grunt.task.run(["build"]);
console.log(result);
// Other stuff
},
This code not spawn any error but not working, the output file is no generated.
This sub-task are executed correctly from CLI, and refer to the same Gruntfile.js