diff --git a/.eslintrc b/.eslintrc index e67f987..eaadcdb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -65,7 +65,12 @@ "Runner": false, "Svg": false, "Metrics": false, - "Example": false + "Example": false, + "__MATTER_VERSION__": false, + "jest": false, + "test": false, + "expect": false, + "describe": false }, "extends": "eslint:recommended" } diff --git a/.gitignore b/.gitignore index b409461..baa4e68 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,11 @@ build/matter-dev.js build/matter-dev.min.js demo/js/lib/matter-dev.js demo/js/Examples.js +demo/js/Examples.min.js examples/build test/browser/diffs test/browser/refs test/node/diffs -test/node/refs \ No newline at end of file +test/node/refs +__snapshots__ +__compare__ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index fb11589..307b7ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,9 @@ language: node_js sudo: false node_js: - "node" -before_install: - - npm install -g gulp - - mkdir travis-phantomjs - - wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 - - tar -xvf $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -C $PWD/travis-phantomjs - - export PATH=$PWD/travis-phantomjs:$PATH -install: npm install \ No newline at end of file +install: + - npm install +script: + - npm run lint + - npm run test + - npm run build \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15d0454..242a4bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,22 +2,39 @@ ## License Agreement -When providing any contributions, you must agree and be legally entitled to provide them for use and distribution in the project under the same terms as the [license](https://github.com/liabru/matter-js/blob/master/LICENSE), otherwise they can not be accepted. - -## Building - -To build you must first install [node.js](http://nodejs.org/) and [gulp](http://gulpjs.com/), then run - - npm install - -This will install the required build dependencies, then run - - gulp dev - -which is a task that builds the `matter-dev.js` file, spawns a development server and opens `http://localhost:8000/demo/index.html` in your browser. Any changes you make to the source will automatically rebuild `matter-dev.js` and reload your browser. +By providing any kind of contribution to this project, **you must agree and be legally entitled** to provide them for use and distribution as a part of this project **wholly under the same terms as in the original included [license](https://github.com/liabru/matter-js/blob/master/LICENSE)**. ## Contributions -Contributions by pull request are welcome! Please ensure they follow the same style and architecture as the rest of the code. You should run `gulp test` and ensure there are no reported errors. Please do not include any changes to the files in the `build` directory. All contributors must agree to the license agreement described at the beginning of this document. +Contributions by pull request or issues are welcome. Please ensure they follow the same style and architecture as the rest of the code. Use `npm run lint` before submitting. Please **do not include** any changes to the files in the `build` directory. -If you'd like to contribute but not sure what to work on, feel free to get in touch. \ No newline at end of file +Before contributing please read the license agreement described at the beginning of this document. + +## Building + +To build you must first install [node.js](http://nodejs.org), then run + + npm install + +which will install the required build dependencies, then run + + npm run dev + +which will run the development server and opens `http://localhost:8000/` in your browser. Any changes you make to the source will automatically rebuild and reload the page. + +## Commands + +The following development commands can be run at the terminal + +- **npm run dev** +runs development server +- **npm run build** +creates a release build +- **npm run lint** +runs the linter +- **npm run test** +runs the tests +- **npm run compare** +compares the output of examples for current source against release build +- **npm run doc** +builds the documentation diff --git a/Gulpfile.js b/Gulpfile.js index 54b4674..cd7bccb 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -1,55 +1,83 @@ -var gulp = require('gulp'); -var uglify = require('gulp-uglify'); -var rename = require('gulp-rename'); -var header = require('gulp-header'); -var eslint = require('gulp-eslint'); -var bump = require('gulp-bump'); -var changelog = require('gulp-conventional-changelog'); -var tag = require('gulp-tag-version'); -var release = require('gulp-github-release'); -var sequence = require('run-sequence'); -var gutil = require('gulp-util'); -var replace = require('gulp-replace'); -var webserver = require('gulp-webserver'); -var concat = require('gulp-concat'); -var preprocess = require('gulp-preprocess'); -var browserify = require('browserify'); -var derequire = require('gulp-derequire'); -var transform = require('vinyl-transform'); -var through2 = require('through2'); -var pkg = require('./package.json'); -var clone = require('gulp-clone'); -var livereload = require('connect-livereload'); -var es = require('event-stream'); -var path = require('path'); -var fs = require('fs'); -var watchify = require('watchify'); -var extend = require('util')._extend; -var exec = require('child_process').exec; -var buildDirectory = 'build'; -var server; +/* eslint-env es6 */ +"use strict"; -gulp.task('default', ['build:dev']); +const gulp = require('gulp'); +const bump = require('gulp-bump'); +const changelog = require('gulp-conventional-changelog'); +const tag = require('gulp-tag-version'); +const sequence = require('run-sequence'); +const gutil = require('gulp-util'); +const pkg = require('./package.json'); +const exec = require('child_process').exec; -gulp.task('dev', function(callback) { - sequence('watch', 'serve', callback); +const shellExec = (command, callback) => { + const args = process.argv.slice(3).join(' '), + proc = exec(command + ' ' + args, (err, stdout, stderr) => { + callback(err, stdout, stderr, proc); + }); + + proc.stdout.on('data', data => process.stdout.write(data)); + proc.stderr.on('data', data => process.stderr.write(data)); +}; + +const shell = command => (callback => { shellExec(command, callback); }); + +const hint = command => (callback => { + gutil.log(gutil.colors.red('Error'), 'use', gutil.colors.yellow(command), 'instead.'); + callback(); }); -gulp.task('release', function(callback) { - shell('git status --porcelain', function(err, stdout) { +gulp.task('default', hint('npm run build')); +gulp.task('dev', hint('npm run dev')); +gulp.task('build', hint('npm run build')); +gulp.task('test', hint('npm run test')); +gulp.task('lint', hint('npm run lint')); + +gulp.task('doc', callback => { + shellExec(`yuidoc --config yuidoc.json --project-version ${pkg.version}`, callback); +}); + +gulp.task('bump', () => { + return gulp.src(['package.json', 'bower.json']) + .pipe(bump({ type: process.argv[4] || 'minor' })) + .pipe(gulp.dest('.')); +}); + +gulp.task('tag', () => { + return gulp.src('package.json') + .pipe(tag({ prefix: '' })); +}); + +gulp.task('changelog', () => { + return gulp.src('CHANGELOG.md') + .pipe(changelog()) + .pipe(gulp.dest('.')); +}); + +gulp.task('release', callback => { + shellExec('git status --porcelain', (err, stdout) => { if (stdout && stdout.trim()) { throw new gutil.PluginError({ plugin: 'release', message: 'cannot build release as there are uncomitted changes' }); } else { - sequence('test', 'bump', 'reload', 'build:release', 'doc', 'changelog', callback); + sequence( + 'release:lint', 'bump', 'release:build', 'release:test', + 'doc', 'changelog', callback + ); } }); }); -gulp.task('release:push', function(callback) { - shell('git status --porcelain', function(err, stdout) { +gulp.task('release:lint', shell('npm run lint')); +gulp.task('release:build', shell('npm run build')); +gulp.task('release:test', shell('TEST_BUILD=true npm run test')); +gulp.task('release:push:git', shell('git push origin && git push origin --tags')); +gulp.task('release:push:npm', shell('npm publish')); + +gulp.task('release:push', callback => { + shellExec('git status --porcelain', (err, stdout) => { if (stdout && stdout.trim()) { throw new gutil.PluginError({ plugin: 'release', @@ -60,254 +88,3 @@ gulp.task('release:push', function(callback) { } }); }); - -gulp.task('release:push:github', function(callback) { - return gulp.src([ - 'CHANGELOG.md', - 'LICENSE', - buildDirectory + '/matter.min.js', - buildDirectory + '/matter.js' - ]).pipe(release({ - owner: 'liabru', - repo: pkg.name, - tag: pkg.version, - name: 'Matter.js ' + pkg.version - })); -}); - -gulp.task('release:push:git', function(callback) { - shell('git push', callback); -}); - -gulp.task('release:push:npm', function(callback) { - shell('npm publish', callback); -}); - -gulp.task('build:dev', function() { - return build(extend(extend({}, pkg), { version: pkg.version + '-dev' })); -}); - -gulp.task('build:edge', function() { - return build(extend(extend({}, pkg), { version: pkg.version + '-alpha' })); -}); - -gulp.task('build:release', function() { - return build(extend(extend({}, pkg), { version: pkg.version })); -}); - -gulp.task('build:examples', function() { - var options = extend(extend({}, pkg), { version: pkg.version + '-dev' }); - options.name = options.name + '-examples'; - options.date = options.date || new Date().toISOString().slice(0, 10); - options.author = '@liabru'; - - return gulp.src('examples/**/*.js') - .pipe(concat('examples.js')) - .pipe(header(banner, { context: options })) - .pipe(gulp.dest('examples/build')); -}); - -gulp.task('watch', function() { - var b = browserify({ - entries: ['src/module/main.js'], - standalone: 'Matter', - plugin: [watchify] - }); - - var bundle = function() { - gutil.log('Updated bundle build/matter-dev.js'); - b.bundle() - .on('error', function(err) { - gutil.log('ERROR', err.message); - this.emit('end'); - }) - .pipe(through2({ objectMode: true }, function(chunk, encoding, callback) { - return callback( - null, - chunk.toString().replace(/@@VERSION@@/g, pkg.version + '-dev') - ); - })) - .pipe(fs.createWriteStream('build/matter-dev.js')); - }; - - b.on('update', bundle); - bundle(); -}); - -gulp.task('bump', function() { - return gulp.src(['package.json', 'bower.json']) - .pipe(bump({ type: process.argv[4] || 'minor' })) - .pipe(gulp.dest('.')); -}); - -gulp.task('reload', function(callback) { - delete require.cache[require.resolve('./package.json')]; - pkg = require('./package.json'); - callback(); -}); - -gulp.task('tag', function() { - return gulp.src('package.json') - .pipe(tag({ prefix: '' })); -}); - -gulp.task('changelog', function () { - return gulp.src('CHANGELOG.md') - .pipe(changelog()) - .pipe(gulp.dest('.')); -}); - -gulp.task('serve', function() { - serve(false); -}); - -gulp.task('serve:test', function() { - serve(true); -}); - -gulp.task('serve:stop', function() { - if (server) { - try { - server.emit('kill'); - } catch (e) {} // eslint-disable-line no-empty - gutil.log('Web server stopped'); - } -}); - -gulp.task('test', function(callback) { - // TODO: fix tests by switching to nightmare instead of phantom - // sequence('serve:test', 'lint', 'build:dev', 'test:browser', 'test:node', 'serve:stop', callback); - sequence('lint', callback); -}); - -gulp.task('test:browser', function(callback) { - shell('phantomjs test/browser/TestDemo.js', callback); -}); - -gulp.task('test:node', function(callback) { - shell('node test/node/TestDemo.js', callback); -}); - -gulp.task('lint', function() { - return gulp.src([ - 'src/**/*.js', - 'demo/js/*.js', - 'examples/*.js', - 'test/browser/TestDemo.js', - 'test/node/TestDemo.js', - 'Gulpfile.js' - ]) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); -}); - -gulp.task('doc', function(callback) { - var options = { - paths: ['src'], - themedir: 'matter-doc-theme', - outdir: 'doc/build', - linkNatives: true, - project: { - name: pkg.name + ' ' + pkg.version + ' Physics Engine API Docs', - description: pkg.description, - version: pkg.version, - url: pkg.homepage - } - }; - - var Y = require('yuidocjs'); - var json = new Y.YUIDoc(options).run(); - json.project = options.project; - - var builder = new Y.DocBuilder(options, json); - builder.compile(callback); -}); - -var serve = function(isTest) { - process.on('uncaughtException', function(err) { - if (err.errno === 'EADDRINUSE') { - gutil.log('Server already running (or port is otherwise in use)'); - } - }); - - server = gulp.src('.') - .pipe(webserver({ - host: '0.0.0.0', - livereload: { - enable: !isTest, - filter: function(filename) { - return filename.match(/build|demo/); - } - }, - middleware: livereload(), - open: isTest ? false : 'http://localhost:8000/demo/index.html', - directoryListing: true - })); -}; - -var build = function(options) { - var isDev = options.version.indexOf('-dev') !== -1, - filename = buildDirectory + (isDev ? '/matter-dev' : '/matter'), - dest = filename + '.js', - destMin = filename + '.min.js'; - - options.date = options.date || new Date().toISOString().slice(0, 10); - options.author = '@liabru'; - - gutil.log('Building', filename, options.date); - - var compiled = gulp.src(['src/module/main.js']) - .pipe(through2.obj(function(file, enc, next){ - browserify(file.path, { standalone: 'Matter' }) - .bundle(function(err, res){ - file.contents = res; - next(null, file); - }); - })) - .pipe(derequire()) - .pipe(replace('@@VERSION@@', options.version)); - - if (!isDev) { - compiled.pipe(preprocess({ context: { DEBUG: false } })); - } - - var build = compiled.pipe(clone()) - .pipe(header(banner + '\n' + license + '\n\n', { context: options })) - .pipe(rename(dest)) - .pipe(gulp.dest('.')); - - var buildMin = compiled.pipe(clone()) - .pipe(uglify({ output: { max_line_len: 1000 } })) - .pipe(header(banner, { context: options })) - .pipe(rename(destMin)) - .pipe(gulp.dest('.')); - - return es.merge(build, buildMin); -}; - -var shell = function(command, callback) { - var args = process.argv.slice(3).join(' '), - proc = exec(command + ' ' + args, function(err, stdout, stderr) { - callback(err, stdout, stderr, proc); - }); - - proc.stdout.on('data', function(data) { - process.stdout.write(data); - }); - - proc.stderr.on('data', function(data) { - process.stderr.write(data); - }); -}; - -var license = fs.readFileSync('src/module/license.js'); - -var banner = [ - '/**', - '* <%= context.name %> <%= context.version %> by <%= context.author %> <%= context.date %>', - '* <%= context.homepage %>', - '* License <%= context.license %>', - '*/', - '' -].join('\n'); diff --git a/README.md b/README.md index be9b583..9c8fc2f 100644 --- a/README.md +++ b/README.md @@ -111,15 +111,14 @@ See how others are using matter.js physics ### Install -Download the [edge build (master)](https://github.com/liabru/matter-js/blob/master/build/matter.js) or get a [stable release](https://github.com/liabru/matter-js/releases) and include the script in your web page: +You can install using package managers [npm](https://www.npmjs.org/package/matter-js) and [Yarn](https://yarnpkg.com/) using: + + npm install matter-js + +Alternatively you can download a [stable release](https://github.com/liabru/matter-js/tags) or try the latest experimental [alpha build](https://github.com/liabru/matter-js/tree/master/build) (master) and include the script in your web page: -You can also install using the package managers [Bower](http://bower.io/search/?q=matter-js) and [NPM](https://www.npmjs.org/package/matter-js). - - bower install matter-js - npm install matter-js - ### Usage Visit the [Getting started](https://github.com/liabru/matter-js/wiki/Getting-started) wiki page for a minimal usage example which should work in both browsers and Node.js. @@ -149,13 +148,13 @@ See the [API Documentation](http://brm.io/matter-js/docs/) and the [wiki](https: ### Building and Contributing -To build you must first install [node.js](http://nodejs.org/) and [gulp](http://gulpjs.com/), then run +To build you must first install [node.js](http://nodejs.org/), then run npm install This will install the required build dependencies, then run - gulp dev + npm run dev to spawn a development server. For information on contributing see [CONTRIBUTING.md](https://github.com/liabru/matter-js/blob/master/CONTRIBUTING.md). diff --git a/demo/index.html b/demo/index.html index 95f4b7b..b6898cf 100644 --- a/demo/index.html +++ b/demo/index.html @@ -12,21 +12,21 @@