<commit_before>module.exports = function(grunt) {
	require('load-grunt-tasks')(grunt, ['grunt-*', 'grunt-bump']);

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		phantom: {
			dist: 'dist',
			compiled: 'standalone'
		},
		clean: {
			dist: ['<%= phantom.dist %>'],
			compiled: ['<%= phantom.compiled %>']
		},
		copy: {
			dist: {
				files: [{
					expand: true,
					dot: true,
					dest: '<%= phantom.dist %>',
					src: [
						'*.hbs',
						'partials/*.hbs',
						'assets/{js,font}/*.*'
					]
				}]
			},
			compiled: {
				files: [{
					expand: true,
					dot: true,
					dest: '<%= phantom.compiled %>',
					src: [
						'*.hbs',
						'partials/*.hbs',
						'assets/{js,font,css}/*.*'
					]
				}]
			}
		},
		sass: {
			dist: {
				options: {
					style: 'compressed',
					require: ['./helpers/url64.rb']
				},
				expand: true,
				cwd: './assets/scss/',
				src: ['*.scss', '!_*.scss'],
				dest: './assets/css/',
				ext: '.css'
			},
			dev: {
				options: {
					style: 'expanded',
					require: ['./helpers/url64.rb']
				},
				expand: true,
				cwd: './assets/scss/',
				src: ['*.scss', '!_*.scss'],
				dest: './assets/css/',
				ext: '.css'
			}
		},
		cssmin: {
			dist: {
				files: {
					'<%= phantom.dist %>/assets/css/main.css': './assets/**/**.css'
				}
			}
		},
		jshint: {
			files: ['Gruntfile.js', 'assets/**/*.js'],
			options: {
				curly: true,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				boss: true,
				eqnull: true,
				browser: true,

				globals: {
					module: true,
					require: true,
					console: true,
					$: true,
					jQuery: true
				}
			}
		},
		watch: {
			scss: {
				files: [
					'assets/**/*.{scss, scss}'
				],
				tasks: ['sass:dev']
			},
			livereload: {
				files: [
					'**/*.hbs',
					'assets/**/*.{css,js,png,jpg,gif,svg}'
				],
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			}
		},
		replace: {
			codes: {
				src: [
					'<%= phantom.compiled %>/partials/analytics.hbs',
					'<%= phantom.compiled %>/partials/disqus.hbs'
				],
				overwrite: true,
				replacements: [{
					from: /UA-21512134-2/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return 'UA-XXXXXXXX-X';
					}
				}, {
					from: /bartingerat/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return 'yourDisqusShortname';
					}
				}]
			},
			dist: {
				src: ['<%= phantom.dist %>/default.hbs'],
				overwrite: true,
				replacements: [{
					from: /\s*<link rel="stylesheet" type="text\/css" href="{{asset "\/css\/normalize.css"}}" \/>/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return '';
					}
				}]
			}
		},
		bump: {
			options: {
				updateConfigs: ['pkg'],
				commitFiles: ['package.json', '<%= phantom.compiled %>/package.json'],
				push: false
			}
		},
		rsync: {
			options: {
				args: ['--verbose'],
				exclude: ['.git*', '*.scss', 'node_modules'],
				recursive: true
			},
			dev: {
				options: {
					src: '<%= phantom.dist %>/',
					dest: '/home/ubuntu/ghost/content/themes/phantom',
					host: 'ubuntu@bartinger.at',
					syncDestIgnoreExcl: true
				}
			}
		},
		compress: {
			dist: {
				options: {
					archive: 'phantom.zip',
					mode: 'zip'
				},
				files: [{
					expand: true,
					src: "**/*",
					cwd: "dist/"
				}]
			}
		},
		"git-describe": {
			all: {}
		}
	});

	// Default Task
	grunt.registerTask('dev', [
		'jshint',
		'sass:dev',
		'watch'
	]);

	grunt.registerTask('build', [
		'clean:dist',
		'jshint',
		'copy:dist',
		'sass:dist',
		'cssmin:dist',
		'replace:dist'
	]);

	grunt.registerTask('compile', [
		'clean:compiled',
		'jshint',
		'sass:dev',
		'copy:compiled',
		'replace:codes'
	]);

	grunt.task.registerTask('packtheme', '', function(dir) {
		var pkg = grunt.file.readJSON('package.json');
		var data = JSON.stringify({
			name: pkg.name,
			version: pkg.version
		});
		var dist = grunt.config('phantom.dist');
		var compiled = grunt.config('phantom.compiled');

		grunt.file.write(dist + '/package.json', data);
		grunt.file.write(compiled + '/package.json', data);
	});

	grunt.task.registerTask('verify', '', function() {
		grunt.event.once('git-describe', function(rev) {
			grunt.log.writeln("Git Revision: " + rev.dirty);
		});
		grunt.task.run('git-describe');
	});

	grunt.task.registerTask('pump', '', function(increment) {
		var incrementTypes = ['patch', 'minor', 'major'];
		if (increment) {
			if (incrementTypes.indexOf(increment) === -1) {
				grunt.fail.fatal('"' + increment + '" is not a valid option use one of ' + incrementTypes.join(', '));
			}
		} else {
			increment = incrementTypes[0];
		}
		grunt.task.run([
			'bump-only:' + increment,
			'packtheme',
			'bump-commit'
		]);
	});

	grunt.registerTask('release', ['build', 'compile', 'pump']);
	grunt.registerTask('package', ['build', 'compile', 'packtheme', 'compress']);

};<commit_msg>Verify that repo isn't dirty<commit_after>module.exports = function(grunt) {
	require('load-grunt-tasks')(grunt, ['grunt-*', 'grunt-bump']);

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		phantom: {
			dist: 'dist',
			compiled: 'standalone'
		},
		clean: {
			dist: ['<%= phantom.dist %>'],
			compiled: ['<%= phantom.compiled %>']
		},
		copy: {
			dist: {
				files: [{
					expand: true,
					dot: true,
					dest: '<%= phantom.dist %>',
					src: [
						'*.hbs',
						'partials/*.hbs',
						'assets/{js,font}/*.*'
					]
				}]
			},
			compiled: {
				files: [{
					expand: true,
					dot: true,
					dest: '<%= phantom.compiled %>',
					src: [
						'*.hbs',
						'partials/*.hbs',
						'assets/{js,font,css}/*.*'
					]
				}]
			}
		},
		sass: {
			dist: {
				options: {
					style: 'compressed',
					require: ['./helpers/url64.rb']
				},
				expand: true,
				cwd: './assets/scss/',
				src: ['*.scss', '!_*.scss'],
				dest: './assets/css/',
				ext: '.css'
			},
			dev: {
				options: {
					style: 'expanded',
					require: ['./helpers/url64.rb']
				},
				expand: true,
				cwd: './assets/scss/',
				src: ['*.scss', '!_*.scss'],
				dest: './assets/css/',
				ext: '.css'
			}
		},
		cssmin: {
			dist: {
				files: {
					'<%= phantom.dist %>/assets/css/main.css': './assets/**/**.css'
				}
			}
		},
		jshint: {
			files: ['Gruntfile.js', 'assets/**/*.js'],
			options: {
				curly: true,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				boss: true,
				eqnull: true,
				browser: true,

				globals: {
					module: true,
					require: true,
					console: true,
					$: true,
					jQuery: true
				}
			}
		},
		watch: {
			scss: {
				files: [
					'assets/**/*.{scss, scss}'
				],
				tasks: ['sass:dev']
			},
			livereload: {
				files: [
					'**/*.hbs',
					'assets/**/*.{css,js,png,jpg,gif,svg}'
				],
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			}
		},
		replace: {
			codes: {
				src: [
					'<%= phantom.compiled %>/partials/analytics.hbs',
					'<%= phantom.compiled %>/partials/disqus.hbs'
				],
				overwrite: true,
				replacements: [{
					from: /UA-21512134-2/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return 'UA-XXXXXXXX-X';
					}
				}, {
					from: /bartingerat/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return 'yourDisqusShortname';
					}
				}]
			},
			dist: {
				src: ['<%= phantom.dist %>/default.hbs'],
				overwrite: true,
				replacements: [{
					from: /\s*<link rel="stylesheet" type="text\/css" href="{{asset "\/css\/normalize.css"}}" \/>/,
					to: function(matchedWord, index, fullText, regexMatches) {
						return '';
					}
				}]
			}
		},
		bump: {
			options: {
				updateConfigs: ['pkg'],
				commitFiles: ['package.json', '<%= phantom.compiled %>/package.json'],
				push: false
			}
		},
		rsync: {
			options: {
				args: ['--verbose'],
				exclude: ['.git*', '*.scss', 'node_modules'],
				recursive: true
			},
			dev: {
				options: {
					src: '<%= phantom.dist %>/',
					dest: '/home/ubuntu/ghost/content/themes/phantom',
					host: 'ubuntu@bartinger.at',
					syncDestIgnoreExcl: true
				}
			}
		},
		compress: {
			dist: {
				options: {
					archive: 'phantom.zip',
					mode: 'zip'
				},
				files: [{
					expand: true,
					src: "**/*",
					cwd: "dist/"
				}]
			}
		},
		"git-describe": {
			all: {}
		}
	});

	// Default Task
	grunt.registerTask('dev', [
		'jshint',
		'sass:dev',
		'watch'
	]);

	grunt.registerTask('compileDist', [
		'clean:dist',
		'jshint',
		'copy:dist',
		'sass:dist',
		'cssmin:dist',
		'replace:dist'
	]);

	grunt.registerTask('compileStandalone', [
		'clean:compiled',
		'jshint',
		'sass:dev',
		'copy:compiled',
		'replace:codes'
	]);

	grunt.task.registerTask('packtheme', '', function(dir) {
		var pkg = grunt.file.readJSON('package.json');
		var data = JSON.stringify({
			name: pkg.name,
			version: pkg.version
		});
		var dist = grunt.config('phantom.dist');
		var compiled = grunt.config('phantom.compiled');

		grunt.file.write(dist + '/package.json', data);
		grunt.file.write(compiled + '/package.json', data);
	});

	grunt.task.registerTask('verify', '', function() {
		grunt.event.once('git-describe', function(rev) {
			if (rev.dirty) {
				grunt.fail.fatal('You have uncommited changes. Please run "grunt build" and commit them first.');
			}
		});
		grunt.task.run('git-describe');
	});

	grunt.task.registerTask('pump', '', function(increment) {
		var incrementTypes = ['patch', 'minor', 'major'];
		if (increment) {
			if (incrementTypes.indexOf(increment) === -1) {
				grunt.fail.fatal('"' + increment + '" is not a valid option use one of ' + incrementTypes.join(', '));
			}
		} else {
			increment = incrementTypes[0];
		}
		grunt.task.run([
			'bump-only:' + increment,
			'packtheme',
			'bump-commit'
		]);
	});

	grunt.registerTask('build', ['compileStandalone', 'compileDist']);
	grunt.registerTask('release', ['build', 'verify', 'pump']);
	grunt.registerTask('package', ['build', 'packtheme', 'compress']);

};<|endoftext|>


