1
0
mirror of https://github.com/videojs/video.js.git synced 2025-03-29 22:07:10 +02:00

breaking grunt tasks out into separate files to clean up the main Gruntfile. Also removed unused requires from the primary Gruntfile and making sure they are in the appropriate task file.

This commit is contained in:
Matthew McClure 2015-02-25 16:00:09 -08:00 committed by heff
parent 8e372d7ffd
commit 0b392fa9f5
12 changed files with 422 additions and 361 deletions

@ -1,10 +1,7 @@
module.exports = function(grunt) {
var pkg, s3, semver, version, verParts, uglify, exec;
var pkg, s3, version, verParts;
semver = require('semver');
pkg = grunt.file.readJSON('package.json');
uglify = require('uglify-js');
exec = require('child_process').exec;
verParts = pkg.version.split('.');
version = {
@ -14,6 +11,7 @@ module.exports = function(grunt) {
patch: verParts[2]
};
version.majorMinor = version.major + '.' + version.minor;
grunt.vjsVersion = version;
// loading predefined source order from source-loader.js
// trust me, this is the easist way to do it so far
@ -22,6 +20,8 @@ module.exports = function(grunt) {
var sourceFiles; // Needed to satisfy jshint
eval(grunt.file.read('./build/source-loader.js'));
grunt.sourceFiles = sourceFiles;
// Project configuration.
grunt.initConfig({
pkg: pkg,
@ -117,6 +117,27 @@ module.exports = function(grunt) {
]
}
},
fastly: {
options: {
key: process.env.VJS_FASTLY_API_KEY
},
minor: {
options: {
host: 'vjs.zencdn.net',
urls: [
version.majorMinor+'/*'
]
}
},
patch: {
options: {
host: 'vjs.zencdn.net',
urls: [
version.full+'/*'
]
}
}
},
cssmin: {
minify: {
expand: true,
@ -312,6 +333,22 @@ module.exports = function(grunt) {
commit: true,
message: 'Release %version%',
prefix: 'v'
},
'github-release': {
options: {
repository: 'videojs/video.js',
auth: {
user: process.env.VJS_GITHUB_USER,
password: process.env.VJS_GITHUB_TOKEN
},
release: {
name: version.full,
body: require('chg').find(version.full).changesRaw
}
},
files: {
src: ['dist/video-js-'+ version.full +'.zip'] // Files that you want to attach to Release
}
}
});
@ -333,6 +370,8 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-version');
grunt.loadNpmTasks('grunt-tagrelease');
grunt.loadNpmTasks('chg');
grunt.loadNpmTasks('grunt-fastly');
grunt.loadNpmTasks('grunt-github-releaser');
// grunt.loadTasks('./docs/tasks/');
// grunt.loadTasks('../videojs-doc-generator/tasks/');
@ -344,357 +383,8 @@ module.exports = function(grunt) {
grunt.registerTask('dev', ['jshint', 'less', 'vjslanguages', 'build', 'qunit:source']);
grunt.registerTask('test-qunit', ['pretask', 'qunit']);
// The test task will run `karma:saucelabs` when running in travis,
// when running via a PR from a fork, it'll run qunit tests in phantom using
// karma otherwise, it'll run the tests in chrome via karma
// You can specify which browsers to build with by using grunt-style arguments
// or separating them with a comma:
// grunt test:chrome:firefox # grunt-style
// grunt test:chrome,firefox # comma-separated
grunt.registerTask('test', function() {
var tasks = this.args,
tasksMinified,
tasksMinifiedApi;
grunt.task.run(['pretask']);
if (process.env.TRAVIS_PULL_REQUEST !== 'false') {
grunt.task.run(['karma:phantomjs', 'karma:minified_phantomjs', 'karma:minified_api_phantomjs']);
} else if (process.env.TRAVIS) {
grunt.task.run(['karma:phantomjs', 'karma:minified_phantomjs', 'karma:minified_api_phantomjs']);
//Disabling saucelabs until we figure out how to make it run reliably.
//grunt.task.run([
//'karma:chrome_sl',
//'karma:firefox_sl',
//'karma:safari_sl',
//'karma:ipad_sl',
//'karma:android_sl',
//'karma:ie_sl'
//]);
} else {
// if we aren't running this in a CI, but running it manually, we can
// supply arguments to this task. These arguments are either colon (`:`)
// separated which is the default grunt separator for arguments, or they
// are comma (`,`) separated to make it easier.
// The arguments are the names of which browsers you want. It'll then
// make sure you have the `minified` and `minified_api` for those browsers
// as well.
if (tasks.length === 0) {
tasks.push('chrome');
}
if (tasks.length === 1) {
tasks = tasks[0].split(',');
}
tasksMinified = tasks.slice();
tasksMinifiedApi = tasks.slice();
tasksMinified = tasksMinified.map(function(task) {
return 'minified_' + task;
});
tasksMinifiedApi = tasksMinifiedApi.map(function(task) {
return 'minified_api_' + task;
});
tasks = tasks.concat(tasksMinified).concat(tasksMinifiedApi);
tasks = tasks.map(function(task) {
return 'karma:' + task;
});
grunt.task.run(tasks);
}
});
grunt.registerTask('saucelabs', function() {
var done = this.async();
if (this.args[0] == 'connect') {
exec('curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash',
function(error, stdout, stderr) {
if (error) {
grunt.log.error(error);
return done();
}
grunt.verbose.error(stderr.toString());
grunt.verbose.writeln(stdout.toString());
grunt.task.run(['karma:saucelabs']);
done();
});
} else {
grunt.task.run(['karma:saucelabs']);
done();
}
});
var fs = require('fs');
grunt.registerTask('vttjs', 'prepend vttjs to videojs source files', function() {
var vttjs, vttjsMin, vjs, vjsMin;
// copy the current files to make a novttjs build
grunt.file.copy('build/files/combined.video.js', 'build/files/combined.video.novtt.js');
grunt.file.copy('build/files/minified.video.js', 'build/files/minified.video.novtt.js');
// read in vttjs files
vttjs = grunt.file.read('node_modules/vtt.js/dist/vtt.js');
vttjsMin = grunt.file.read('node_modules/vtt.js/dist/vtt.min.js');
// read in videojs files
vjs = grunt.file.read('build/files/combined.video.js');
vjsMin = grunt.file.read('build/files/minified.video.js');
// write out the concatenated files
grunt.file.write('build/files/combined.video.js', vjs + '\n' + vttjs);
grunt.file.write('build/files/minified.video.js', vjsMin + '\n' + vttjsMin);
});
grunt.registerMultiTask('build', 'Building Source', function(){
// Fix windows file path delimiter issue
var i = sourceFiles.length;
while (i--) {
sourceFiles[i] = sourceFiles[i].replace(/\\/g, '/');
}
// Create a combined sources file. https://github.com/zencoder/video-js/issues/287
var combined = '';
sourceFiles.forEach(function(result){
combined += grunt.file.read(result);
});
// Replace CDN version ref in js. Use major/minor version.
combined = combined.replace(/GENERATED_CDN_VSN/g, version.majorMinor);
combined = combined.replace(/GENERATED_FULL_VSN/g, version.full);
grunt.file.write('build/files/combined.video.js', combined);
// Copy over other files
// grunt.file.copy('src/css/video-js.png', 'build/files/video-js.png');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'build/files/video-js.swf');
// Inject version number into css file
var css = grunt.file.read('build/files/video-js.css');
css = css.replace(/GENERATED_AT_BUILD/g, version.full);
grunt.file.write('build/files/video-js.css', css);
// Copy over font files
grunt.file.recurse('src/css/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'build/files/font/' + filename);
}
});
// Minify CSS
grunt.task.run(['cssmin']);
});
grunt.registerMultiTask('minify', 'Minify JS files using Closure Compiler.', function() {
var done = this.async();
var exec = require('child_process').exec;
var externs = this.data.externs || [];
var dest = this.data.dest;
var filePatterns = [];
// Make sure deeper directories exist for compiler
grunt.file.write(dest, '');
if (this.data.sourcelist) {
filePatterns = filePatterns.concat(grunt.file.read(this.data.sourcelist).split(','));
}
if (this.data.src) {
filePatterns = filePatterns.concat(this.data.src);
}
// Build closure compiler shell command
var command = 'java -jar build/compiler/compiler.jar'
+ ' --compilation_level ADVANCED_OPTIMIZATIONS'
// + ' --formatting=pretty_print'
+ ' --js_output_file=' + dest
+ ' --create_source_map ' + dest + '.map --source_map_format=V3'
+ ' --jscomp_warning=checkTypes --warning_level=VERBOSE'
+ ' --output_wrapper "(function() {%output%})();"';
//@ sourceMappingURL=video.js.map
// Add each js file
grunt.file.expand(filePatterns).forEach(function(file){
command += ' --js='+file;
});
// Add externs
externs.forEach(function(extern){
command += ' --externs='+extern;
});
// Run command
exec(command, { maxBuffer: 500*1024 }, function(err, stdout, stderr){
if (err) {
grunt.warn(err);
done(false);
}
if (stdout) {
grunt.log.writeln(stdout);
}
done();
});
});
grunt.registerTask('dist-copy', 'Assembling distribution', function(){
var css, jsmin, jsdev, cdnjs;
// Manually copy each source file
grunt.file.copy('build/files/minified.video.js', 'dist/video-js/video.js');
grunt.file.copy('build/files/combined.video.js', 'dist/video-js/video.dev.js');
grunt.file.copy('build/files/minified.video.novtt.js', 'dist/video-js/video.novtt.js');
grunt.file.copy('build/files/combined.video.novtt.js', 'dist/video-js/video.novtt.dev.js');
grunt.file.copy('build/files/video-js.css', 'dist/video-js/video-js.css');
grunt.file.copy('build/files/video-js.min.css', 'dist/video-js/video-js.min.css');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'dist/video-js/video-js.swf');
grunt.file.copy('build/demo-files/demo.html', 'dist/video-js/demo.html');
grunt.file.copy('build/demo-files/demo.captions.vtt', 'dist/video-js/demo.captions.vtt');
grunt.file.copy('src/css/video-js.less', 'dist/video-js/video-js.less');
// Copy over font files
grunt.file.recurse('build/files/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'dist/video-js/font/' + filename);
}
});
// Copy over language files
grunt.file.recurse('build/files/lang', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'dist/cdn/lang/' + filename);
grunt.file.copy(absdir, 'dist/video-js/lang/' + filename);
}
});
// ds_store files sometime find their way in
if (grunt.file.exists('dist/video-js/.DS_Store')) {
grunt.file['delete']('dist/video-js/.DS_Store');
}
// CDN version uses already hosted font files
// Minified version only, doesn't need demo files
grunt.file.copy('build/files/minified.video.js', 'dist/cdn/video.js');
grunt.file.copy('build/files/video-js.min.css', 'dist/cdn/video-js.css');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'dist/cdn/video-js.swf');
grunt.file.copy('build/demo-files/demo.captions.vtt', 'dist/cdn/demo.captions.vtt');
grunt.file.copy('build/demo-files/demo.html', 'dist/cdn/demo.html');
// Replace font urls with CDN versions
css = grunt.file.read('dist/cdn/video-js.css');
css = css.replace(/font\//g, '../f/3/');
grunt.file.write('dist/cdn/video-js.css', css);
// Add CDN-specfic JS
jsmin = grunt.file.read('dist/cdn/video.js');
// GA Tracking Pixel (manually building the pixel URL)
cdnjs = uglify.minify('src/js/cdn.js').code.replace('v0.0.0', 'v'+version.full);
grunt.file.write('dist/cdn/video.js', jsmin + cdnjs);
});
grunt.registerTask('cdn-links', 'Update the version of CDN links in docs', function(){
var doc = grunt.file.read('docs/guides/setup.md');
var version = pkg.version;
// remove the patch version to point to the latest patch
version = version.replace(/(\d+\.\d+)\.\d+/, '$1');
// update the version in http://vjs.zencdn.net/4.3/video.js
doc = doc.replace(/(\/\/vjs\.zencdn\.net\/)\d+\.\d+(\.\d+)?/g, '$1'+version);
grunt.file.write('docs/guides/setup.md', doc);
});
grunt.registerTask('dist', 'Creating distribution', ['dist-copy', 'zip:dist']);
grunt.registerTask('next-issue', 'Get the next issue that needs a response', function(){
var done = this.async();
var GitHubApi = require('github');
var open = require('open');
var github = new GitHubApi({
// required
version: '3.0.0',
// optional
debug: true,
protocol: 'https',
// host: 'github.my-GHE-enabled-company.com',
// pathPrefix: '/api/v3', // for some GHEs
timeout: 5000
});
github.issues.repoIssues({
// optional:
// headers: {
// 'cookie': 'blahblah'
// },
user: 'videojs',
repo: 'video.js',
sort: 'updated',
direction: 'asc',
state: 'open',
per_page: 100
}, function(err, res) {
var issueToOpen;
var usersWithWrite = ['heff', 'mmcc'];
var categoryLabels = ['enhancement', 'bug', 'question', 'feature'];
console.log('Number of issues: '+res.length);
// TODO: Find the best way to exclude an issue where a question has been asked of the
// issue owner/submitter that hasn't been answerd yet.
// A stupid simple first step would be to check for the needs: more info label
// and exactly one comment (the question)
// find issues that need categorizing, no category labels
res.some(function(issue){
if (issue.labels.length === 0) {
return issueToOpen = issue; // break
}
// look for category labels
var categorized = issue.labels.some(function(label){
return categoryLabels.indexOf(label.name) >= 0;
});
if (!categorized) {
return issueToOpen = issue; // break
}
});
if (issueToOpen) {
open(issueToOpen.html_url);
return done();
}
// find issues that need confirming or answering
res.some(function(issue){
// look for confirmed label
var confirmed = issue.labels.some(function(label){
return label.name === 'confirmed';
});
// Was exluding questions, but that might leave a lot of people hanging
// var question = issue.labels.some(function(label){
// return label.name === 'question';
// });
if (!confirmed) { // && !question
return issueToOpen = issue; // break
}
});
if (issueToOpen) {
open(issueToOpen.html_url);
return done();
}
grunt.log.writeln('No next issue found');
done();
});
});
// Load all the tasks in the tasks directory
grunt.loadTasks('tasks');
};

@ -202,8 +202,11 @@
[ "git pull upstream stable", "Update the release branch" ],
[ "npm install", "Ensure dependency updates have been installed" ],
[ "grunt test", "Run tests" ],
[ "grunt chg-release:{{ release_type }}", "Update the changelog with the new release" ],
[ "grunt version:{{ release_type }}", "Bump package versions" ],
{ "exec": "grunt vjs-version",
"id": "version", "desc": "Return the current VJS Version from the package.json file"},
[ "grunt chg-release:{{ version }}", "Update the changelog with the new release" ],
[ "grunt clean:dist", "Clean out the dist folder before the build" ],
[ "grunt", "Build the release" ],
[ "git add dist/video-js --force", "Add the (otherwise ignored) release files" ],
[ "grunt vjsdocs", "Rebuild the docs" ],
@ -212,10 +215,11 @@
[ "git push upstream stable", "Push changes to the remote" ],
[ "git push upstream --tags", "Push tags to the remote" ],
[ "npm publish", "Publish to npm" ],
[ "grunt github-release", "Create a new release on Github"],
[ "git checkout master", "Checkout the development branch" ],
[ "git pull upstream master", "Update the development branch" ],
[ "git merge stable", "Merge changes" ],
[ "grunt clean:dist", "Remove built dist files to re-ignore them" ],
[ "grunt clean:dist", "Remove built dist files again to re-ignore them" ],
[ "git add -u", "Add the changes for the removed dist files" ],
[ "git commit -m 'Removed dist files'", "Commit the removed dist files" ],
[ "git push upstream master", "Push development branch changes" ]

@ -26,7 +26,7 @@
},
"devDependencies": {
"calcdeps": "~0.1.7",
"chg": "~0.1.8",
"chg": "~0.2.0",
"contribflow": "~0.2.0",
"github": "~0.1.14",
"grunt": "^0.4.4",
@ -40,10 +40,13 @@
"grunt-contrib-less": "~0.6.4",
"grunt-contrib-qunit": "~0.2.1",
"grunt-contrib-watch": "~0.1.4",
"grunt-fastly": "^0.1.3",
"grunt-github-releaser": "^0.1.17",
"grunt-karma": "^0.8.3",
"grunt-s3": "~0.2.0-alpha",
"grunt-tagrelease": "~0.3.3",
"grunt-version": "~0.3.0",
"grunt-videojs-languages": "0.0.4",
"grunt-zip": "0.10.2",
"karma": "^0.12.14",
"karma-chrome-launcher": "^0.1.3",
@ -58,10 +61,8 @@
"mocha": "~1.8.1",
"open": "0.0.4",
"qunitjs": "~1.14.0",
"semver": "~1.1.4",
"sinon": "~1.9.1",
"uglify-js": "~2.3.6",
"videojs-doc-generator": "0.0.1",
"grunt-videojs-languages": "0.0.4"
"videojs-doc-generator": "0.0.1"
}
}

41
tasks/build.js Normal file

@ -0,0 +1,41 @@
module.exports = function(grunt) {
grunt.registerMultiTask('build', 'Building Source', function(){
// Fix windows file path delimiter issue
var i = grunt.sourceFiles.length;
while (i--) {
grunt.sourceFiles[i] = grunt.sourceFiles[i].replace(/\\/g, '/');
}
// Create a combined sources file. https://github.com/zencoder/video-js/issues/287
var combined = '';
grunt.sourceFiles.forEach(function(result){
combined += grunt.file.read(result);
});
// Replace CDN version ref in js. Use major/minor version.
combined = combined.replace(/GENERATED_CDN_VSN/g, grunt.vjsVersion.majorMinor);
combined = combined.replace(/GENERATED_FULL_VSN/g, grunt.vjsVersion.full);
grunt.file.write('build/files/combined.video.js', combined);
// Copy over other files
// grunt.file.copy('src/css/video-js.png', 'build/files/video-js.png');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'build/files/video-js.swf');
// Inject version number into css file
var css = grunt.file.read('build/files/video-js.css');
css = css.replace(/GENERATED_AT_BUILD/g, grunt.vjsVersion.full);
grunt.file.write('build/files/video-js.css', css);
// Copy over font files
grunt.file.recurse('src/css/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'build/files/font/' + filename);
}
});
// Minify CSS
grunt.task.run(['cssmin']);
});
}

13
tasks/cdn-links.js Normal file

@ -0,0 +1,13 @@
module.exports = function(grunt) {
grunt.registerTask('cdn-links', 'Update the version of CDN links in docs', function(){
var doc = grunt.file.read('docs/guides/setup.md');
var version = pkg.version;
// remove the patch version to point to the latest patch
version = version.replace(/(\d+\.\d+)\.\d+/, '$1');
// update the version in http://vjs.zencdn.net/4.3/video.js
doc = doc.replace(/(\/\/vjs\.zencdn\.net\/)\d+\.\d+(\.\d+)?/g, '$1'+version);
grunt.file.write('docs/guides/setup.md', doc);
});
};

61
tasks/dist-copy.js Normal file

@ -0,0 +1,61 @@
module.exports = function(grunt) {
grunt.registerTask('dist-copy', 'Assembling distribution', function(){
var css, jsmin, jsdev, cdnjs, uglify;
uglify = require('uglify-js');
// Manually copy each source file
grunt.file.copy('build/files/minified.video.js', 'dist/video-js/video.js');
grunt.file.copy('build/files/combined.video.js', 'dist/video-js/video.dev.js');
grunt.file.copy('build/files/minified.video.novtt.js', 'dist/video-js/video.novtt.js');
grunt.file.copy('build/files/combined.video.novtt.js', 'dist/video-js/video.novtt.dev.js');
grunt.file.copy('build/files/video-js.css', 'dist/video-js/video-js.css');
grunt.file.copy('build/files/video-js.min.css', 'dist/video-js/video-js.min.css');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'dist/video-js/video-js.swf');
grunt.file.copy('build/demo-files/demo.html', 'dist/video-js/demo.html');
grunt.file.copy('build/demo-files/demo.captions.vtt', 'dist/video-js/demo.captions.vtt');
grunt.file.copy('src/css/video-js.less', 'dist/video-js/video-js.less');
// Copy over font files
grunt.file.recurse('build/files/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'dist/video-js/font/' + filename);
}
});
// Copy over language files
grunt.file.recurse('build/files/lang', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'dist/cdn/lang/' + filename);
grunt.file.copy(absdir, 'dist/video-js/lang/' + filename);
}
});
// ds_store files sometime find their way in
if (grunt.file.exists('dist/video-js/.DS_Store')) {
grunt.file['delete']('dist/video-js/.DS_Store');
}
// CDN version uses already hosted font files
// Minified version only, doesn't need demo files
grunt.file.copy('build/files/minified.video.js', 'dist/cdn/video.js');
grunt.file.copy('build/files/video-js.min.css', 'dist/cdn/video-js.css');
grunt.file.copy('node_modules/videojs-swf/dist/video-js.swf', 'dist/cdn/video-js.swf');
grunt.file.copy('build/demo-files/demo.captions.vtt', 'dist/cdn/demo.captions.vtt');
grunt.file.copy('build/demo-files/demo.html', 'dist/cdn/demo.html');
// Replace font urls with CDN versions
css = grunt.file.read('dist/cdn/video-js.css');
css = css.replace(/font\//g, '../f/3/');
grunt.file.write('dist/cdn/video-js.css', css);
// Add CDN-specfic JS
jsmin = grunt.file.read('dist/cdn/video.js');
// GA Tracking Pixel (manually building the pixel URL)
cdnjs = uglify.minify('src/js/cdn.js').code.replace('v0.0.0', 'v'+ grunt.vjsVersion.full);
grunt.file.write('dist/cdn/video.js', jsmin + cdnjs);
});
}

55
tasks/minify.js Normal file

@ -0,0 +1,55 @@
module.exports = function(grunt) {
grunt.registerMultiTask('minify', 'Minify JS files using Closure Compiler.', function() {
var done = this.async();
var exec = require('child_process').exec;
var externs = this.data.externs || [];
var dest = this.data.dest;
var filePatterns = [];
// Make sure deeper directories exist for compiler
grunt.file.write(dest, '');
if (this.data.sourcelist) {
filePatterns = filePatterns.concat(grunt.file.read(this.data.sourcelist).split(','));
}
if (this.data.src) {
filePatterns = filePatterns.concat(this.data.src);
}
// Build closure compiler shell command
var command = 'java -jar build/compiler/compiler.jar'
+ ' --compilation_level ADVANCED_OPTIMIZATIONS'
// + ' --formatting=pretty_print'
+ ' --js_output_file=' + dest
+ ' --create_source_map ' + dest + '.map --source_map_format=V3'
+ ' --jscomp_warning=checkTypes --warning_level=VERBOSE'
+ ' --output_wrapper "(function() {%output%})();"';
//@ sourceMappingURL=video.js.map
// Add each js file
grunt.file.expand(filePatterns).forEach(function(file){
command += ' --js='+file;
});
// Add externs
externs.forEach(function(extern){
command += ' --externs='+extern;
});
// Run command
exec(command, { maxBuffer: 500*1024 }, function(err, stdout, stderr){
if (err) {
grunt.warn(err);
done(false);
}
if (stdout) {
grunt.log.writeln(stdout);
}
done();
});
});
}

82
tasks/next-issue.js Normal file

@ -0,0 +1,82 @@
module.exports = function(grunt) {
grunt.registerTask('next-issue', 'Get the next issue that needs a response', function(){
var done = this.async();
var GitHubApi = require('github');
var open = require('open');
var github = new GitHubApi({
// required
version: '3.0.0',
// optional
debug: true,
protocol: 'https',
// host: 'github.my-GHE-enabled-company.com',
// pathPrefix: '/api/v3', // for some GHEs
timeout: 5000
});
github.issues.repoIssues({
// optional:
// headers: {
// 'cookie': 'blahblah'
// },
user: 'videojs',
repo: 'video.js',
sort: 'updated',
direction: 'asc',
state: 'open',
per_page: 100
}, function(err, res) {
var issueToOpen;
var usersWithWrite = ['heff', 'mmcc'];
var categoryLabels = ['enhancement', 'bug', 'question', 'feature'];
console.log('Number of issues: '+res.length);
// TODO: Find the best way to exclude an issue where a question has been asked of the
// issue owner/submitter that hasn't been answerd yet.
// A stupid simple first step would be to check for the needs: more info label
// and exactly one comment (the question)
// find issues that need categorizing, no category labels
res.some(function(issue){
if (issue.labels.length === 0) {
return issueToOpen = issue; // break
}
// look for category labels
var categorized = issue.labels.some(function(label){
return categoryLabels.indexOf(label.name) >= 0;
});
if (!categorized) {
return issueToOpen = issue; // break
}
});
if (issueToOpen) {
open(issueToOpen.html_url);
return done();
}
// find issues that need confirming or answering
res.some(function(issue){
// look for confirmed label
var confirmed = issue.labels.some(function(label){
return label.name === 'confirmed';
});
// Was exluding questions, but that might leave a lot of people hanging
// var question = issue.labels.some(function(label){
// return label.name === 'question';
// });
if (!confirmed) { // && !question
return issueToOpen = issue; // break
}
});
if (issueToOpen) {
open(issueToOpen.html_url);
return done();
}
grunt.log.writeln('No next issue found');
done();
});
});
}

24
tasks/saucelabs.js Normal file

@ -0,0 +1,24 @@
module.exports = function(grunt) {
grunt.registerTask('saucelabs', function() {
var exec = require('child_process').exec;
var done = this.async();
if (this.args[0] == 'connect') {
exec('curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash',
function(error, stdout, stderr) {
if (error) {
grunt.log.error(error);
return done();
}
grunt.verbose.error(stderr.toString());
grunt.verbose.writeln(stdout.toString());
grunt.task.run(['karma:saucelabs']);
done();
});
} else {
grunt.task.run(['karma:saucelabs']);
done();
}
});
}

63
tasks/test.js Normal file

@ -0,0 +1,63 @@
module.exports = function(grunt) {
// The test task will run `karma:saucelabs` when running in travis,
// when running via a PR from a fork, it'll run qunit tests in phantom using
// karma otherwise, it'll run the tests in chrome via karma
// You can specify which browsers to build with by using grunt-style arguments
// or separating them with a comma:
// grunt test:chrome:firefox # grunt-style
// grunt test:chrome,firefox # comma-separated
grunt.registerTask('test', function() {
var tasks = this.args,
tasksMinified,
tasksMinifiedApi;
grunt.task.run(['pretask']);
if (process.env.TRAVIS_PULL_REQUEST !== 'false') {
grunt.task.run(['karma:phantomjs', 'karma:minified_phantomjs', 'karma:minified_api_phantomjs']);
} else if (process.env.TRAVIS) {
grunt.task.run(['karma:phantomjs', 'karma:minified_phantomjs', 'karma:minified_api_phantomjs']);
//Disabling saucelabs until we figure out how to make it run reliably.
//grunt.task.run([
//'karma:chrome_sl',
//'karma:firefox_sl',
//'karma:safari_sl',
//'karma:ipad_sl',
//'karma:android_sl',
//'karma:ie_sl'
//]);
} else {
// if we aren't running this in a CI, but running it manually, we can
// supply arguments to this task. These arguments are either colon (`:`)
// separated which is the default grunt separator for arguments, or they
// are comma (`,`) separated to make it easier.
// The arguments are the names of which browsers you want. It'll then
// make sure you have the `minified` and `minified_api` for those browsers
// as well.
if (tasks.length === 0) {
tasks.push('chrome');
}
if (tasks.length === 1) {
tasks = tasks[0].split(',');
}
tasksMinified = tasks.slice();
tasksMinifiedApi = tasks.slice();
tasksMinified = tasksMinified.map(function(task) {
return 'minified_' + task;
});
tasksMinifiedApi = tasksMinifiedApi.map(function(task) {
return 'minified_api_' + task;
});
tasks = tasks.concat(tasksMinified).concat(tasksMinifiedApi);
tasks = tasks.map(function(task) {
return 'karma:' + task;
});
grunt.task.run(tasks);
}
});
};

7
tasks/vjs-version.js Normal file

@ -0,0 +1,7 @@
module.exports = function(grunt) {
grunt.registerTask('vjs-version', function() {
var version = grunt.vjsVersion.full;
grunt.log.writeln(version);
return version;
});
}

20
tasks/vtt.js Normal file

@ -0,0 +1,20 @@
module.exports = function(grunt) {
grunt.registerTask('vttjs', 'prepend vttjs to videojs source files', function() {
var vttjs, vttjsMin, vjs, vjsMin;
// copy the current files to make a novttjs build
grunt.file.copy('build/files/combined.video.js', 'build/files/combined.video.novtt.js');
grunt.file.copy('build/files/minified.video.js', 'build/files/minified.video.novtt.js');
// read in vttjs files
vttjs = grunt.file.read('node_modules/vtt.js/dist/vtt.js');
vttjsMin = grunt.file.read('node_modules/vtt.js/dist/vtt.min.js');
// read in videojs files
vjs = grunt.file.read('build/files/combined.video.js');
vjsMin = grunt.file.read('build/files/minified.video.js');
// write out the concatenated files
grunt.file.write('build/files/combined.video.js', vjs + '\n' + vttjs);
grunt.file.write('build/files/minified.video.js', vjsMin + '\n' + vttjsMin);
});
};