Grunt bump package.json version - gruntjs

I would like to add 'release' task:
grunt.initConfig({
...
shell: {
release: {
command: function(version) {
return 'git checkout -b release-' + version + ' devel';
}
}
}
...
grunt.loadNpmTasks('grunt-bumpup');
grunt.loadNpmTasks('grunt-shell');
...
grunt.registerTask('release', function() {
grunt.task.run('bumpup');
var version = grunt.config.get('pkg').version;
grunt.task.run('shell:release:' + version);
});
But I have the following:
Running "release" task
Running "bumpup" task
Bumped to: 1.2.5
Running "shell:release:1.2.4" (shell) task
Switched to a new branch 'release-1.2.4'
M Gruntfile.js
M package.json
M src/manifest.json
Done, without errors.
So the version was bumped up, but branch was created for previous version.
I think it is because package.json cached. Can I reread it?
var version = grunt.file.readJSON('package.json').version; // old version too
EDIT:
Adding 'updateProps' to bumpup config will change pkg version property, but:
grunt.registerTask('release', function() {
grunt.task.run('bumpup');
var version = grunt.config.get('pkg').version;
grunt.log.writeln(version); // old version, because tasks run async?
grunt.task.run('shell:release:' + version);
});
Works good:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
...
bumpup: {
options: {
updateProps: {
pkg: 'package.json'
}
},
files: ['package.json', 'src/manifest.json']
},
shell: {
release: {
command: function() {
return 'git checkout -b release-' + grunt.config.get('pkg').version + ' devel';
}
}
},
...
grunt.loadNpmTasks('grunt-bumpup');
grunt.loadNpmTasks('grunt-shell');
...
grunt.registerTask('release', ['lint', 'bumpup', 'shell:release']);

Are you sure to have set the updateProps option of the grunt-bumpup plugin? This will allow you to specify files to update with the new bumped version after your bumpup task is completed
grunt.initConfig({
...
bumpup: {
options: {
updateProps: {
pkg: 'package.json'
}
},
file: 'package.json'
}
...
});

Related

SyntaxError: Unexpected token { in Gruntfile.js

I don't manage to configure grunt. I have followed all the steps from Magento2 but I receive this syntax error.
grunt
Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: Unexpected token {
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
I have reinstalled both the grunt and the node.js, but it doesn't work.
Has anybody had the same problem?
Below you can see the Gruntfile.js ( that is original) posted.
Is it an error of this file or is there another problem?
Gruntfile.js
module.exports = function (grunt) {
'use strict';
var _ = require('underscore'),
path = require('path'),
filesRouter = require('./dev/tools/grunt/tools/files-router'),
configDir = './dev/tools/grunt/configs',
tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'),
themes;
filesRouter.set('themes', 'dev/tools/grunt/configs/themes');
themes = filesRouter.get('themes');
tasks = _.map(tasks, function(task){ return task.replace('.js', '') });
tasks.push('time-grunt');
tasks.forEach(function (task) {
require(task)(grunt);
});
require('load-grunt-config')(grunt, {
configPath: path.join(__dirname, configDir),
init: true,
jitGrunt: {
staticMappings: {
usebanner: 'grunt-banner'
}
}
});
_.each({
/**
* Assembling tasks.
* ToDo: define default tasks.
*/
default: function () {
grunt.log.subhead('I\'m default task and at the moment I\'m empty, sorry :/');
},
/**
* Production preparation task.
*/
prod: function (component) {
var tasks = [
'less',
'autoprefixer',
'cssmin',
'usebanner'
].map(function(task){
return task + ':' + component;
});
if (typeof component === 'undefined') {
grunt.log.subhead('Tip: Please make sure that u specify prod subtask. By default prod task do nothing');
} else {
grunt.task.run(tasks);
}
},
/**
* Refresh themes.
*/
refresh: function () {
var tasks = [
'clean',
'exec:all'
];
_.each(themes, function(theme, name) {
tasks.push('less:' + name);
});
grunt.task.run(tasks);
},
/**
* Documentation
*/
documentation: [
'replace:documentation',
'less:documentation',
'styledocco:documentation',
'usebanner:documentationCss',
'usebanner:documentationLess',
'usebanner:documentationHtml',
'clean:var',
'clean:pub'
],
'legacy-build': [
'mage-minify:legacy'
],
spec: function (theme) {
var runner = require('./dev/tests/js/jasmine/spec_runner');
runner.init(grunt, { theme: theme });
grunt.task.run(runner.getTasks());
}
}, function (task, name) {
grunt.registerTask(name, task);
});
};
Thanks in advance!
I was getting the same error.
I installed node using the following commands and error resolved.
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt install nodejs
node -v
npm -v
Hope this helps!

Is there a way to specify variable in grunt task name?

Is there a way to specify variable in grunt task name?
I would like to do something like
grunt build version 0.1
and then in gruntfile.js
grunt.initConfig({
version: // read that version
files: {
'<%= version %>.js'
Try this:
YourTask: {
dist: {
files: { 'dist.<%= version %>.js', ........
}
},
Register your build task like this:
grunt.task.registerTask('build', 'build a specific version',
function(version) {
if (arguments.length === 0) {
grunt.log.writeln(this.name + ", missing version");
} else {
grunt.log.writeln(this.name + " version " + version);
grunt.config.set('version', version);
grunt.task.run([
'YourTask:dist'
]);
}
});
You would then call: grunt build:0.1
I can hardly understand why do you need to use different names in grunt-tasks. But the thing you are talking about seems like arguments usage. Try these code:
grunt.registerTask('custom', 'Build version', function () {
grunt.config.set('ver', grunt.option('ver') || 0);
grunt.task.run('build');
});
And run it with --ver argument:
grunt custom --ver=0.1

registerMultiTask.js in grunt-horde

I'm trying to configure grunt-horde so that I can have multiple builds all using a centrally managed task configuration.
The documentation provides the following example of a registerMultiTasks.js file, but I can't get it to work
module.exports = function(grunt) {
var myMultiTask = require('./multi-tasks/secret-sauce.js');
return {
myMultiTask: ['some description', myMultiTask]
};
};
Even if I replace their example with something more simple:
module.exports = function(grunt) {
return {
demo: ['Demo', function() {
console.info('hello');
}]
};
};
When I run grunt demo:test the output is:
Running "demo:test" (demo) task
Verifying property demo.test exists in config...ERROR
>> Unable to process task.
Warning: Required config property "demo.test" missing. Use --force to continue.
Aborted due to warnings.
When I run grunt --help the demo task shows up in the list. Thinking about the warning message I've also tried the following, but again with no luck.
module.exports = function(grunt) {
return {
demo: ['Demo', function(){
return {test: function(){console.info('hello');}};
}]
};
};
...what am I doing wrong?
I figured it out - you need to define the configuration for each target of the multitasks:
initConfig/demo.js
module.exports = function() {
'use strict';
return {
test: {
foo: 'bar'
}
};
};
You can then access this configuration data and the target from within the multitask function:
registerMultiTask.js
module.exports = function(grunt) {
return {
demo: ['Demo', function() {
grunt.log.writeln('target: ' + this.target);
grunt.log.writeln('foo: ' + this.data.foo);
}]
};
};

Grunt-contrib-watch targets and recursion

I'm trying to figure out a way to break out a watch target from the rest of the block. Currently my watch target looks like this:
watch: {
options: {
// Parent-level options
},
coffee: {
// ...
},
stylus: {
// ...
},
test: {
options: {
// Test-specific options
},
files: {
// ...
}
tasks: {
// ...
}
}
}
The problem I'm facing is that my test options include a different livereload port than the top level, so I can simultaneously run grunt server and grunt test with livereloading and not have them interfere with each other.
Beneath that, I have a server alias and a test alias. What I'm looking for is to break the test watch target out into another task so I can simply run watch in my server alias and something like watch-test for testing, such that the server task doesn't run the test target.
Any ideas? Please let me know if I've left out anything important or this isn't clear.
Thanks!
A solution I've used is to define multiple watch targets and rename the watch task like so:
watch: {
scripts: {
files: ['js/**/*.js'],
tasks: ['concat', 'uglify'],
options: {
spawn: false
}
}
},
// Don't uglify in dev task
watchdev: {
scripts: {
files: ['js/**/*.js'],
tasks: ['concat'],
options: {
spawn: false
}
}
}
grunt.loadNpmTasks('grunt-contrib-watch');
// Rename watch to watchdev and load it again
grunt.renameTask('watch', 'watchdev');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['watch']);
grunt.registerTask('dev', ['watchdev']);
Since grunt watch is a multi task, running grunt watch from the CLI means that all targets are watched. You can instead run one target out of those by simply running grunt watch:test or grunt watch:server, whatever is your preference. Hope that helps.
Edit: It might be appropriate to point out this issue on the watch issue tracker:
https://github.com/gruntjs/grunt-contrib-watch/issues/206
The code in the issue is a little old, I would recommend newer code to require lodash and use _ instead of grunt.util._ (that utility is now deprecated). So the code would look like this:
var _ = require('lodash');
module.exports = function(grunt) {
// Run with: grunt switchwatch:target1:target2 to only watch those targets
grunt.registerTask('switchwatch', function() {
var targets = Array.prototype.slice.call(arguments, 0);
Object.keys(grunt.config('watch')).filter(function(target) {
return !(_.indexOf(targets, target) !== -1);
}).forEach(function(target) {
grunt.log.writeln('Ignoring ' + target + '...');
grunt.config(['watch', target], {files: []});
});
grunt.task.run('watch');
});
}
Still, you could modify your server task to run something like switchwatch:coffee:stylus:server:
grunt.registerTask('server', [/* rest of your tasks */, 'switchwatch:coffee:stylus:server']);

Conditionally running tasks in grunt if some files are changed

I'm new to Grunt, and from what I understood up till now, Grunt has the "watch" task, which continuously checks files for modifications, and each time modification happens, runs corresponding tasks.
What I'm looking for would be a kind of discrete version of this - a task, that would run other tasks, if and only if some files were changed since the last build.
Seems to be a natural thing to ask for, but I couldn't find this. Is it just me, or is this really an issue?
Configuration file should look like this:
grunt.initConfig({
foo: {
files: "foo/*"
// some task
},
bar: {
files: "bar/*"
// some other task
},
ifModified: {
foo: {
files: "foo/*",
tasks: ['foo']
},
bar: {
files: 'bar/*',
tasks: ['bar', 'foo']
}
}
});
grunt.registerTask('default', ['bar', 'foo']);
Running grunt should always execute tasks 'bar', 'foo', while running grunt ifModified should execute any tasks only if some of the files were actually changed since the previous build.
Made my own task for that. It turned out to be not hard, here is the code:
build/tasks/if-modified.js:
var fs = require('fs');
var crypto = require('crypto');
module.exports = function (grunt) {
grunt.registerMultiTask('if-modified', 'Conditionally running tasks if files are changed.', function () {
var options = this.options({});
grunt.verbose.writeflags(options, 'Options');
var hashes = {};
if (grunt.file.exists(options.hashFile)) {
try {
hashes = grunt.file.readJSON(options.hashFile);
}
catch (err) {
grunt.log.warn(err);
}
}
grunt.verbose.writeflags(hashes, 'Hashes');
var md5 = crypto.createHash('md5');
this.files.forEach(function (f) {
f.src.forEach(function (filepath) {
var stats = fs.statSync(filepath);
md5.update(JSON.stringify({
filepath: filepath,
isFile: stats.isFile(),
size: stats.size,
ctime: stats.ctime,
mtime: stats.mtime
}));
});
});
var hash = md5.digest('hex');
grunt.verbose.writeln('Hash: ' + hash);
if (hash != hashes[this.target]) {
grunt.log.writeln('Something changed, executing tasks: ' + JSON.stringify(options.tasks));
grunt.task.run(options.tasks);
hashes[this.target] = hash;
grunt.file.write(options.hashFile, JSON.stringify(hashes));
}
else
grunt.log.writeln('Nothing changed.');
});
};
Gruntfile.js:
grunt.initConfig({
foo: {
src: ["foo/**/*"],
dest: "foo-dest"
// some task
},
bar: {
src: ["bar/**/*", "foo-dest"]
// some other task
},
'if-modified': {
options: {
hashFile: 'build/hashes.json'
},
foo: {
src: ['foo/**/*', 'Gruntfile.js', 'package.json'],
options: {tasks: ['foo']}
},
bar: {
src: ['bar/**/*', "foo-dest", 'Gruntfile.js', 'package.json'],
options: {tasks: ['bar']}
}
}
});
grunt.loadTasks('build/tasks'); // if-modified.js in this dir
grunt.registerTask('default', ['foo', 'bar']);
run:
grunt if-modified
You could create a task that runs conditionally other tasks, from https://github.com/gruntjs/grunt/wiki/Creating-tasks :
grunt.registerTask('foo', 'My "foo" task.', function() {
// Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
grunt.task.run('bar', 'baz');
// Or:
grunt.task.run(['bar', 'baz']);
});
What you need might be grunt-newer :
The newer task will configure another task to run with src files that are a) newer than the dest files or b) newer than the last successful run (if there are no dest files). See below for examples and more detail.
https://github.com/tschaub/grunt-newer

Resources