<commit_before>var path = require('path');

module.exports = function(grunt) {
  'use strict';

  var bower = grunt.file.readJSON('bower.json');
  var components = [];
  for (var i in bower.concat.app) {
    components.push('components/' + bower.concat.app[i] + '/**/*.js');
  }
  components.push('components/' + 'webaudiorecorder/lib/WebAudioRecorder.js');

  var libtextsecurecomponents = [];
  for (i in bower.concat.libtextsecure) {
    libtextsecurecomponents.push('components/' + bower.concat.libtextsecure[i] + '/**/*.js');
  }

  var importOnce = require("node-sass-import-once");
  grunt.loadNpmTasks("grunt-sass");

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      components: {
        src: components,
        dest: 'js/components.js',
      },
      libtextsecurecomponents: {
        src: libtextsecurecomponents,
        dest: 'libtextsecure/components.js',
      },
      test: {
        src: [
          'components/mocha/mocha.js',
          'components/chai/chai.js',
          'test/_test.js'
        ],
        dest: 'test/test.js',
      },
      //TODO: Move errors back down?
      libtextsecure: {
        options: {
          banner: ";(function() {\n",
          footer: "})();\n",
        },
        src: [
          'libtextsecure/errors.js',
          'libtextsecure/libsignal-protocol.js',
          'libtextsecure/protocol_wrapper.js',

          'libtextsecure/crypto.js',
          'libtextsecure/storage.js',
          'libtextsecure/storage/user.js',
          'libtextsecure/storage/groups.js',
          'libtextsecure/storage/unprocessed.js',
          'libtextsecure/protobufs.js',
          'libtextsecure/websocket-resources.js',
          'libtextsecure/helpers.js',
          'libtextsecure/stringview.js',
          'libtextsecure/event_target.js',
          'libtextsecure/api.js',
          'libtextsecure/account_manager.js',
          'libtextsecure/message_receiver.js',
          'libtextsecure/outgoing_message.js',
          'libtextsecure/sendmessage.js',
          'libtextsecure/sync_request.js',
          'libtextsecure/contacts_parser.js',
          'libtextsecure/ProvisioningCipher.js',
          'libtextsecure/task_with_timeout.js',
        ],
        dest: 'js/libtextsecure.js',
      },
      libtextsecuretest: {
        src: [
          'components/jquery/dist/jquery.js',
          'components/mock-socket/dist/mock-socket.js',
          'components/mocha/mocha.js',
          'components/chai/chai.js',
          'libtextsecure/test/_test.js'
        ],
        dest: 'libtextsecure/test/test.js',
      }
    },
    sass: {
      options: {
        sourceMap: true,
        importer: importOnce
      },
      dev: {
        files: {
          "stylesheets/manifest.css": "stylesheets/manifest.scss"
        }
      }
    },
    jshint: {
      files: [
        'Gruntfile.js',
        'js/**/*.js',
        '!js/libtextsecure.js',
        '!js/WebAudioRecorderMp3.js',
        '!js/Mp3LameEncoder.min.js',
        '!js/libsignal-protocol-worker.js',
        '!js/components.js',
        '!js/signal_protocol_store.js',
        '_locales/**/*'
      ],
      options: { jshintrc: '.jshintrc' },
    },
    dist: {
      src: [
        'manifest.json',
        'background.html',
        'index.html',
        'options.html',
        '_locales/**',
        'protos/*',
        'js/**',
        'stylesheets/*.css',
        '!js/register.js'
      ],
      res: [
        'audio/**',
        'images/**/*',
        'fonts/*',
      ]
    },
    copy: {
      res: {
        files: [{ expand: true, dest: 'dist/', src: ['<%= dist.res %>'] }],
      },
      src: {
        files: [{ expand: true, dest: 'dist/', src: ['<%= dist.src %>'] }],
        options: {
          process: function(content, srcpath) {
            if (srcpath.match('background.js')) {
              return content.replace(
                /textsecure-service-staging.whispersystems.org/g,
                'textsecure-service-ca.whispersystems.org');
            } else if (srcpath.match('expire.js')) {
              var gitinfo = grunt.config.get('gitinfo');
              var commited = gitinfo.local.branch.current.lastCommitTime;
              var time = Date.parse(commited) + 1000 * 60 * 60 * 24 * 90;
              return content.replace(
                /var BUILD_EXPIRATION = 0/,
                "var BUILD_EXPIRATION = " + time
              );
            } else {
              return content;
            }
          }
        }
      }
    },
    jscs: {
      all: {
        src: [
        'Gruntfile',
        'js/**/*.js',
        '!js/libtextsecure.js',
        '!js/WebAudioRecorderMp3.js',
        '!js/Mp3LameEncoder.min.js',
        '!js/libsignal-protocol-worker.js',
        '!js/components.js',
        'test/**/*.js',
        '!test/blanket_mocha.js',
        '!test/test.js',
        ]
      }
    },
    watch: {
      sass: {
        files: ['./stylesheets/*.scss'],
        tasks: ['sass']
      },
      libtextsecure: {
        files: ['./libtextsecure/*.js', './libtextsecure/storage/*.js'],
        tasks: ['concat:libtextsecure']
      },
      dist: {
        files: ['<%= dist.src %>', '<%= dist.res %>'],
        tasks: ['copy_dist']
      },
      scripts: {
        files: ['<%= jshint.files %>', './js/**/*.js'],
        tasks: ['jshint']
      },
      style: {
        files: ['<%= jscs.all.src %>', './js/**/*.js'],
        tasks: ['jscs']
      },
    },
    connect: {
      server: {
        options: {
          base: '.',
          port: 9999
        }
      }
    },
    'saucelabs-mocha': {
      all: {
        options: {
          urls: [
            'http://127.0.0.1:9999/test/index.html',
            'http://127.0.0.1:9999/libtextsecure/test/index.html',
          ],
          build: process.env.TRAVIS_JOB_ID,
          browsers: [
            { browserName: 'chrome', version: '41' },
          ],
          testname: 'TextSecure-Browser Tests',
          'max-duration': 300,
          statusCheckAttempts: 200
        }
      }
    },
    exec: {
      'tx-pull': {
        cmd: 'tx pull'
      }
    },
    'test-release': {
      osx: {
        archive: 'mac/Signal.app/Contents/Resources/app.asar',
        exe: 'mac/Signal.app/Contents/MacOS/Signal'
      },
      mas: {
        archive: 'mas/Signal.app/Contents/Resources/app.asar',
        exe: 'mas/Signal.app/Contents/MacOS/Signal'
      },
      linux: {
        archive: 'linux-unpacked/resources/app.asar',
        exe: 'linux-unpacked/signal-desktop'
      },
      win: {
        archive: 'win-unpacked/resources/app.asar',
        exe: 'win-unpacked/Signal.exe'
      }
    },
    gitinfo: {} // to be populated by grunt gitinfo
  });

  Object.keys(grunt.config.get('pkg').devDependencies).forEach(function(key) {
    if (/^grunt(?!(-cli)?$)/.test(key)) {  // ignore grunt and grunt-cli
      grunt.loadNpmTasks(key);
    }
  });

  // Transifex does not understand placeholders, so this task patches all non-en
  // locales with missing placeholders
  grunt.registerTask('locale-patch', function(){
    var en = grunt.file.readJSON('_locales/en/messages.json');
    grunt.file.recurse('_locales', function(abspath, rootdir, subdir, filename){
      if (subdir === 'en' || filename !== 'messages.json'){
        return;
      }
      var messages = grunt.file.readJSON(abspath);

      for (var key in messages){
        if (en[key] !== undefined && messages[key] !== undefined){
          if (en[key].placeholders !== undefined && messages[key].placeholders === undefined){
            messages[key].placeholders = en[key].placeholders;
          }
        }
      }

      grunt.file.write(abspath, JSON.stringify(messages, null, 4) + '\n');
    });
  });

  grunt.registerTask('getExpireTime', function() {
      grunt.task.requires('gitinfo');
      var gitinfo = grunt.config.get('gitinfo');
      var commited = gitinfo.local.branch.current.lastCommitTime;
      var time = Date.parse(commited) + 1000 * 60 * 60 * 24 * 90;
      grunt.file.write('config/local-production.json',
        JSON.stringify({ buildExpiration: time }) + '\n');
  });

  grunt.registerTask('clean-release', function() {
    require('rimraf').sync('release');
    require('mkdirp').sync('release');
  });

  grunt.registerTask('fetch-release', function() {
    grunt.task.requires('gitinfo');
    require('mkdirp').sync('release');
    var fs = require('fs');
    var done = this.async();
    var package_json = grunt.config.get('pkg');
    var gitinfo = grunt.config.get('gitinfo');
    var https = require('https');

    var urlBase = "https://s3-us-west-1.amazonaws.com/signal-desktop-builds";
    var keyBase = 'WhisperSystems/Signal-Desktop';
    var sha = gitinfo.local.branch.current.SHA;
    var files = [
      'signal-desktop-' + package_json.version + '.zip',
      'Signal-' + package_json.version + '-win.zip'
    ];

    var extract = require('extract-zip');
    var download = function(url, dest, cb) {
        var file = fs.createWriteStream(dest);
        var request = https.get(url, function(response) {
          if (response.statusCode !== 200) {
            cb(response.statusCode);
          } else {
            response.pipe(file);
            file.on('finish', function() {
              file.close(function() {
                extract(dest, {dir: 'release'}, cb);
              });
            });
          }
        }).on('error', function(err) { // Handle errors
          fs.unlink(dest); // Delete the file async. (But we don't check the result)
          if (cb) cb(err.message);
        });
    };

    Promise.all(files.map(function(fileName) {
      var key = [ keyBase, sha, 'dist', fileName].join('/');
      var url = [urlBase, key].join('/');
      var dest = 'release/' + fileName;
      return new Promise(function(resolve) {
        console.log(url);
        download(url, dest, function(err) {
          if (err) {
            console.log('failed', dest, err);
            resolve(err);
          } else {
            console.log('done', dest);
            resolve();
          }
        });
      });
    })).then(function(results) {
      results.forEach(function(error) {
        if (error) {
          grunt.fail.warn('Failed to fetch some release artifacts');
        }
      });
      done();
    });
  });

  grunt.registerTask('unit-tests', 'Run unit tests inside Electron', function() {
      var environment = grunt.option('env') || 'test';
      var done = this.async();
      var failure;

      var Application = require('spectron').Application;
      var electronBinary = process.platform === 'win32' ? 'electron.cmd' : 'electron';
      var app = new Application({
        path: path.join(__dirname, 'node_modules', '.bin', electronBinary),
        args: [path.join(__dirname, 'main.js')],
        env: {
          NODE_ENV: environment
        }
      });

      function getMochaResults() {
        return window.mochaResults;
      }

      app.start().then(function() {
        return app.client.waitUntil(function() {
          return app.client.execute(getMochaResults).then(function(data) {
            return Boolean(data.value);
          });
        }, 10000, 'Expected to find window.mochaResults set!');
      }).then(function() {
        return app.client.execute(getMochaResults);
      }).then(function(data) {
        var results = data.value;
        if (results.failures > 0) {
          console.error(results.reports);
          failure = function() {
            grunt.fail.fatal('Found ' + results.failures + ' failing unit tests.');
          };
          return app.client.log('browser');
        } else {
          grunt.log.ok(results.passes + ' tests passed.');
        }
      }).then(function(logs) {
        if (logs) {
          console.error();
          console.error('Because tests failed, printing browser logs:');
          console.error(logs);
        }
      }).catch(function (error) {
        failure = function() {
          grunt.fail.fatal('Something went wrong: ' + error.message + ' ' + error.stack);
        };
      }).then(function () {
        // We need to use the failure variable and this early stop to clean up before
        // shutting down. Grunt's fail methods are the only way to set the return value,
        // but they shut the process down immediately!
        return app.stop();
      }).then(function() {
        if (failure) {
          failure();
        }
        done();
      }).catch(function (error) {
        console.error('Second-level error:', error.message, error.stack);
        if (failure) {
          failure();
        }
        done();
      });
  });

  grunt.registerMultiTask('test-release', 'Test packaged releases', function() {
      var dir = grunt.option('dir') || 'dist';
      var environment = grunt.option('env') || 'production';
      var asar = require('asar');
      var config = this.data;
      var archive = [dir, config.archive].join('/');
      var files = [
        'config/default.json',
        'config/' + environment + '.json',
        'config/local-' + environment + '.json'
      ];

      console.log(this.target, archive);
      var releaseFiles = files.concat(config.files || []);
      releaseFiles.forEach(function(fileName) {
        console.log(fileName);
        try {
          asar.statFile(archive, fileName);
          return true;
        } catch (e) {
          console.log(e);
          throw new Error("Missing file " + fileName);
        }
      });

      var done = this.async();
      // A simple test to verify a visible window is opened with a title
      var Application = require('spectron').Application;
      var assert = require('assert');

      var app = new Application({
        path: [dir, config.exe].join('/')
      });

      app.start().then(function () {
        return app.client.getWindowCount();
      }).then(function (count) {
        assert.equal(count, 1);
        console.log('window opened');
      }).then(function () {
        // Get the window's title
        return app.client.getTitle();
      }).then(function (title) {
        // Verify the window's title
        assert.equal(title, 'Signal');
        console.log('title ok');
      }).then(function () {
        assert(app.chromeDriver.logLines.indexOf('NODE_ENV ' + environment) > -1);
        console.log('environment ok');
      }).catch(function (error) {
        // Log any failures
        console.log('Test failed', error.message);
      }).then(function () {
        // Stop the application
        return app.stop();
      }).then(done);

      // todo: verify package.json has `environment: <environment>`
  });

  grunt.registerTask('tx', ['exec:tx-pull', 'locale-patch']);
  grunt.registerTask('dev', ['default', 'connect', 'watch']);
  grunt.registerTask('test', ['jshint', 'jscs', 'unit-tests']);
  grunt.registerTask('copy_dist', ['gitinfo', 'copy']);
  grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
  grunt.registerTask('prep-release', ['gitinfo', 'clean-release', 'fetch-release']);
  grunt.registerTask('default', ['concat', 'sass', 'date']);

};
<commit_msg>Add release test for auto updater config<commit_after>var path = require('path');

