Suggest deploy path in a Grunt task - gruntjs

I have a Grunt task to automatize the deploy of my webapp on webserver.
On My webserver I have 3 paths:
/www/myApp (production)
/www/myApp_rc
I have a package.json file
{
...
"ftpDeployPath":"myApp_rc" //or /www/myApp
...
}
and this is my task
{'ftp-deploy': {
toMyServer: {
auth: {
host: '10.7.88.87',
port: 21,
authKey: 'key1'
},
src: 'deploy',
dest: '<%= pkg.ftpDeployPath %>',
forceVerbose: true
}
}
}
When I want deploy, every time I have to check and eventually edit package.json file.
Is there any way to show a prompt (bu grunt console) to allow me to select the right deploy path?

You can probably try using grunt-prompt task with 'input' question type and your "ftpDeployPath" as 'config'. Or, modify your gruntfile to use command line options (http://gruntjs.com/frequently-asked-questions#dynamic-alias-tasks) and run your tasks as external tools from WebStorm (Settings | Tools | External tools) - you can add $Prompt$ macro to tool parameters to get a prompt for option value when running a tool

Using a combination of command line arguments and a custom task, you can modify configuration for tasks before you run them. Let's start first by modifying the template string for dist; change it to access a grunt.option() param called deployPath our custom task will set:
grunt.initConfig({
'ftp-deploy': {
toMyServer: {
auth: {
host: '10.7.88.87',
port: 21,
authKey: 'key1'
},
src: 'deploy',
dest: '<%= grunt.option('deployPath') %>',
forceVerbose: true
}
}
});
Next, craft a custom task that sets the grunt.option('deployPath') parameter. The task below will set deployPath to myApp when you run grunt deploy:prod. If you run just grunt deploy, the path is set to myApp_rc. Once the path is chosen, the custom then calls the ftp-deploy task:
function deployTask(grunt) {
var deployPath = (this.args[0] === 'prod') ? 'myApp' : 'myApp_rc';
grunt.option('deployPath', deployPath);
grunt.task.run('ftp-deploy');
}
grunt.registerTask('deploy', deployTask);

Related

Looking for Modernizr references

I'm trying to use the grunt-modernizr plugin in my project but I'm receiving the following output when I run tasks:
Running "modernizr:dist" (modernizr) task
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
I'm not receiving any type of error the terminal just goes back to the directory that I'm in, as if it's just giving up.
Here is my grunt file:
module.exports = function(grunt) {
grunt.initConfig ({
// Do grunt-related things in here
pkg: grunt.file.readJSON('package.json'),
modernizr: {
dist: {
"dest": "javascripts/modernizr-custom.js",
"parseFiles": true,
"customTests": [],
"devFile": "javascripts/modernizr-custom.js",
"outputFile": "javascripts/min/modernizr-custom.min.js",
"tests": [
"pointerevents",
"css/pointerevents"
],
"extensibility": [
"setClasses"
],
"uglify": false
}
},
cssmin: {
target: {
files: {
'css/min/bootstrap.min.css': ['css/bootstrap.css']
}
}
},
});
grunt.loadNpmTasks("grunt-modernizr");
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default',['modernizr', 'cssmin']);
};
Output from running grunt --verbose:
Initializing
Command-line options: --verbose
Reading "gruntfile.js" Gruntfile...OK
Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK
Registering "grunt-modernizr" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Loading "modernizr.js" tasks...OK
+ modernizr
Registering "grunt-contrib-cssmin" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Loading "cssmin.js" tasks...OK
+ cssmin
Loading "gruntfile.js" tasks...OK
+ default
No tasks specified, running default tasks.
Running tasks: default
Running "default" task
Running "modernizr" task
Running "modernizr:dist" (modernizr) task
Verifying property modernizr.dist exists in config...OK
Files: -> javascripts/modernizr-custom.js
Verifying property modernizr exists in config...OK
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
This is something I just came across too and seems to be grunt-modernizr stopping after customizr doesn't find any files to crawl (it crawls by default).
If you add "crawl": false to your modernizr:dist task that should fix the problem.
Also, I think "extensibility": [ "setClasses" ], should be "options": [ "setClasses" ],.
To use the grunt-modernizr task to crawl your code for Modernizr references you'll have to look at the config properties for the customizr task as this is part of grunt-modernizr 's node_modules:
modernizr: {
dist: {
dest: 'bower_components/modernizr/build/modernizr.custom.js',
uglify: false,
options: [
'setClasses',
'addTest'
],
files: {
src: ['js/app/**/*.js', 'js/app/*.js']
}
}
}
devFile: doesn't seem to matter where you point at
dest: instead of outputFile, note I'm just outputting to a build directory that's not part of the package
uglify: false if you have other minifying options like bundleconfig.json
options: to bypass the default options { "setClasses", "addTest", "html5printshiv", "testProp", "fnBind" }
files: to enlist your crawlable director(y|ies), make sure you take care of the root files and/or subdirectories as well
Load the required tasks, in my case:
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-modernizr');
grunt.loadNpmTasks('grunt-contrib-copy');
Refer to the 'modernizr:dist' task => grunt.registerTask('default', ['clean', 'modernizr:dist', 'copy']);
Which results in an unminified 34kb file:
Running "clean:files" (clean) task
19 paths cleaned.
Running "modernizr:dist" (modernizr) task
Looking for Modernizr references
1 match in js/app/classes/yambo.options.js
bgpositionxy
1 match in js/app/modules/yambo.audio.js
audio
Ready to build using these settings:
setClasses, addTest
Building your customized Modernizr...OK
Success! Saved file to bower_components/modernizr/build/modernizr.custom.js
Process terminated with code 0.
Running "copy:main" (copy) task
Copied 11 files
Done, without errors.
This way there's no need to even go to the online build to add a feature test. Simply reference Modernizr throughout your js code:
window.Yambo = (function($, modernizr, ns){
ns.Audio = {
extension: (function () {
return modernizr && modernizr.audio.mp3
? 'mp3'
: modernizr.audio.ogg
? 'ogg'
: 'wav';
}())
};
return ns;
}(window.jQuery, window.Modernizr, window.Yambo || {}));
Make sure to use the correct property name for a feature detection, so customizr can pick it up and provide a test to your custom build.
This should be also possible for css but haven't been testing that for the moment.
It looks like you missed source files.
http://gruntjs.com/configuring-tasks#files-object-format
Try to include
"dist": {
"files": {
"src": ['!<%= appDir %>assets/js/bower/modernizr/**']
}
}

grunt-contrib-jade compiling to single JS with cwd

I am trying to compile multiple jade templates into single JS file using grunt-contrib-jade. Problem I'm facing is that with full path to templates, I get function names with full path. I want to avoid that, so I tried using cwd (without expand). This ended up with the following:
>> Source file "test.jade" not found.
>> Source file "test2.jade" not found.
Is there any way I could achieve what I plan? My grunt config for that task is as following:
jade: {
js: {
options: {
client: true,
amd: true
},
files: [ {
cwd: 'js/views/',
src: ['*.jade'],
dest: 'js/tmp/templates.js'
} ]
}
},
Thanks in advice,
Dracco
Silly me, didn't fully read the documentation of the plugin :(.
The solution is trivial, using the processName option:
options: {
client: true,
amd: true,
processName: function(path) {
var pathChunks = path.split('.')[0].split('/');
return pathChunks[pathChunks.length - 1];
}
}

How to get grunt.file.readJSON() to wait until file is generated by another task

I'm working on setting up series of grunt tasks that work with RequireJS r.js compiler:
1) generates a .json file listing of all files in a directory
2) strips the ".js" from the filename (requirejs requires this)
3) use grunt.file.readJSON() to parse that file and use as a configuration option in my requirejs compilation task.
Here is the relevant code from my gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
// create automatic list of all js code modules for requirejs to build
fileslist: {
modules: {
dest: 'content/js/auto-modules.json',
includes: ['**/*.js', '!app.js', '!libs/*'],
base: 'content/js',
itemTemplate: '\t{' +
'\n\t\t"name": "<%= File %>",' +
'\n\t\t"exclude": ["main"]' +
'\n\t}',
itemSeparator: ',\n',
listTemplate: '[' +
'\n\t<%= items %>\n' +
'\n]'
}
},
// remove .js from filenames in module list
replace: {
nodotjs: {
src: ['content/js/auto-modules.json'],
overwrite: true,
replacements: [
{ from: ".js", to: "" }
]
}
},
// do the requirejs bundling & minification
requirejs: {
compile: {
options: {
appDir: 'content/js',
baseUrl: '.',
mainConfigFile: 'content/js/app.js',
dir: 'content/js-build',
modules: grunt.file.readJSON('content/js/auto-modules.json'),
paths: {
jquery: "empty:",
modernizr: "empty:"
},
generateSourceMaps: true,
optimize: "uglify2",
preserveLicenseComments: false,
//findNestedDependencies: true,
wrapShim: true
}
}
}
});
grunt.loadNpmTasks('grunt-fileslist');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['fileslist','replace', 'requirejs']);
I'm running into a problem where, if the "content/js/auto-modules.json" file doesn't already exist on load of my config file, the file.readJSON() is executed immediately, before the file exists and the entire task fails and throws "Error: Unable to read file " If the file already exists, everything works beautifully.
How can I set this up so that the task configuration waits for that file to be created in the first task, and modified in the second task before it tries to load & parse the JSON in it for the third task? Or is there another way (perhaps using a different plugin) to generate a json object in one task, and then pass that object to another task?
Old post but I had a similar experience.
I was trying to load a some json config like:
conf: grunt.file.readJSON('conf.json'),
but if this file did not exist then it would fall in a heap and not do anything.
So I did the following to load it and populate defaults if it didnt exist:
grunt.registerTask('checkConf', 'ensure conf.json is present', function(){
var conf = {};
try{
conf = grunt.file.readJSON('./conf.json');
} catch (e){
conf.foo = "";
conf.bar = "";
grunt.file.write("./conf.json", JSON.stringify(conf) );
}
grunt.config.set('conf', conf);
});
You still may have some timing issues but this approach may help someone with a readJSON error.

How to configure more than one svninfo object with grunt-svninfo?

I need to have two svninfo objects of two different svn repositories. The svn information of the app should be stored in the object svninfo_app and the svn information of the elstr repository (external) should be stored in svninfo_elstr:
information of repo app -> svninfo_app
information of repo elstr -> svninfo_elstr
My Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
svninfo: {
options: {
output: 'svninfo_app',
cwd: '.'
},
elstr: {
options: {
output: 'svninfo_elstr',
cwd: './public/jslib/elstr/2.0.dev'
}
}
},
svn_export: {
dev: {
options: {
repository: '<%= svninfo_elstr.url %>',
output: 'deploy/'
}
}
}
});
// https://npmjs.org/package/grunt-svninfo
grunt.loadNpmTasks('grunt-svninfo');
grunt.loadNpmTasks('grunt-svn-export');
// Default task.
grunt.registerTask('default', ['svninfo','svn_export']);
};
Returns a warning and aborts:
Running "svninfo" task
SVN info fetched (rev: 4)
Running "svn_export:dev" (svn_export) task
Warning: An error occurred while processing a template (Cannot read property 'url' of undefined). Use --force to continue.
Aborted due to warnings.
The object svninfo_elstr is undefined. Why this?
How to configure more than one svninfo object with grunt-svninfo?
Now I found a working solution. The following Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
svninfo: {
options: {
output: 'svninfo_app',
cwd: '.',
elstrCwd: './public/jslib/elstr/2.0.dev'
}
}
});
// https://npmjs.org/package/grunt-svninfo
grunt.loadNpmTasks('grunt-svninfo');
// Default task.
grunt.registerTask('default', ['svninfo','svninfo:svninfo_elstr:elstrCwd']);
};
Returns
Running "svninfo" task
SVN info fetched (rev: 5)
Running "svninfo:svninfo_elstr:elstrCwd" (svninfo) task
SVN info fetched (rev: 305)
Done, without errors.
It it necessary to register tow tasks:
'svninfo' -> returns the informations into the object svninfo_app with default options
'svninfo:svninfo_elstr:elstrCwd' -> returns the information into the object svninfo_elstr with options elstrCwd
Well, there's no property named svninfo_elstr, as the error message says. Your Grunt config doesn't have any svninfo_elstr properties.
How to configure more than one svninfo object with grunt-svninfo?
Maybe it would help to update the post with what you're trying to accomplish in more detail? E.g. what would it look like without the <%= %> stuff?

Run grunt server with various browsers

Is it possible to specify a particular browser (besides the OS' default) in the gruntfile or at the command prompt? E.g. "grunt server firefox" or the like. My default browser is Chrome, but I want to test/develop my site in multiple browsers. I am using GruntJS within Yeoman.
Bryan
Quick Answer
In Gruntfile.js you can add an app parameter:
open: {
server: {
url: 'http://localhost:<%= connect.options.port %>',
app: 'firefox'
}
},
Pull request: https://github.com/jsoverson/grunt-open/pull/7
Commit: https://github.com/GabLeRoux/grunt-open/commit/6f2c7069767e58160ec96aaaa8fa20ed210ba183
Command Line Parameters
It is possible to pass command line parameters in the app string, such as app: "chromium-browser --incognito" - #bk11425
From the documentation of grunt connect: https://github.com/gruntjs/grunt-contrib-connect
You can use:
open: {
target: 'http://localhost:8000', // target url to open
appName: 'open', // name of the app that opens, ie: open, start, xdg-open
callback: function() {} // called when the app has opened
}
i.e. appName: 'Google Chrome'
While the answers in here helped fix my occurrence of the problem, as someone who's not very familiar with grunt, I had a hard time figuring just exactly where I was supposed to put the "open:" stanza in my Gruntfile.js. It took me about three three tries for me to find the right spot (e.g I tried directly under 'grunt.initConfig' and under 'connect: options:' to no effect)
I'm using the Gruntfile.js as generated by the standard angular yeoman generator.
I'm posting where I put it in this file just to give a little more "context" for anyone in a similar predicament.
Here is the relevant snippet of the Gruntfile.js:
// ...
The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
//open: true, <- original line, comment out
// add this
open: {
//target: 'http://localhost:9000', <- this works too
target: 'http://localhost:<%= connect.options.port %>',
appName: 'firefox'
},
// end add
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect().use(
'/app/styles',
connect.static('./app/styles')
),
connect.static(appConfig.app)
];
}
}
},
test: {
//...
The grunt server task has almost nothing to do with the browser, it just starts a static server for you to connect to and preview your app. You could theoretically use any browser you want to connect to http://localhost:8080/
To clarify based on the poster's comment:
grunt-open is a different task than grunt-server: https://npmjs.org/package/grunt-open.grunt-open uses node-open which just defaults to the default open task for darwin or start for win32: https://github.com/jjrdn/node-open#how-it-works
So, to answer, whatever application you have specified to open .html files (or whatever you're opening) will open with this task.

Resources