/* * grunt-chmod * https://github.com/JamesMGreene/grunt-chmod * * Copyright (c) 2013 James M. Greene * Licensed under the MIT license. */ 'use strict'; var fs = require('fs'); module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jshint: { options: { jshintrc: '.jshintrc', }, all: [ 'Gruntfile.js', 'tasks/**/*.js', 'test/**/*.js', ] }, // Before generating any new files, remove any previously-created files. clean: { tests: ['tmp'], }, // Configuration to be run (and then tested). chmod: { // Emit events, JUST for testing purposes! options: { emit: true }, default_options: { src: ['tmp/default_options.txt'] }, custom_options_without_string_mode: { options: { mode: {} }, src: ['tmp/custom_options_without_string_mode.txt'] }, custom_options_with_empty_mode: { options: { mode: '' }, src: ['tmp/custom_options_with_empty_mode.txt'] }, custom_options_with_invalid_mode: { options: { mode: 'a+rwx' }, src: ['tmp/custom_options_with_invalid_mode.txt'] }, custom_options_nonexistent_file: { options: { mode: '600' }, src: ['tmp/custom_options_nonexistent_file.txt'] }, custom_options_file: { options: { /* Because it seems Windows will set the U digit (UGO) for all spots, so '400' => '444'. Default on Windows is: '666' */ mode: '444' }, src: ['tmp/custom_options_file.js'] }, custom_options_dir: { options: { /* Because it seems Windows will set the U digit (UGO) for all spots, so '400' => '444'. Default on Windows is: '666' */ mode: '444' }, src: ['tmp/custom_options_dir/'] }, custom_options_file_symbolic_1: { options: { mode: 'u+r' // 400 }, src: ['tmp/custom_options_file_symbolic_1.js'] }, custom_options_file_symbolic_2: { options: { mode: 'u+rw' // 600 }, src: ['tmp/custom_options_file_symbolic_2.js'] }, custom_options_file_symbolic_3: { options: { mode: 'u+rwx' // 700 }, src: ['tmp/custom_options_file_symbolic_3.js'] }, custom_options_file_symbolic_4: { options: { mode: 'uo+r' // 404 }, src: ['tmp/custom_options_file_symbolic_4.js'] }, }, // Unit tests. nodeunit: { all: ['test/*_test.js'] } }); // Actually load this plugin's task(s). grunt.loadTasks('tasks'); // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); var forceValue = (function(val) { return (typeof val === 'boolean' ? val : !!val); })(grunt.option('force')); // Enable force for tests to avoid the build halting on warnings grunt.registerTask('force-enable', function() { grunt.option('force', true); }); grunt.registerTask('force-revert', function() { grunt.option('force', forceValue); }); // Test setup grunt.registerTask('test-setup', function() { grunt.file.mkdir('tmp/custom_options_dir'); grunt.file.write('tmp/custom_options_file.js', ''); grunt.file.write('tmp/custom_options_file_symbolic_1.js', ''); grunt.file.write('tmp/custom_options_file_symbolic_2.js', ''); grunt.file.write('tmp/custom_options_file_symbolic_3.js', ''); grunt.file.write('tmp/custom_options_file_symbolic_4.js', ''); fs.chmodSync('tmp/custom_options_file_symbolic_1.js', '000'); fs.chmodSync('tmp/custom_options_file_symbolic_2.js', '000'); fs.chmodSync('tmp/custom_options_file_symbolic_3.js', '000'); fs.chmodSync('tmp/custom_options_file_symbolic_4.js', '000'); }); // Test emission listeners var args = (function() { var slicer = Array.prototype.slice; return function(argsObj) { return slicer.call(argsObj, 0); }; })(); var emissions = [], taskTargetName; grunt.registerTask('listeners-on', function() { grunt.event.on('chmod.*', function(msg) { if (this.event === 'chmod.taskTargetName') { taskTargetName = msg; return; } var emission = { name: this.event, args: args(arguments) }; emissions.push(emission); }); }); grunt.registerTask('listeners-off', function() { grunt.file.write('tmp/' + taskTargetName + '.json', JSON.stringify(emissions, null, 2)); emissions.length = 0; grunt.event.removeAllListeners('chmod.*'); }); var badConfigOptions = [ 'default_options', 'custom_options_without_string_mode', 'custom_options_with_empty_mode', 'custom_options_with_invalid_mode', 'custom_options_nonexistent_file' ]; badConfigOptions.forEach(function(e, i) { grunt.registerTask( 'test-prep-' + (i + 1), [ 'force-enable', 'listeners-on', 'chmod:' + e, 'listeners-off', 'force-revert' ] ); }); var goodConfigOptions = [ 'custom_options_file', 'custom_options_dir', 'custom_options_file_symbolic_1', 'custom_options_file_symbolic_2', 'custom_options_file_symbolic_3', 'custom_options_file_symbolic_4' ]; goodConfigOptions.forEach(function(e, i) { grunt.registerTask( 'test-prep-' + (badConfigOptions.length + i + 1), [ 'listeners-on', 'chmod:' + e, 'listeners-off' ] ); }); // Whenever the "test" task is run, first clean the "tmp" dir, then run this plugin's // task(s), then test the result(s). Do NOT clean the "tmp" dir at the end! grunt.registerTask( 'test', (function() { var taskList = []; taskList.push('clean'); taskList.push('test-setup'); for (var i = 1, len = (badConfigOptions.length + goodConfigOptions.length + 1); i < len; i++) { taskList.push('test-prep-' + i); } taskList.push('nodeunit'); return taskList; })() ); // By default: lint, run all tests, and clean it up. grunt.registerTask('default', ['jshint', 'test', 'clean']); // Travis-CI: lint, run all tests, and clean it up. grunt.registerTask('travis', ['jshint', 'test', 'clean']); };