module.exports = function(grunt) {
  'use strict';

  var bower = grunt.file.readJSON('bower.json');
  var components = [];
  for (var i in bower.concat.app) {
    components.push('components/' + bower.concat.app[i] + '/**/*.js');
  }
  components.push('components/' + 'webaudiorecorder/lib/WebAudioRecorder.js');

  var libtextsecurecomponents = [];
  for (i in bower.concat.libtextsecure) {
    libtextsecurecomponents.push('components/' + bower.concat.libtextsecure[i] + '/**/*.js');
  }

  var importOnce = require("node-sass-import-once");
  grunt.loadNpmTasks("grunt-sass");

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      components: {
        src: components,
        dest: 'js/components.js',
      },
      libtextsecurecomponents: {
        src: libtextsecurecomponents,
        dest: 'libtextsecure/components.js',
      },
      test: {
        src: [
          'components/mocha/mocha.js',
          'components/chai/chai.js',
          'test/_test.js'
        ],
        dest: 'test/test.js',
      },
      //TODO: Move errors back down?
      libtextsecure: {
        options: {
          banner: ";(function() {\n",
          footer: "})();\n",
        },
        src: [
          'libtextsecure/errors.js',
          'libtextsecure/libsignal-protocol.js',
          'libtextsecure/protocol_wrapper.js',

          'libtextsecure/crypto.js',
          'libtextsecure/storage.js',
          'libtextsecure/storage/user.js',
          'libtextsecure/storage/groups.js',
          'libtextsecure/storage/unprocessed.js',
          'libtextsecure/protobufs.js',
          'libtextsecure/websocket-resources.js',
          'libtextsecure/helpers.js',
          'libtextsecure/stringview.js',
          'libtextsecure/event_target.js',
          'libtextsecure/api.js',
          'libtextsecure/account_manager.js',
          'libtextsecure/message_receiver.js',
          'libtextsecure/outgoing_message.js',
          'libtextsecure/sendmessage.js',
          'libtextsecure/sync_request.js',
          'libtextsecure/contacts_parser.js',
          'libtextsecure/ProvisioningCipher.js',
          'libtextsecure/task_with_timeout.js',
        ],
        dest: 'js/libtextsecure.js',
      },
      libtextsecuretest: {
        src: [
          'components/jquery/dist/jquery.js',
          'components/mock-socket/dist/mock-socket.js',
          'components/mocha/mocha.js',
          'components/chai/chai.js',
          'libtextsecure/test/_test.js'
        ],
        dest: 'libtextsecure/test/test.js',
      }
    },
    sass: {
      options: {
        sourceMap: true,
        importer: importOnce
      },
      dev: {
        files: {
          "stylesheets/manifest.css": "stylesheets/manifest.scss"
        }
      }
    },
    jshint: {
      files: [
        'Gruntfile.js',
        'js/**/*.js',
        '!js/libtextsecure.js',
        '!js/WebAudioRecorderMp3.js',
        '!js/Mp3LameEncoder.min.js',
        '!js/libsignal-protocol-worker.js',
        '!js/components.js',
        '!js/signal_protocol_store.js',
        '_locales/**/*'
      ],
      options: { jshintrc: '.jshintrc' },
    },
    dist: {
      src: [
        'manifest.json',
        'background.html',
        'index.html',
        'options.html',
        '_locales/**',
        'protos/*',
        'js/**',
        'stylesheets/*.css',
        '!js/register.js'
      ],
      res: [
        'audio/**',
        'images/**/*',
        'fonts/*',
      ]
    },
    copy: {
      res: {
        files: [{ expand: true, dest: 'dist/', src: ['<%= dist.res %>'] }],
      },
      src: {
        files: [{ expand: true, dest: 'dist/', src: ['<%= dist.src %>'] }],
        options: {
          process: function(content, srcpath) {
            if (srcpath.match('background.js')) {
              return content.replace(
                /textsecure-service-staging.whispersystems.org/g,
                'textsecure-service-ca.whispersystems.org');
            } else if (srcpath.match('expire.js')) {
              var gitinfo = grunt.config.get('gitinfo');
              var commited = gitinfo.local.branch.current.lastCommitTime;
              var time = Date.parse(commited) + 1000 * 60 * 60 * 24 * 90;
              return content.replace(
                /var BUILD_EXPIRATION = 0/,
                "var BUILD_EXPIRATION = " + time
              );
            } else {
              return content;
            }
          }
        }
      }
    },
    jscs: {
      all: {
        src: [
        'Gruntfile',
        'js/**/*.js',
        '!js/libtextsecure.js',
        '!js/WebAudioRecorderMp3.js',
        '!js/Mp3LameEncoder.min.js',
        '!js/libsignal-protocol-worker.js',
        '!js/components.js',
        'test/**/*.js',
        '!test/blanket_mocha.js',
        '!test/test.js',
        ]
      }
    },
    watch: {
      sass: {
        files: ['./stylesheets/*.scss'],
        tasks: ['sass']
      },
      libtextsecure: {
        files: ['./libtextsecure/*.js', './libtextsecure/storage/*.js'],
        tasks: ['concat:libtextsecure']
      },
      dist: {
        files: ['<%= dist.src %>', '<%= dist.res %>'],
        tasks: ['copy_dist']
      },
      scripts: {
        files: ['<%= jshint.files %>', './js/**/*.js'],
        tasks: ['jshint']
      },
      style: {
        files: ['<%= jscs.all.src %>', './js/**/*.js'],
        tasks: ['jscs']
      },
    },
    connect: {
      server: {
        options: {
          base: '.',
          port: 9999
        }
      }
    },
    'saucelabs-mocha': {
      all: {
        options: {
          urls: [
            'http://127.0.0.1:9999/test/index.html',
            'http://127.0.0.1:9999/libtextsecure/test/index.html',
          ],
          build: process.env.TRAVIS_JOB_ID,
          browsers: [
            { browserName: 'chrome', version: '41' },
          ],
          testname: 'TextSecure-Browser Tests',
          'max-duration': 300,
          statusCheckAttempts: 200
        }
      }
    },
    exec: {
      'tx-pull': {
        cmd: 'tx pull'
      }
    },
    'test-release': {
      osx: {
        archive: 'mac/Signal.app/Contents/Resources/app.asar',
        appUpdateYML: 'mac/Signal.app/Contents/Resources/app-update.yml',
        exe: 'mac/Signal.app/Contents/MacOS/Signal'
      },
      mas: {
        archive: 'mas/Signal.app/Contents/Resources/app.asar',
        appUpdateYML: 'mac/Signal.app/Contents/Resources/app-update.yml',
        exe: 'mas/Signal.app/Contents/MacOS/Signal'
      },
      linux: {
        archive: 'linux-unpacked/resources/app.asar',
        exe: 'linux-unpacked/signal-desktop'
      },
      win: {
        archive: 'win-unpacked/resources/app.asar',
        appUpdateYML: 'win-unpacked/resources/app-update.yml',
        exe: 'win-unpacked/Signal.exe'
      }
    },
    gitinfo: {} // to be populated by grunt gitinfo
  });

  Object.keys(grunt.config.get('pkg').devDependencies).forEach(function(key) {
    if (/^grunt(?!(-cli)?$)/.test(key)) {  // ignore grunt and grunt-cli
      grunt.loadNpmTasks(key);
    }
  });

  // Transifex does not understand placeholders, so this task patches all non-en
  // locales with missing placeholders
  grunt.registerTask('locale-patch', function(){
    var en = grunt.file.readJSON('_locales/en/messages.json');
    grunt.file.recurse('_locales', function(abspath, rootdir, subdir, filename){
      if (subdir === 'en' || filename !== 'messages.json'){
        return;
      }
      var messages = grunt.file.readJSON(abspath);

      for (var key in messages){
        if (en[key] !== undefined && messages[key] !== undefined){
          if (en[key].placeholders !== undefined && messages[key].placeholders === undefined){
            messages[key].placeholders = en[key].placeholders;
          }
        }
      }

      grunt.file.write(abspath, JSON.stringify(messages, null, 4) + '\n');
    });
  });

  grunt.registerTask('getExpireTime', function() {
      grunt.task.requires('gitinfo');
      var gitinfo = grunt.config.get('gitinfo');
      var commited = gitinfo.local.branch.current.lastCommitTime;
      var time = Date.parse(commited) + 1000 * 60 * 60 * 24 * 90;
      grunt.file.write('config/local-production.json',
        JSON.stringify({ buildExpiration: time }) + '\n');
  });

  grunt.registerTask('clean-release', function() {
    require('rimraf').sync('release');
    require('mkdirp').sync('release');
  });

  grunt.registerTask('fetch-release', function() {
    grunt.task.requires('gitinfo');
    require('mkdirp').sync('release');
    var fs = require('fs');
    var done = this.async();
    var package_json = grunt.config.get('pkg');
    var gitinfo = grunt.config.get('gitinfo');
    var https = require('https');

    var urlBase = "https://s3-us-west-1.amazonaws.com/signal-desktop-builds";
    var keyBase = 'WhisperSystems/Signal-Desktop';
    var sha = gitinfo.local.branch.current.SHA;
    var files = [
      'signal-desktop-' + package_json.version + '.zip',
      'Signal-' + package_json.version + '-win.zip'
    ];

    var extract = require('extract-zip');
    var download = function(url, dest, cb) {
        var file = fs.createWriteStream(dest);
        var request = https.get(url, function(response) {
          if (response.statusCode !== 200) {
            cb(response.statusCode);
          } else {
            response.pipe(file);
            file.on('finish', function() {
              file.close(function() {
                extract(dest, {dir: 'release'}, cb);
              });
            });
          }
        }).on('error', function(err) { // Handle errors
          fs.unlink(dest); // Delete the file async. (But we don't check the result)
          if (cb) cb(err.message);
        });
    };

    Promise.all(files.map(function(fileName) {
      var key = [ keyBase, sha, 'dist', fileName].join('/');
      var url = [urlBase, key].join('/');
      var dest = 'release/' + fileName;
      return new Promise(function(resolve) {
        console.log(url);
        download(url, dest, function(err) {
          if (err) {
            console.log('failed', dest, err);
            resolve(err);
          } else {
            console.log('done', dest);
            resolve();
          }
        });
      });
    })).then(function(results) {
      results.forEach(function(error) {
        if (error) {
          grunt.fail.warn('Failed to fetch some release artifacts');
        }
      });
      done();
    });
  });

  grunt.registerTask('unit-tests', 'Run unit tests inside Electron', function() {
      var environment = grunt.option('env') || 'test';
      var done = this.async();
      var failure;

      var Application = require('spectron').Application;
      var electronBinary = process.platform === 'win32' ? 'electron.cmd' : 'electron';
      var app = new Application({
        path: path.join(__dirname, 'node_modules', '.bin', electronBinary),
        args: [path.join(__dirname, 'main.js')],
        env: {
          NODE_ENV: environment
        }
      });

      function getMochaResults() {
        return window.mochaResults;
      }

      app.start().then(function() {
        return app.client.waitUntil(function() {
          return app.client.execute(getMochaResults).then(function(data) {
            return Boolean(data.value);
          });
        }, 10000, 'Expected to find window.mochaResults set!');
      }).then(function() {
        return app.client.execute(getMochaResults);
      }).then(function(data) {
        var results = data.value;
        if (results.failures > 0) {
          console.error(results.reports);
          failure = function() {
            grunt.fail.fatal('Found ' + results.failures + ' failing unit tests.');
          };
          return app.client.log('browser');
        } else {
          grunt.log.ok(results.passes + ' tests passed.');
        }
      }).then(function(logs) {
        if (logs) {
          console.error();
          console.error('Because tests failed, printing browser logs:');
          console.error(logs);
        }
      }).catch(function (error) {
        failure = function() {
          grunt.fail.fatal('Something went wrong: ' + error.message + ' ' + error.stack);
        };
      }).then(function () {
        // We need to use the failure variable and this early stop to clean up before
        // shutting down. Grunt's fail methods are the only way to set the return value,
        // but they shut the process down immediately!
        return app.stop();
      }).then(function() {
        if (failure) {
          failure();
        }
        done();
      }).catch(function (error) {
        console.error('Second-level error:', error.message, error.stack);
        if (failure) {
          failure();
        }
        done();
      });
  });

  grunt.registerMultiTask('test-release', 'Test packaged releases', function() {
      var dir = grunt.option('dir') || 'dist';
      var environment = grunt.option('env') || 'production';
      var asar = require('asar');
      var config = this.data;
      var archive = [dir, config.archive].join('/');
      var files = [
        'config/default.json',
        'config/' + environment + '.json',
        'config/local-' + environment + '.json'
      ];

      console.log(this.target, archive);
      var releaseFiles = files.concat(config.files || []);
      releaseFiles.forEach(function(fileName) {
        console.log(fileName);
        try {
          asar.statFile(archive, fileName);
          return true;
        } catch (e) {
          console.log(e);
          throw new Error("Missing file " + fileName);
        }
      });

      if (config.appUpdateYML) {
        var appUpdateYML = [dir, config.appUpdateYML].join('/');
        if (require('fs').existsSync(appUpdateYML)) {
          console.log("auto update ok");
        } else {
          throw new Error("Missing auto update config " + appUpdateYML);
        }
      }

      var done = this.async();
      // A simple test to verify a visible window is opened with a title
      var Application = require('spectron').Application;
      var assert = require('assert');

      var app = new Application({
        path: [dir, config.exe].join('/')
      });

      app.start().then(function () {
        return app.client.getWindowCount();
      }).then(function (count) {
        assert.equal(count, 1);
        console.log('window opened');
      }).then(function () {
        // Get the window's title
        return app.client.getTitle();
      }).then(function (title) {
        // Verify the window's title
        assert.equal(title, 'Signal');
        console.log('title ok');
      }).then(function () {
        assert(app.chromeDriver.logLines.indexOf('NODE_ENV ' + environment) > -1);
        console.log('environment ok');
      }).catch(function (error) {
        // Log any failures
        console.log('Test failed', error.message);
      }).then(function () {
        // Stop the application
        return app.stop();
      }).then(done);

      // todo: verify package.json has `environment: <environment>`
  });

  grunt.registerTask('tx', ['exec:tx-pull', 'locale-patch']);
  grunt.registerTask('dev', ['default', 'connect', 'watch']);
  grunt.registerTask('test', ['jshint', 'jscs', 'unit-tests']);
  grunt.registerTask('copy_dist', ['gitinfo', 'copy']);
  grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
  grunt.registerTask('prep-release', ['gitinfo', 'clean-release', 'fetch-release']);
  grunt.registerTask('default', ['concat', 'sass', 'date']);

};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  'use strict';

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',

    clean: {
      examples: [
        '/examples/libglobal/dist/',
        '/examples/libglobal-hybrid/dist/',
        '/examples/multipage/www-built/',
        '/examples/multipage-shim/www-built/'
      ],
      tmp: ['tmp']
    },

    copy: {
      dist: {
        files: {
          'tmp/doNotKillAlmond/': 'test/fixtures/*.js'
        }
      }
    },

    // Configuration to be run (and then tested).
    requirejs: {
      compile: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs.js'
        }
      },
      rmCombined: {
        options: {
          baseUrl: 'tmp/doNotKillAlmond',
          name: 'project',
          out: 'tmp/requirejs-killed.js',
          almond: true,
          removeCombined: true
        }
      },
      template: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs-template.js'
        }
      },
      sourcemaps: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs-sourcemaps.js',
          optimize: "uglify2",
          generateSourceMaps: true,
          preserveLicenseComments: false,
          useSourceUrl: true
        }
      }
    },

    nodeunit: {
      all: ['test/*_test.js']
    },

    qunit: {
      options: {
        timeout: 20000
      },
      all: ['examples/**/tests/*.html']
    },

    watch: {
      files: '<config:lint.files>',
      tasks: 'default'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true,
        es5: true,
        globals: {
          exports: true,
          require: true,
          module: true
        },
      },
      all: ['grunt.js', 'tasks/**/*.js', 'test/require_test.js', 'lib/**/*.js']
    }
  });

  // build all the projects from the ´examples´ folder
  // to run some tests against them
  grunt.registerTask('buildExampleProjects', function () {
    var done = this.async(),
        util = grunt.utils || grunt.util,
        preparation = [false, false, false, false],
        checkForPreparation = function () {
          if (util._.all(preparation, util._.identity)) {
            grunt.log.ok('all examples build');
            done();
          }
        };

    // build libglobal example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/libglobal'}
    }, function () {
      grunt.log.writeln('> "libglobal" example build');
      preparation[0] = true;
      checkForPreparation();
    });

    // build libglobal-hybrid example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/libglobal-hybrid'}
    }, function () {
      grunt.log.writeln('> "libglobal-hybrid" example build');
      preparation[3] = true;
      checkForPreparation();
    });

    // build multipage example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/multipage'}
    }, function () {
      grunt.log.writeln('> "multipage" example build');
      preparation[1] = true;
      checkForPreparation();
    });

    // build multipage-shim example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/multipage-shim'}
    }, function () {
      grunt.log.writeln('> "multipage-shim" example build');
      preparation[2] = true;
      checkForPreparation();
    });

  });

  // Load tasks.
  grunt.loadTasks('tasks');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-nodeunit');
  grunt.loadNpmTasks('grunt-contrib-qunit');

  // Setup the test environment task.
  grunt.registerTask('setUp', ['buildExampleProjects', 'copy', 'requirejs']);

  // Default task.
  grunt.registerTask('default', ['setUp', 'jshint', 'nodeunit', 'qunit', 'clean']);
};
<commit_msg>Changed qunit test order<commit_after>module.exports = function(grunt) {
  'use strict';

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',

    clean: {
      examples: [
        '/examples/libglobal/dist/',
        '/examples/libglobal-hybrid/dist/',
        '/examples/multipage/www-built/',
        '/examples/multipage-shim/www-built/'
      ],
      tmp: ['tmp']
    },

    copy: {
      dist: {
        files: {
          'tmp/doNotKillAlmond/': 'test/fixtures/*.js'
        }
      }
    },

    // Configuration to be run (and then tested).
    requirejs: {
      compile: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs.js'
        }
      },
      rmCombined: {
        options: {
          baseUrl: 'tmp/doNotKillAlmond',
          name: 'project',
          out: 'tmp/requirejs-killed.js',
          almond: true,
          removeCombined: true
        }
      },
      template: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs-template.js'
        }
      },
      sourcemaps: {
        options: {
          baseUrl: 'test/fixtures',
          name: 'project',
          out: 'tmp/requirejs-sourcemaps.js',
          optimize: "uglify2",
          generateSourceMaps: true,
          preserveLicenseComments: false,
          useSourceUrl: true
        }
      }
    },

    nodeunit: {
      all: ['test/*_test.js']
    },

    qunit: {
      options: {
        timeout: 20000
      },
      all: [
        'examples/multipage/tests/*.html',
        'examples/libglobal/tests/*.html',
        'examples/libglobal-hybrid/tests/*.html'
      ]
    },

    watch: {
      files: '<config:lint.files>',
      tasks: 'default'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true,
        es5: true,
        globals: {
          exports: true,
          require: true,
          module: true
        },
      },
      all: ['grunt.js', 'tasks/**/*.js', 'test/require_test.js', 'lib/**/*.js']
    }
  });

  // build all the projects from the ´examples´ folder
  // to run some tests against them
  grunt.registerTask('buildExampleProjects', function () {
    var done = this.async(),
        util = grunt.utils || grunt.util,
        preparation = [false, false, false, false],
        checkForPreparation = function () {
          if (util._.all(preparation, util._.identity)) {
            grunt.log.ok('all examples build');
            done();
          }
        };

    // build libglobal example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/libglobal'}
    }, function () {
      grunt.log.writeln('> "libglobal" example build');
      preparation[0] = true;
      checkForPreparation();
    });

    // build libglobal-hybrid example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/libglobal-hybrid'}
    }, function () {
      grunt.log.writeln('> "libglobal-hybrid" example build');
      preparation[3] = true;
      checkForPreparation();
    });

    // build multipage example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/multipage'}
    }, function () {
      grunt.log.writeln('> "multipage" example build');
      preparation[1] = true;
      checkForPreparation();
    });

    // build multipage-shim example
    util.spawn({
      cmd: 'grunt',
      args: ['build', '--force'],
      opts: {cwd: 'examples/multipage-shim'}
    }, function () {
      grunt.log.writeln('> "multipage-shim" example build');
      preparation[2] = true;
      checkForPreparation();
    });

  });

  // Load tasks.
  grunt.loadTasks('tasks');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-nodeunit');
  grunt.loadNpmTasks('grunt-contrib-qunit');

  // Setup the test environment task.
  grunt.registerTask('setUp', ['buildExampleProjects', 'copy', 'requirejs']);

  // Default task.
  grunt.registerTask('default', ['setUp', 'jshint', 'nodeunit', 'qunit', 'clean']);
};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    grunt.initConfig({
        bower_concat: require('./grunt/bower-concat'),
        clean: require('./grunt/clean'),
        concat: require('./grunt/concat'),
        connect: require('./grunt/connect'),
        copy: require('./grunt/copy'),
        jshint: require('./grunt/jshint'),
        karma: require('./grunt/karma'),
        ngtemplates: require('./grunt/angular-templates'),
        sass: require('./grunt/sass'),
        sasslint: require('./grunt/sasslint'),
        tags: require('./grunt/script-link-tags'),
        watch: require('./grunt/watch')
    });

    grunt.registerTask('build-develop', [
        'clean:build',
        'copy:index',

        'build-js',
        'build-css'
    ]);

    grunt.registerTask('build-release', [
        'build-develop',
        'clean:temp'
    ]);

    grunt.registerTask('test-js', [
        'jshint',
        'karma:coverage'
    ]);

    grunt.registerTask('test-css', [
        'sasslint'
    ]);

    /**
     * The output of build-js are two files 'build/atlas.js' and a source map.
     */
    grunt.registerTask('build-js', [
        'bower_concat:js',
        'ngtemplates',
        'concat:js',
        'tags:js'
    ]);

    /**
     * The output of build-css are two files 'build/atlas.css' and a source map.
     */
    grunt.registerTask('build-css', [
        'bower_concat:css',
        'sass',
        'concat:css',
        'tags:css'
    ]);

    /**
     * 'default' formerly known as 'grunt serve'
     */
    grunt.registerTask('default', [
        'build-develop',
        'connect:build',
        'watch'
    ]);

    grunt.registerTask('test', [
        'build-release',
        'test-js',
        'test-css'
    ]);

    grunt.loadNpmTasks('grunt-angular-templates');
    grunt.loadNpmTasks('grunt-bower-concat');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-sass-lint');
    grunt.loadNpmTasks('grunt-script-link-tags');
};<commit_msg>Testen met de develop build.<commit_after>module.exports = function (grunt) {
    grunt.initConfig({
        bower_concat: require('./grunt/bower-concat'),
        clean: require('./grunt/clean'),
        concat: require('./grunt/concat'),
        connect: require('./grunt/connect'),
        copy: require('./grunt/copy'),
        jshint: require('./grunt/jshint'),
        karma: require('./grunt/karma'),
        ngtemplates: require('./grunt/angular-templates'),
        sass: require('./grunt/sass'),
        sasslint: require('./grunt/sasslint'),
        tags: require('./grunt/script-link-tags'),
        watch: require('./grunt/watch')
    });

    grunt.registerTask('build-develop', [
        'clean:build',
        'copy:index',

        'build-js',
        'build-css'
    ]);

    grunt.registerTask('build-release', [
        'build-develop',
        'clean:temp'
    ]);

    grunt.registerTask('test-js', [
        'jshint',
        'karma:coverage'
    ]);

    grunt.registerTask('test-css', [
        'sasslint'
    ]);

    /**
     * The output of build-js are two files 'build/atlas.js' and a source map.
     */
    grunt.registerTask('build-js', [
        'bower_concat:js',
        'ngtemplates',
        'concat:js',
        'tags:js'
    ]);

    /**
     * The output of build-css are two files 'build/atlas.css' and a source map.
     */
    grunt.registerTask('build-css', [
        'bower_concat:css',
        'sass',
        'concat:css',
        'tags:css'
    ]);

    /**
     * 'default' formerly known as 'grunt serve'
     */
    grunt.registerTask('default', [
        'build-develop',
        'connect:build',
        'watch'
    ]);

    grunt.registerTask('test', [
        'build-develop',
        'test-js',
        'test-css'
    ]);

    grunt.loadNpmTasks('grunt-angular-templates');
    grunt.loadNpmTasks('grunt-bower-concat');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-sass-lint');
    grunt.loadNpmTasks('grunt-script-link-tags');
};<|endoftext|>


<commit_before>/*
 * grunt-angular-combine
 * https://github.com/astik/grunt-angular-combine
 *
 * Copyright (c) 2013 Romain Gonord
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	// Project configuration.
	grunt.initConfig({
		jshint : {
			all : [ 'Gruntfile.js', 'tasks/*.js', '<%= nodeunit.tests %>' ],
			options : {
				jshintrc : '.jshintrc',
			},
		},

		// Before generating any new files, remove any previously-created files.
		clean : {
			tests : [ 'tmp' ],
		},

		// Configuration to be run (and then tested).
		angularCombine : {
			combine : {
				files : [ {
					expand : true,
					cwd : 'test/fixtures',
					src : '*',
					dest : 'tmp/combined',
					filter : 'isDirectory'
				} ]
			},
		},

		// Unit tests.
		nodeunit : {
			tests : [ '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');

	// Whenever the "test" task is run, first clean the "tmp" dir, then run this
	// plugin's task(s), then test the result.
	grunt.registerTask('test', [ 'clean', 'angularCombine', 'nodeunit' ]);

	// By default, lint and run all tests.
	grunt.registerTask('default', [ 'jshint', 'test' ]);

};
<commit_msg>remove useless colon<commit_after>/*
 * grunt-angular-combine
 * https://github.com/astik/grunt-angular-combine
 *
 * Copyright (c) 2013 Romain Gonord
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	// Project configuration.
	grunt.initConfig({
		jshint : {
			all : [ 'Gruntfile.js', 'tasks/*.js', '<%= nodeunit.tests %>' ],
			options : {
				jshintrc : '.jshintrc'
			}
		},

		// Before generating any new files, remove any previously-created files.
		clean : {
			tests : [ 'tmp' ]
		},

		// Configuration to be run (and then tested).
		angularCombine : {
			combine : {
				files : [ {
					expand : true,
					cwd : 'test/fixtures',
					src : '*',
					dest : 'tmp/combined',
					filter : 'isDirectory'
				} ]
			}
		},

		// Unit tests.
		nodeunit : {
			tests : [ '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');

	// Whenever the "test" task is run, first clean the "tmp" dir, then run this
	// plugin's task(s), then test the result.
	grunt.registerTask('test', [ 'clean', 'angularCombine', 'nodeunit' ]);

	// By default, lint and run all tests.
	grunt.registerTask('default', [ 'jshint', 'test' ]);

};
<|endoftext|>


<commit_before>// Generated on 2014-10-27 using generator-chrome-extension 0.2.11
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Configurable paths
  var config = {
    app: 'app',
    dist: 'dist'
  };

  grunt.initConfig({

    // Project settings
    config: config,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['bowerInstall']
      },
      coffee: {
        files: ['<%= config.app %>/scripts/{,*/}*.{coffee,litcoffee,coffee.md}'],
        tasks: ['coffee:chrome'],
        options: {
          livereload: true
        }
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      styles: {
        files: ['<%= config.app %>/styles/{,*/}*.css'],
        tasks: [],
        options: {
          livereload: true
        }
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= config.app %>/*.html',
          '<%= config.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= config.app %>/manifest.json',
          '<%= config.app %>/_locales/{,*/}*.json'
        ]
      }
    },

    // Grunt server and debug server setting
    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: 'localhost'
      },
      chrome: {
        options: {
          open: false,
          base: [
            '<%= config.app %>'
          ]
        }
      },
      test: {
        options: {
          open: false,
          base: [
            'test',
            '<%= config.app %>'
          ]
        }
      }
    },

    // Empties folders to start fresh
    clean: {
      chrome: {
      },
      dist: {
        files: [{
          dot: true,
          src: [
            '<%= config.dist %>/*',
            '!<%= config.dist %>/.git*'
          ]
        }]
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= config.app %>/scripts/{,*/}*.js',
        '!<%= config.app %>/scripts/vendor/*',
        'test/spec/{,*/}*.js'
      ]
    },
    mocha: {
      all: {
        options: {
          run: true,
          urls: ['http://localhost:<%= connect.options.port %>/index.html']
        }
      }
    },

    // Compiles CoffeeScript to JavaScript
    coffee: {
      chrome: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/scripts',
          src: '{,*/}*.{coffee,litcoffee,coffee.md}',
          dest: '<%= config.app %>/scripts',
          ext: '.js'
        }]
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/scripts',
          src: '{,*/}*.{coffee,litcoffee,coffee.md}',
          dest: '<%= config.app %>/scripts',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '{,*/}*.coffee',
          dest: './spec',
          ext: '.js'
        }]
      }
    },

    // Automatically inject Bower components into the HTML file
    bowerInstall: {
      app: {
        src: [
          '<%= config.app %>/*.html'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      options: {
        dest: '<%= config.dist %>'
      },
      html: [
        '<%= config.app %>/popup.html',
        '<%= config.app %>/options.html'
      ]
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      options: {
        assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images']
      },
      html: ['<%= config.dist %>/{,*/}*.html'],
      css: ['<%= config.dist %>/styles/{,*/}*.css']
    },

    // The following *-min tasks produce minifies files in the dist folder
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/images',
          src: '{,*/}*.{gif,jpeg,jpg,png}',
          dest: '<%= config.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= config.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          // removeCommentsFromCDATA: true,
          // collapseWhitespace: true,
          // collapseBooleanAttributes: true,
          // removeAttributeQuotes: true,
          // removeRedundantAttributes: true,
          // useShortDoctype: true,
          // removeEmptyAttributes: true,
          // removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>',
          src: '*.html',
          dest: '<%= config.dist %>'
        }]
      }
    },

    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= config.dist %>/styles/main.css': [
    //         '<%= config.app %>/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= config.dist %>/scripts/scripts.js': [
    //         '<%= config.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>',
          dest: '<%= config.dist %>',
          src: [
            '*.{ico,png,txt}',
            'images/{,*/}*.{webp,gif}',
            '{,*/}*.html',
            'styles/{,*/}*.css',
            'styles/fonts/{,*/}*.*',
            '_locales/{,*/}*.json',
          ]
        }]
      }
    },

    // Run some tasks in parallel to speed up build process
    concurrent: {
      chrome: [
        'coffee:chrome',
      ],
      dist: [
        'coffee:dist',
        'imagemin',
        'svgmin'
      ],
      test: [
        'coffee:test',
      ]
    },

    // Auto buildnumber, exclude debug files. smart builds that event pages
    chromeManifest: {
      dist: {
        options: {
          buildnumber: true,
          background: {
            target: 'scripts/background.js',
            exclude: [
              'scripts/chromereload.js'
            ]
          }
        },
        src: '<%= config.app %>',
        dest: '<%= config.dist %>'
      }
    },

    // Compres dist files to package
    compress: {
      dist: {
        options: {
          archive: function() {
            var manifest = grunt.file.readJSON('app/manifest.json');
            return 'package/BTC Address Monitor-' + manifest.version + '.zip';
          }
        },
        files: [{
          expand: true,
          cwd: 'dist/',
          src: ['**'],
          dest: ''
        }]
      }
    }
  });

  grunt.registerTask('debug', function () {
    grunt.task.run([
      'jshint',
      'concurrent:chrome',
      'connect:chrome',
      'watch'
    ]);
  });

  grunt.registerTask('test', [
    'connect:test',
    'mocha'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'chromeManifest:dist',
    'useminPrepare',
    'concurrent:dist',
    'cssmin',
    'concat',
    'uglify',
    'copy',
    'usemin',
    'compress'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'test',
    'build'
  ]);
};
<commit_msg>pointless jshint checks removed<commit_after>// Generated on 2014-10-27 using generator-chrome-extension 0.2.11
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Configurable paths
  var config = {
    app: 'app',
    dist: 'dist'
  };

  grunt.initConfig({

    // Project settings
    config: config,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['bowerInstall']
      },
      coffee: {
        files: ['<%= config.app %>/scripts/{,*/}*.{coffee,litcoffee,coffee.md}'],
        tasks: ['coffee:chrome'],
        options: {
          livereload: true
        }
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      styles: {
        files: ['<%= config.app %>/styles/{,*/}*.css'],
        tasks: [],
        options: {
          livereload: true
        }
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= config.app %>/*.html',
          '<%= config.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= config.app %>/manifest.json',
          '<%= config.app %>/_locales/{,*/}*.json'
        ]
      }
    },

    // Grunt server and debug server setting
    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: 'localhost'
      },
      chrome: {
        options: {
          open: false,
          base: [
            '<%= config.app %>'
          ]
        }
      },
      test: {
        options: {
          open: false,
          base: [
            'test',
            '<%= config.app %>'
          ]
        }
      }
    },

    // Empties folders to start fresh
    clean: {
      chrome: {
      },
      dist: {
        files: [{
          dot: true,
          src: [
            '<%= config.dist %>/*',
            '!<%= config.dist %>/.git*'
          ]
        }]
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '!<%= config.app %>/scripts/vendor/*',
        'test/spec/{,*/}*.js'
      ]
    },
    mocha: {
      all: {
        options: {
          run: true,
          urls: ['http://localhost:<%= connect.options.port %>/index.html']
        }
      }
    },

    // Compiles CoffeeScript to JavaScript
    coffee: {
      chrome: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/scripts',
          src: '{,*/}*.{coffee,litcoffee,coffee.md}',
          dest: '<%= config.app %>/scripts',
          ext: '.js'
        }]
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/scripts',
          src: '{,*/}*.{coffee,litcoffee,coffee.md}',
          dest: '<%= config.app %>/scripts',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '{,*/}*.coffee',
          dest: './spec',
          ext: '.js'
        }]
      }
    },

    // Automatically inject Bower components into the HTML file
    bowerInstall: {
      app: {
        src: [
          '<%= config.app %>/*.html'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      options: {
        dest: '<%= config.dist %>'
      },
      html: [
        '<%= config.app %>/popup.html',
        '<%= config.app %>/options.html'
      ]
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      options: {
        assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images']
      },
      html: ['<%= config.dist %>/{,*/}*.html'],
      css: ['<%= config.dist %>/styles/{,*/}*.css']
    },

    // The following *-min tasks produce minifies files in the dist folder
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/images',
          src: '{,*/}*.{gif,jpeg,jpg,png}',
          dest: '<%= config.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= config.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          // removeCommentsFromCDATA: true,
          // collapseWhitespace: true,
          // collapseBooleanAttributes: true,
          // removeAttributeQuotes: true,
          // removeRedundantAttributes: true,
          // useShortDoctype: true,
          // removeEmptyAttributes: true,
          // removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>',
          src: '*.html',
          dest: '<%= config.dist %>'
        }]
      }
    },

    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= config.dist %>/styles/main.css': [
    //         '<%= config.app %>/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= config.dist %>/scripts/scripts.js': [
    //         '<%= config.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>',
          dest: '<%= config.dist %>',
          src: [
            '*.{ico,png,txt}',
            'images/{,*/}*.{webp,gif}',
            '{,*/}*.html',
            'styles/{,*/}*.css',
            'styles/fonts/{,*/}*.*',
            '_locales/{,*/}*.json',
          ]
        }]
      }
    },

    // Run some tasks in parallel to speed up build process
    concurrent: {
      chrome: [
        'coffee:chrome',
      ],
      dist: [
        'coffee:dist',
        'imagemin',
        'svgmin'
      ],
      test: [
        'coffee:test',
      ]
    },

    // Auto buildnumber, exclude debug files. smart builds that event pages
    chromeManifest: {
      dist: {
        options: {
          buildnumber: true,
          background: {
            target: 'scripts/background.js',
            exclude: [
              'scripts/chromereload.js'
            ]
          }
        },
        src: '<%= config.app %>',
        dest: '<%= config.dist %>'
      }
    },

    // Compres dist files to package
    compress: {
      dist: {
        options: {
          archive: function() {
            var manifest = grunt.file.readJSON('app/manifest.json');
            return 'package/BTC Address Monitor-' + manifest.version + '.zip';
          }
        },
        files: [{
          expand: true,
          cwd: 'dist/',
          src: ['**'],
          dest: ''
        }]
      }
    }
  });

  grunt.registerTask('debug', function () {
    grunt.task.run([
      'jshint',
      'concurrent:chrome',
      'connect:chrome',
      'watch'
    ]);
  });

  grunt.registerTask('test', [
    'connect:test',
    'mocha'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'chromeManifest:dist',
    'useminPrepare',
    'concurrent:dist',
    'cssmin',
    'concat',
    'uglify',
    'copy',
    'usemin',
    'compress'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'test',
    'build'
  ]);
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sync: {
            main: {
                files: [
                    {cwd: 'src', src: './views/**', dest: 'bin/'},
                    {cwd: 'src', src: ['./public/**', '!./public/**/*.coffee'], dest: 'bin/'}
                ]
            }
        },
        less: {
            development: {
                files: {
                    'bin/public/stylesheets/less_main.css': 'src/public/stylesheets/external/less/main.less'
                }
            }
        },
        watch: {
            app: {
                files: [
                    'src/public/**/*.coffee',
                    'src/components/**/*.coffee',
                    'src/lib/common/**/*.coffee'
                ],
                tasks: ['browserify']
            },
            server: {
                files: [
                    'src/models/**/*.coffee',
                    'src/controllers/**/*.coffee',
                    'src/lib/**/*.coffee'
                ],
                tasks: ['coffee']
            },
            templates: {
                files: [
                    'src/views/**',
                    'src/public/**/*.css',
                    'src/public/**/*.js',
                    'src/public/**/*.ico'
                ],
                tasks: ['sync']
            },
            lessFiles: {
                files: [
                    'src/public/**/*.less'
                ],
                tasks: ['less']
            }
        },
        browserify: {
            dist: {
                files: {
                    'bin/public/js/bundle.js': 'src/public/js/index.coffee'
                },
                options: {
                    transform: ["coffee-reactify"],
                    browserifyOptions: {
                        debug: true,
                        extensions: ['.cjsx', '.coffee']
                    }
                }
            }
        },
        coffee: {
            glob_to_multiple: {
                expand: true,
                flatten: false,
                cwd: 'src',
                src: [
                    './controllers/**/*.coffee',
                    './lib/**/*.coffee',
                    './models/**/*.coffee',
                    './oneoff/**/*.coffee',
                    './routes/**/*.coffee',
                    './tests/**/*.coffee',
                    './index.coffee'
                ],
                dest: 'bin',
                ext: '.js'
            }
        },
        nodemon: {
            dev: {
                script: 'bin/index.js',
                options: {
                    nodeArgs: ['--debug'],
                    watch: ['bin']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-sync');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-nodemon');

    grunt.registerTask('default', ['coffee', 'browserify', 'less', 'sync']);
};<commit_msg>no more 404 from grunt nodemon<commit_after>module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sync: {
            main: {
                files: [
                    {cwd: 'src', src: './views/**', dest: 'bin/'},
                    {cwd: 'src', src: ['./public/**', '!./public/**/*.coffee'], dest: 'bin/'},
                    {
                        cwd: 'node_modules/material-design-icons/sprites',
                        src: './svg-sprite/*.css',
                        dest: 'bin/public/stylesheets/external/'
                    }
                ]
            }
        },
        less: {
            development: {
                files: {
                    'bin/public/stylesheets/less_main.css': 'src/public/stylesheets/external/less/main.less'
                }
            }
        },
        watch: {
            app: {
                files: [
                    'src/public/**/*.coffee',
                    'src/components/**/*.coffee',
                    'src/lib/common/**/*.coffee'
                ],
                tasks: ['browserify']
            },
            server: {
                files: [
                    'src/models/**/*.coffee',
                    'src/controllers/**/*.coffee',
                    'src/lib/**/*.coffee'
                ],
                tasks: ['coffee']
            },
            templates: {
                files: [
                    'src/views/**',
                    'src/public/**/*.css',
                    'src/public/**/*.js',
                    'src/public/**/*.ico'
                ],
                tasks: ['sync']
            },
            lessFiles: {
                files: [
                    'src/public/**/*.less'
                ],
                tasks: ['less']
            }
        },
        browserify: {
            dist: {
                files: {
                    'bin/public/js/bundle.js': 'src/public/js/index.coffee'
                },
                options: {
                    transform: ["coffee-reactify"],
                    browserifyOptions: {
                        debug: true,
                        extensions: ['.cjsx', '.coffee']
                    }
                }
            }
        },
        coffee: {
            glob_to_multiple: {
                expand: true,
                flatten: false,
                cwd: 'src',
                src: [
                    './controllers/**/*.coffee',
                    './lib/**/*.coffee',
                    './models/**/*.coffee',
                    './oneoff/**/*.coffee',
                    './routes/**/*.coffee',
                    './tests/**/*.coffee',
                    './index.coffee'
                ],
                dest: 'bin',
                ext: '.js'
            }
        },
        nodemon: {
            dev: {
                script: 'bin/index.js',
                options: {
                    nodeArgs: ['--debug'],
                    watch: ['bin']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-sync');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-nodemon');

    grunt.registerTask('default', ['coffee', 'browserify', 'less', 'sync']);
};<|endoftext|>


<commit_before>module.exports = function(grunt) {
  var banner = [
    '/**',
    ' * @license',
    ' * <%= pkg.name %> - v<%= pkg.version %>',
    ' * Copyright (c) 2013-2014 burninggramma',
    ' * <%= pkg.repository.url %>',
    ' *',
    ' * Compiled: <%= grunt.template.today("yyyy-mm-dd") %>',
    ' *',
    ' * <%= pkg.name %> is licensed under the <%= pkg.license %> License.',
    ' * <%= pkg.licenseUrl %>',
    ' */',
    ''
  ].join('\n');

  grunt.initConfig({
    pkg : grunt.file.readJSON('package.json'),

    jshint: {
      options: {
        maxlen: 150,
        quotmark: 'single'
      },
      dev: ['Gruntfile.js', 'test/*.js'],
      app:  ['src/*.js', 'index/index.js']
    },

    browserify: {
      '<%= pkg.name %>.js': ['browserify.js']
    },

    uglify: {
      browserified : {
        options: {
          banner: banner,
          beautify: {
            width: 100,
            beautify: true
          }
        },
        files: {
          '<%= pkg.name %>.js':
          ['<%= pkg.name %>.js'],
        }
      },
      build: {
        options: {
          banner: banner
        },
        files: {
          '<%= pkg.name %>.min.js':
          ['<%= pkg.name %>.js'],
        }
      },
    },

    simplemocha : {
      all: { src : ['test/*.js'] },
      options : {
        reporter: 'spec',
        slow: 200,
        timeout: 100
      }
    },

    watch : {
      scripts : {
        files : ['test/*.js', 'src/*.js', 'index/index.js'],
        tasks : ['test']
      }
    }
  });

  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-simple-mocha');

  grunt.registerTask('test',    ['jshint', 'simplemocha']);
  grunt.registerTask('default', [
    'jshint',
    'simplemocha',
    'browserify',
    'uglify:browserified',
    'uglify:build'
  ]);
};
<commit_msg>Minor change in Grunt config.<commit_after>module.exports = function(grunt) {
  var banner = [
    '/**',
    ' * @license',
    ' * <%= pkg.name %> - v<%= pkg.version %>',
    ' * Copyright (c) 2013-2014 burninggramma',
    ' * <%= pkg.repository.url %>',
    ' *',
    ' * Compiled: <%= grunt.template.today("yyyy-mm-dd") %>',
    ' *',
    ' * <%= pkg.name %> is licensed under the <%= pkg.license %> License.',
    ' * <%= pkg.licenseUrl %>',
    ' */',
    ''
  ].join('\n');

  grunt.initConfig({
    pkg : grunt.file.readJSON('package.json'),

    jshint: {
      options: {
        maxlen: 150,
        quotmark: 'single'
      },
      dev: ['Gruntfile.js', 'test/*.js'],
      app:  ['src/*.js', 'index/index.js', 'test/*.js']
    },

    browserify: {
      '<%= pkg.name %>.js': ['browserify.js']
    },

    uglify: {
      browserified : {
        options: {
          banner: banner,
          beautify: {
            width: 100,
            beautify: true
          }
        },
        files: {
          '<%= pkg.name %>.js':
          ['<%= pkg.name %>.js'],
        }
      },
      build: {
        options: {
          banner: banner
        },
        files: {
          '<%= pkg.name %>.min.js':
          ['<%= pkg.name %>.js'],
        }
      },
    },

    simplemocha : {
      all: { src : ['test/*.js'] },
      options : {
        reporter: 'spec',
        slow: 200,
        timeout: 100
      }
    },

    watch : {
      scripts : {
        files : ['test/*.js', 'src/*.js', 'index/index.js'],
        tasks : ['test']
      }
    }
  });

  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-simple-mocha');

  grunt.registerTask('test',    ['jshint', 'simplemocha']);
  grunt.registerTask('default', [
    'jshint',
    'simplemocha',
    'browserify',
    'uglify:browserified',
    'uglify:build'
  ]);
};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-ember-template-compiler');
  grunt.loadNpmTasks('grunt-hashres');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-bower-task');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-microlib');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-compass');

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    karma: {
        ci: { configFile: 'test/js/config/karma.conf.js', singleRun: true, browsers: ['PhantomJS'] },
      unit: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'] },
      unitSpec: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'], reporters: ['spec'] },
      chrome: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'] }
      // e2e: { configFile: 'test/js/config/e2e.js', keepalive: true }, // End-to-end / Functional Tests
      // watch: { configFile: 'test/js/config/unit.js', singleRun:false, autoWatch: true, keepalive: true }
    },
    shell: {
      parse_templates: {
        options: {
          failOnError: true
        },
        command: 'rm -f ./static/build/js/templates/**/*.handlebars ; python ./parse_templates.py -d ./static/build/js/templates'
      }
    },
    watch: {
      scripts: {
        files: ['apps/static/script/**/*.js', 'ember/static/script/templates/*.handlebars'],
        tasks: ['dev'],
        options: {
          interrupt: true,
          debounceDelay: 250
        }
      },
      scss: {
        files: ['bluebottle/common/static/**/*'],
        tasks: ['compass:dev'],
      }
    },
    hashres: {
      options: {
        renameFiles: true
      },
      prod: {
        src: ['static/build/js/lib/deps.min.js'],
        dest: 'ember/person/templates/index.html'
      }
    },
    bower: {
      install: {
        options: {
          targetDir: 'static/build/js/components',
          cleanTargetDir: true,
          cleanBowerDir: true,
          install: true,
          copy: true
        }
      },
      cleanup: {
        options: {
          cleanTargetDir: true,
          cleanBowerDir: true,
          install: false,
          copy: false
        }
      }
    },
    concat: {
      dist: {
        src: [
          'bluebottle/common/static/js/vendor/jquery-1.8.3.js',
          'static/build/js/components/jquery-mockjax/jquery.mockjax.js',
          'static/build/js/components/pavlov/pavlov.js',
          'bluebottle/common/static/js/vendor/handlebars-1.0.0.js',
          'bluebottle/common/static/js/vendor/ember-v1.0.0.js',
          'bluebottle/common/static/js/vendor/ember-data-v0.14.js',
          'bluebottle/common/static/js/vendor/ember-data-drf2-adapter.js',
          'bluebottle/common/static/js/vendor/ember-meta.js',
          'bluebottle/common/static/js/plugins/ember-facebook.js',
          'bluebottle/common/static/js/plugins/ember.hashbang.js',
          'bluebottle/common/static/js/vendor/globalize.js',
          'bluebottle/common/static/jsi18n/en-us/*.js',

          // Bootstrap Stuff
          'bluebottle/common/static/js/vendor/bootstrap/bootstrap-transition.js',
          'bluebottle/common/static/js/vendor/bootstrap/bootstrap-modal.js',
          'bluebottle/common/static/js/vendor/bootstrap/bootstrap-tooltip.js',
          'bluebottle/common/static/js/vendor/bootstrap/bootstrap-popover.js',
          'bluebottle/common/static/js/vendor/bootstrap/bootstrap-typeahead.js',
          'bluebottle/common/static/js/vendor/ember-bootstrap-df3e710.js'
        ],
        dest: 'static/build/js/lib/deps.js'
      },
      test: {
        src: [
          'static/build/js/components/jquery-mockjax/jquery.mockjax.js',
          'static/build/js/components/pavlov/pavlov.js',
          'static/build/js/components/ember-data-factory/dist/ember-data-factory-0.0.1.js',
          // Sion
          'static/build/js/components/sinon/lib/sinon.js',
          'static/build/js/components/sinon/lib/sinon/match.js',
          'static/build/js/components/sinon/lib/sinon/spy.js',
          'static/build/js/components/sinon/lib/sinon/call.js',
          'static/build/js/components/sinon/lib/sinon/behavior.js',
          'static/build/js/components/sinon/lib/sinon/stub.js',
          'static/build/js/components/sinon/lib/sinon/mock.js',
          'static/build/js/components/sinon/lib/sinon/assert.js',
          'static/build/js/components/sinon/lib/sinon/util/event.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_xml_http_request.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_timers.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_server.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_server_with_clock.js',
          'static/build/js/components/sinon/lib/sinon/collection.js',
          'static/build/js/components/sinon/lib/sinon/sandbox.js',
          'static/build/js/components/sinon/lib/sinon/test.js',
          'static/build/js/components/sinon/lib/sinon/test_case.js',
          // 'static/build/js/components/sinon-qunit/lib/sinon-qunit.js'
        ],
        dest: 'static/build/js/lib/test_deps.js'
      },
    },
    uglify: {
      options: {
        // the banner is inserted at the top of the output
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          '<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    emberhandlebars: {
      compile: {
        options: {
          templateName: function(sourceFile) {
            return sourceFile.match(/\/([0-9|a-z|\.|_]+)\.handlebars/i)[1];
          }
        },
        files: ['static/build/js/templates/*.handlebars'],
        dest: 'static/build/js/templates.js'
      }
    },
    compass: {
      // live
      dist: {
        options: {
          httpPath: '/static/assets/',
          basePath: 'bluebottle/common/static',
          sassDir: 'sass',
          cssDir: 'css',
          imagesDir: 'images',
          javascriptsDir: 'js',
          outputStyle: 'compressed',
          relativeAssets: true,
          noLineComments: true,
          environment: 'production',
          raw: 'preferred_syntax = :scss\n' // Use `raw` since it's not directly available
        }
      },
      // development
      dev: {
        options: {
          httpPath: '/static/assets/',
          basePath: 'bluebottle/common/static',
          sassDir: 'sass',
          cssDir: 'css',
          imagesDir: 'images',
          javascriptsDir: 'js',
          outputStyle: 'expanded',
          relativeAssets: true,
          noLineComments: false,
          raw: 'preferred_syntax = :scss\n' // Use `raw` since it's not directly available
        }
      }
    }
  });

  grunt.registerTask('default', ['dev', 'compass:dev']);
  grunt.registerTask('build', ['bower:install', 'concat:dist', 'concat:test']);
  // Add 'shell:parse_templates' and 'emberhandlebars' tasks to dev once it is working
  grunt.registerTask('dev', ['build', 'karma:unit']);
  grunt.registerTask('travis', ['build', 'karma:ci']);
  grunt.registerTask('local', ['dev', 'watch']);
  grunt.registerTask('deploy', ['concat:dist', 'uglify:dist', 'hashres', 'compass:dist']);
}
<commit_msg>fix grunt tests<commit_after>module.exports = function (grunt) {
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-ember-template-compiler');
  grunt.loadNpmTasks('grunt-hashres');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-bower-task');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-microlib');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-compass');

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    karma: {
        ci: { configFile: 'test/js/config/karma.conf.js', singleRun: true, browsers: ['PhantomJS'] },
      unit: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'] },
      unitSpec: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'], reporters: ['spec'] },
      chrome: { configFile: 'test/js/config/karma.conf.js', keepalive: true, browsers: ['Chrome'] }
      // e2e: { configFile: 'test/js/config/e2e.js', keepalive: true }, // End-to-end / Functional Tests
      // watch: { configFile: 'test/js/config/unit.js', singleRun:false, autoWatch: true, keepalive: true }
    },
    shell: {
      parse_templates: {
        options: {
          failOnError: true
        },
        command: 'rm -f ./static/build/js/templates/**/*.handlebars ; python ./parse_templates.py -d ./static/build/js/templates'
      }
    },
    watch: {
      scripts: {
        files: ['apps/static/script/**/*.js', 'ember/static/script/templates/*.handlebars'],
        tasks: ['dev'],
        options: {
          interrupt: true,
          debounceDelay: 250
        }
      },
      scss: {
        files: ['bluebottle/common/static/**/*'],
        tasks: ['compass:dev'],
      }
    },
    hashres: {
      options: {
        renameFiles: true
      },
      prod: {
        src: ['static/build/js/lib/deps.min.js'],
        dest: 'ember/person/templates/index.html'
      }
    },
    bower: {
      install: {
        options: {
          targetDir: 'static/build/js/components',
          cleanTargetDir: true,
          cleanBowerDir: true,
          install: true,
          copy: true
        }
      },
      cleanup: {
        options: {
          cleanTargetDir: true,
          cleanBowerDir: true,
          install: false,
          copy: false
        }
      }
    },
    concat: {
      dist: {
        src: [
          'bluebottle/common/static/js/vendor/jquery-1.8.3.js',
          'static/build/js/components/jquery-mockjax/jquery.mockjax.js',
          'static/build/js/components/pavlov/pavlov.js',

          // Vendor
          'bluebottle/common/static/js/vendor/handlebars-1.0.0.js',
          'bluebottle/common/static/js/vendor/ember-v1.0.0.js',
          'bluebottle/common/static/js/vendor/ember-data-v0.14.js',
          'bluebottle/common/static/js/vendor/ember-data-drf2-adapter.js',
          'bluebottle/common/static/js/vendor/ember-meta.js',
          'bluebottle/common/static/js/vendor/globalize.js',
          'bluebottle/common/static/jsi18n/en-us/*.js',

          // Plugins
          'bluebottle/common/static/js/plugins/ember-facebook.js',
          'bluebottle/common/static/js/plugins/ember.hashbang.js',
          'bluebottle/common/static/js/plugins/bb_modal.js',
        ],
        dest: 'static/build/js/lib/deps.js'
      },
      test: {
        src: [
          'static/build/js/components/jquery-mockjax/jquery.mockjax.js',
          'static/build/js/components/pavlov/pavlov.js',
          'static/build/js/components/ember-data-factory/dist/ember-data-factory-0.0.1.js',
          // Sion
          'static/build/js/components/sinon/lib/sinon.js',
          'static/build/js/components/sinon/lib/sinon/match.js',
          'static/build/js/components/sinon/lib/sinon/spy.js',
          'static/build/js/components/sinon/lib/sinon/call.js',
          'static/build/js/components/sinon/lib/sinon/behavior.js',
          'static/build/js/components/sinon/lib/sinon/stub.js',
          'static/build/js/components/sinon/lib/sinon/mock.js',
          'static/build/js/components/sinon/lib/sinon/assert.js',
          'static/build/js/components/sinon/lib/sinon/util/event.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_xml_http_request.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_timers.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_server.js',
          'static/build/js/components/sinon/lib/sinon/util/fake_server_with_clock.js',
          'static/build/js/components/sinon/lib/sinon/collection.js',
          'static/build/js/components/sinon/lib/sinon/sandbox.js',
          'static/build/js/components/sinon/lib/sinon/test.js',
          'static/build/js/components/sinon/lib/sinon/test_case.js',
          // 'static/build/js/components/sinon-qunit/lib/sinon-qunit.js'
        ],
        dest: 'static/build/js/lib/test_deps.js'
      },
    },
    uglify: {
      options: {
        // the banner is inserted at the top of the output
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          '<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    emberhandlebars: {
      compile: {
        options: {
          templateName: function(sourceFile) {
            return sourceFile.match(/\/([0-9|a-z|\.|_]+)\.handlebars/i)[1];
          }
        },
        files: ['static/build/js/templates/*.handlebars'],
        dest: 'static/build/js/templates.js'
      }
    },
    compass: {
      // live
      dist: {
        options: {
          httpPath: '/static/assets/',
          basePath: 'bluebottle/common/static',
          sassDir: 'sass',
          cssDir: 'css',
          imagesDir: 'images',
          javascriptsDir: 'js',
          outputStyle: 'compressed',
          relativeAssets: true,
          noLineComments: true,
          environment: 'production',
          raw: 'preferred_syntax = :scss\n' // Use `raw` since it's not directly available
        }
      },
      // development
      dev: {
        options: {
          httpPath: '/static/assets/',
          basePath: 'bluebottle/common/static',
          sassDir: 'sass',
          cssDir: 'css',
          imagesDir: 'images',
          javascriptsDir: 'js',
          outputStyle: 'expanded',
          relativeAssets: true,
          noLineComments: false,
          raw: 'preferred_syntax = :scss\n' // Use `raw` since it's not directly available
        }
      }
    }
  });

  grunt.registerTask('default', ['dev', 'compass:dev']);
  grunt.registerTask('build', ['bower:install', 'concat:dist', 'concat:test']);
  // Add 'shell:parse_templates' and 'emberhandlebars' tasks to dev once it is working
  grunt.registerTask('dev', ['build', 'karma:unit']);
  grunt.registerTask('travis', ['build', 'karma:ci']);
  grunt.registerTask('local', ['dev', 'watch']);
  grunt.registerTask('deploy', ['concat:dist', 'uglify:dist', 'hashres', 'compass:dist']);
}
<|endoftext|>