Created
May 30, 2013 12:55
-
-
Save osuka/5677620 to your computer and use it in GitHub Desktop.
Sample gruntfile for Firefox OS projects, including testing, code coverage. Requires npm, bower and ruby (for compass)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Needs a configuration file with paths | |
for Gaia and standalone simulator | |
File contents for grunt.local.json (config): | |
{ | |
"b2g_bin_path": "/Applications/B2G.app/Contents/MacOS", | |
"gaia_homepath": "/Users/OAmat/Documents/code/gaia" | |
} | |
File contents for packages.json (node): | |
{ | |
"name": "webapp", | |
"version": "0.0.0", | |
"dependencies": {}, | |
"devDependencies": { | |
"grunt": "~0.4.1", | |
"grunt-contrib-copy": "~0.4.1", | |
"grunt-contrib-compass": "~0.2.0", | |
"grunt-contrib-jshint": "~0.4.3", | |
"grunt-contrib-connect": "~0.3.0", | |
"grunt-contrib-clean": "~0.4.1", | |
"grunt-contrib-imagemin": "~0.1.4", | |
"grunt-regarde": "~0.1.1", | |
"grunt-requirejs": "~0.3.5", | |
"grunt-mocha": "~0.3.1", | |
"grunt-open": "~0.2.0", | |
"grunt-shell": "~0.2.2", | |
"grunt-coverjs": "git://github.com/hull/grunt-coverjs.git", | |
"matchdep": "~0.1.2", | |
"grunt-contrib-handlebars": "~0.5.8" | |
}, | |
"engines": { | |
"node": ">=0.8.0" | |
} | |
} | |
File contents for component.json: (bower) | |
{ | |
"name": "webapp", | |
"version": "0.0.0", | |
"dependencies": { | |
"requirejs": "~2.1.5", | |
"underscore": "~1.4.4", | |
"zepto": "~1.0.0", | |
"backbone": "~1.0.0", | |
"handlebars.js": "1.0.0-rc.3", | |
"PhoneNumber.js": "~0.5.0" | |
}, | |
"devDependencies": {} | |
} | |
First time run: REQUIRES node >= 0.10.1, ruby >= 1.9.2 | |
npm install | |
gem install bundler && bundle install | |
bower install | |
*/ | |
/*jshint es5: true */ | |
'use strict'; | |
var mountFolder = function (connect, dir) { | |
return connect.static(require('path').resolve(dir)); | |
}; | |
module.exports = function (grunt) { | |
// load all grunt tasks | |
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); | |
grunt.initConfig({ | |
appPaths: { | |
app: 'app', | |
dist: 'dist' | |
}, | |
/* Local Project configuration (per developer) */ | |
properties: grunt.file.isFile('grunt.local.json') ? | |
grunt.file.readJSON('grunt.local.json') : {}, | |
simulator: { | |
b2gbin: '<%= properties.b2g_bin_path %>/b2g-bin' | |
}, | |
gaia: { | |
home: '<%= properties.gaia_homepath %>' | |
}, | |
/* Project tasks */ | |
watch: { | |
compass: { | |
files: ['<%= appPaths.app %>/styles/{,*/}*.{scss,sass}'], | |
tasks: ['compass'] | |
}, | |
handlebars: { | |
files: [ | |
'<%= appPaths.app %>/scripts/templates/*.hbs' | |
], | |
tasks: 'handlebars:compile' | |
}, | |
coverage: { | |
files: [ | |
'<%= appPaths.app %>/scripts/{,*/}*.js', | |
'<%= .tmp/scripts/*.js', | |
], | |
tasks: 'cover:compile' | |
} | |
}, | |
connect: { | |
options: { | |
port: 9000, | |
// change this to '0.0.0.0' to access the server from outside | |
hostname: 'localhost' | |
}, | |
server: { | |
options: { | |
middleware: function (connect) { | |
return [ | |
mountFolder(connect, '.tmp'), | |
mountFolder(connect, 'app') | |
]; | |
} | |
} | |
}, | |
test: { | |
options: { | |
port: 9002, | |
middleware: function (connect) { | |
return [ | |
mountFolder(connect, '.tmp'), | |
mountFolder(connect, 'test') | |
]; | |
} | |
} | |
}, | |
dist: { | |
options: { | |
middleware: function (connect) { | |
return [ | |
mountFolder(connect, 'dist') | |
]; | |
} | |
} | |
} | |
}, | |
open: { | |
server: { | |
path: 'http://localhost:<%= connect.options.port %>' | |
}, | |
test: { | |
path: 'http://localhost:<%= connect.test.options.port %>' | |
} | |
}, | |
clean: { | |
dist: ['.tmp', '<%= appPaths.dist %>/*'], | |
server: '.tmp' | |
}, | |
jshint: { | |
options: { | |
jshintrc: '.jshintrc' | |
}, | |
all: [ | |
'Gruntfile.js', | |
'<%= appPaths.app %>/scripts/{,*/}*.js', | |
'!<%= appPaths.app %>/scripts/vendor/*', | |
'test/spec/{,*/}*.js' | |
] | |
}, | |
mocha: { | |
all: { | |
options: { | |
reporter: 'Spec', | |
run: false, | |
urls: ['http://localhost:<%= connect.test.options.port %>/index.html'] | |
} | |
} | |
}, | |
compass: { | |
options: { | |
sassDir: '<%= appPaths.app %>/styles', | |
cssDir: '.tmp/styles', | |
imagesDir: '<%= appPaths.app %>/images', | |
javascriptsDir: '<%= appPaths.app %>/scripts', | |
fontsDir: '<%= appPaths.app %>/styles/fonts', | |
importPath: 'app/components', | |
relativeAssets: true | |
}, | |
dist: {}, | |
server: { | |
options: { | |
debugInfo: true | |
} | |
} | |
}, | |
imagemin: { | |
dist: { | |
files: [{ | |
expand: true, | |
cwd: '<%= appPaths.app %>/images', | |
src: '**/{,*/}*.{png,jpg,jpeg}', | |
dest: '<%= appPaths.dist %>/images' | |
}] | |
} | |
}, | |
copy: { | |
build: { | |
files: [{ | |
expand: true, | |
dot: true, | |
cwd: '<%= appPaths.app %>', | |
dest: '<%= appPaths.dist %>', | |
src: [ | |
/** COMPONENTS - Extracted from main.js config **/ | |
'components/requirejs/require.js', | |
'components/zepto/zepto.min.js', | |
'components/underscore/underscore-min.js', | |
'components/backbone/backbone-min.js', | |
'components/handlebars.js/dist/handlebars.runtime.js', | |
/** END OF COMPONENTS **/ | |
'icons/**/*.{png,jpg}', | |
'scripts/**/*.js', | |
'*.{ico,txt}', | |
'*.html', | |
'manifest.webapp' | |
] | |
}, { | |
expand: true, | |
cwd: '.tmp', | |
dest: '<%= appPaths.dist %>', | |
src: [ | |
'styles/**/*.css', | |
'scripts/**/*.js', | |
] | |
}, | |
{ | |
expand: true, | |
cwd: '<%= appPaths.app %>/images', | |
src: '**/*.{png,jpg,jpeg}', | |
dest: '<%= appPaths.dist %>/images' | |
} | |
] | |
} | |
}, | |
bower: { | |
all: { | |
rjsConfig: '<%= appPaths.app %>/scripts/main.js' | |
} | |
}, | |
handlebars: { | |
compile: { | |
files: { | |
'.tmp/scripts/templates.js': [ | |
'<%= appPaths.app %>/scripts/templates/*.hbs' | |
] | |
}, | |
options: { | |
namespace: 'Handlebars.templates', | |
amd: true, | |
processName: function (filename) { | |
// funky name processing here | |
return filename | |
.replace(/^app\/scripts\/templates\//, '') | |
.replace(/\.hbs$/, ''); | |
} | |
} | |
} | |
}, | |
cover: { | |
compile: { | |
files: { | |
'test/cov/*.js': ['app/scripts/**/*.js'], | |
'test/cov/templates.js': ['.tmp/scripts/templates.js'] | |
} | |
} | |
}, | |
shell: { | |
ensureLinkedInGaia: { | |
command: 'if [ ! -d <%= gaia.home %>/apps/myappname ]; then' + | |
' ln -s "$(pwd)/dist" "<%= gaia.home %>/apps/myappname";' + | |
'fi', | |
options: { | |
stdout: true | |
} | |
}, | |
launchB2G: { | |
command: '<%= simulator.b2gbin %> -profile ' + | |
'"<%= gaia.home %>/profile" ' + | |
'--screen=320x480@72 -jsconsole' | |
}, | |
killB2G: { | |
command: 'killall b2g-bin' | |
}, | |
makeGaiaDebug: { | |
command: 'DEBUG=1 NOFTU=1 make', | |
options: { | |
stdout: true, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
makeGaia: { | |
command: 'NOFTU=1 make', | |
options: { | |
stdout: true, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
ensureDistributionFolderExists: { | |
command: 'if [ ! -d "<%= gaia.home %>/distribution" ]; then ' + | |
'mkdir "<%= gaia.home %>/distribution";' + | |
'fi', | |
options: { | |
stdout: true | |
} | |
}, | |
generateContacts: { | |
command: 'if [ -f "$(pwd)/contacts.json" ]; then ' + | |
'cp "$(pwd)/contacts.json" ' + | |
'"<%= gaia.home %>/distribution/contacts.json";' + | |
'fi', | |
options: { | |
stdout: true | |
} | |
}, | |
cleanContacts: { | |
command: 'rm "<%= gaia.home %>/distribution/contacts.json";', | |
options: { | |
stdout: true | |
} | |
}, | |
pushAllToDevice: { | |
command: 'NOFTU=1 make install-gaia && adb reboot', | |
options: { | |
stdout: true, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
pushToDevice: { | |
command: 'NOFTU=1 BUILD_APP_NAME=myappname make install-gaia', | |
options: { | |
stdout: true, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
resetDevice: { | |
command: 'NOFTU=1 make reset-gaia', | |
options: { | |
stdout: true, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
removeGaiaProfile: { | |
command: 'rm -r profile', | |
options: { | |
stdout: true, | |
failOnError: false, | |
execOptions: { | |
cwd: '<%= gaia.home %>' | |
} | |
} | |
}, | |
enableRemoteDebugging: { | |
command: './enable-remote-debugging.sh "<%= gaia.home %>"', | |
options: { | |
stdout: true, | |
failOnError: true, | |
} | |
} | |
}, | |
}); | |
grunt.renameTask('regarde', 'watch'); | |
grunt.registerTask('checkProperties', function () { | |
return grunt.config.requires('properties.gaia_homepath'); | |
}); | |
grunt.registerTask('server', function (target) { | |
if (target === 'dist') { | |
grunt.task.run([ | |
'build', | |
'open:server', | |
'connect:dist:keepalive' | |
]); | |
} else if (target === 'test') { | |
grunt.task.run([ | |
'clean:server', | |
'handlebars:compile', | |
'cover:compile', | |
'compass:server', | |
'connect:test', | |
'open:test', | |
'watch' | |
]); | |
} else { | |
grunt.task.run([ | |
'jshint', | |
'clean:server', | |
'handlebars:compile', | |
'compass:server', | |
'connect:server', | |
//'open:server', | |
'watch' | |
]); | |
} | |
}); | |
grunt.registerTask('test', [ | |
'jshint', | |
'clean:server', | |
'handlebars:compile', | |
'compass', | |
'connect:test', | |
'mocha' | |
]); | |
grunt.registerTask('build', [ | |
'clean:dist', | |
'handlebars:compile', | |
'compass:dist', | |
// 'imagemin', | |
'copy:build', | |
]); | |
grunt.registerTask('dist', [ | |
'clean:dist', | |
'handlebars:compile', | |
'compass:dist', | |
// 'imagemin', | |
'copy:build', | |
]); | |
grunt.registerTask('simulate', 'Launch with B2G simulator', function () { | |
grunt.log.write('Using ' + grunt.config.get('simulator.b2gbin')); | |
grunt.task.run([ | |
'checkProperties', | |
'shell:removeGaiaProfile', | |
'build', | |
'shell:ensureLinkedInGaia', | |
'shell:killB2G', | |
'shell:ensureDistributionFolderExists', | |
'shell:generateContacts', | |
'shell:makeGaia', | |
'shell:enableRemoteDebugging', | |
'shell:launchB2G' | |
]); | |
}); | |
grunt.registerTask('clean-contacts', 'Clean generated contacts', function () { | |
if (grunt.file.isFile('contacts.json')) { | |
grunt.file.copy('contacts.json', 'contacts.json.sample'); | |
grunt.file.delete('contacts.json'); | |
} | |
grunt.task.run(['shell:cleanContacts']); | |
}); | |
grunt.registerTask('push-clean', 'Install in device ' + | |
'(rebooting and cleaning it)', function () { | |
grunt.task.run([ | |
'checkProperties', | |
'shell:removeGaiaProfile', | |
'build', | |
'shell:ensureLinkedInGaia', | |
'shell:ensureDistributionFolderExists', | |
'shell:generateContacts', | |
'shell:enableRemoteDebugging', | |
'shell:pushAllToDevice' | |
]); | |
}); | |
grunt.registerTask('push-hard', 'Install and reset the device ' + | |
' (use when you are getting desperate)', function () { | |
grunt.task.run([ | |
'checkProperties', | |
'shell:removeGaiaProfile', | |
'build', | |
'shell:ensureLinkedInGaia', | |
'shell:ensureDistributionFolderExists', | |
'shell:generateContacts', | |
'shell:enableRemoteDebugging', | |
'shell:resetDevice', | |
]); | |
}); | |
grunt.registerTask('push', 'Install in device ' + | |
'(only the this application)', function () { | |
grunt.task.run([ | |
'checkProperties', | |
'build', | |
'shell:ensureLinkedInGaia', | |
'shell:ensureDistributionFolderExists', | |
'shell:generateContacts', | |
'shell:enableRemoteDebugging', | |
'shell:pushToDevice' | |
]); | |
}); | |
grunt.registerTask('default', [ | |
'jshint', | |
'test', | |
'build' | |
]); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment