diff --git a/README.md b/README.md index eec2f93..ee7ff57 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/stevelacy/gulp-bump.png?branch=master)](https://travis-ci.org/stevelacy/gulp-bump) [![NPM version](https://badge.fury.io/js/gulp-bump.png)](http://badge.fury.io/js/gulp-bump) -> Bump any JSON file which supports [semver](http://semver.org/) versioning +> Bump any version in any file which supports [semver](http://semver.org/) versioning ## Information @@ -12,7 +12,7 @@ Description -Bump any Semver version json file +Bump any Semver version in any file with gulp (gulpjs.com) @@ -34,6 +34,9 @@ If you are just requiring a bump for npm, consider using [npm version](https://d ```bash $ npm install gulp-bump --save ``` +#### Breaking changes + +`gulp-bump` v2 supports Any valid semver in any filetype ## Example @@ -60,7 +63,7 @@ gulp.task('bump', function(){ // Defined method of updating: // Semantic major gulp.task('bump', function(){ - gulp.src('./bower.json') + gulp.src('./package.yml') .pipe(bump({type:'major'})) .pipe(gulp.dest('./')); }); @@ -80,14 +83,6 @@ gulp.task('bump', function(){ .pipe(gulp.dest('./')); }); -// Override the tab size for indenting -// (or simply omit to keep the current formatting) -gulp.task('bump', function(){ - gulp.src('./package.json') - .pipe(bump({type:'major', indent: 4 })) - .pipe(gulp.dest('./')); -}); - // Define the key for versioning off gulp.task('bump', function(){ gulp.src('./package.json') @@ -99,11 +94,10 @@ gulp.task('bump', function(){ ``` #### Bumping version and outputting different files ```js - - // `fs` is used instead of require to prevent caching in watch (require caches) - var fs = require('fs'); +var semver = require('semver'); + var getPackageJson = function () { return JSON.parse(fs.readFileSync('./package.json', 'utf8')); }; @@ -139,67 +133,8 @@ gulp.task('default', function(){ ####You can view more examples in the [example folder.](https://github.com/stevelacy/gulp-bump/tree/master/examples) ## Options -### options.type -Semver version type to bump. - - Type: `String` - Default: `patch` - Valid values: `major|minor|patch|prerelease` - -Example: - -```js -.pipe(bump({type: 'Major'}) -.pipe(bump()) //--> defaults to patch -``` - -### options.key -Set the versioning key - - Type: `String` - Default: `version` - -Example: - -```js -.pipe(bump({key: 'appversion'})) -.pipe(bump({key: 'build-version'})) -.pipe(bump({key: 'dev-version', type: 'major'})) -``` -##### Dot notation is supported for nested versions: - -```js - -.pipe(bump({key: {'sublevel.version'}})) - -/* -{ - "sublevel": { - "version": "" - } -} -*/ -``` - -### options.version -Set a specific version to bump to. - - Type: `String` - Default: `null` - -Example: - -```js -.pipe(bump({version: '1.2.3'})) -.pipe(bump({version: '1.0.0-alpha'})) -``` - -### options.indent -Set the amount of spaces for indentation in the result JSON file. - - Type: `Number` - Default: Same as original source file +All options are passed to [bump-regex](https://github.com/stevelacy/bump-regex) ## Versioning #### Versioning Used: [Semantic](http://semver.org/) diff --git a/index.js b/index.js index e58418a..1c90099 100644 --- a/index.js +++ b/index.js @@ -1,86 +1,37 @@ 'use strict'; var path = require('path'); -var gutil = require('gulp-util'); +var pluginError = require('plugin-error'); +var log = require('plugin-log'); var through = require('through2'); +var bump = require('bump-regex'); var semver = require('semver'); -var Dot = require('dot-object'); + +const PLUGIN_NAME = 'gulp-bump'; module.exports = function(opts) { - // set task options - opts = setDefaultOptions(opts); - var content, json, ver; + opts = opts || {}; + if (!opts.type || !semver.inc('0.0.1', opts.type)) { + opts.type = 'patch'; + } return through.obj(function(file, enc, cb) { + if (file.isNull()) { return cb(null, file); } if (file.isStream()) { - return cb(new gutil.PluginError('gulp-bump', 'Streaming not supported')); + return cb(new pluginError(PLUGIN_NAME, 'Streaming not supported')); } - json = file.contents.toString(); - try { - content = JSON.parse(json); - } catch (e) { - return cb(new gutil.PluginError('gulp-bump', 'Problem parsing JSON file', {fileName: file.path, showStack: true})); - } - - // just set a version to the key - if (opts.version) { - if (!content[opts.key]) { - // log to user that key didn't exist before - gutil.log('Creating key', gutil.colors.red(opts.key), 'with version:', gutil.colors.cyan(opts.version)); + opts.str = String(file.contents); + bump(opts, function(err, res) { + if (err) { + return cb(new pluginError(PLUGIN_NAME, err)); } - content[opts.key] = opts.version; - ver = content[opts.key]; - } - else if (semver.valid(content[opts.key])) { - // increment the key with type - content[opts.key] = semver.inc(content[opts.key], opts.type); - ver = content[opts.key]; - } - else if (opts.key.indexOf('.') > -1) { - var dot = new Dot(); - var value = dot.pick(opts.key, content); - ver = semver.inc(value, opts.type); - dot.str(opts.key, ver, content); - } - else { - return cb(new gutil.PluginError('gulp-bump', 'Detected invalid semver ' + opts.key, {fileName: file.path, showStack: false})); - } - file.contents = new Buffer(JSON.stringify(content, null, opts.indent || space(json)) + possibleNewline(json)); - - gutil.log('Bumped \'' + gutil.colors.cyan(path.basename(file.path)) + '\' ' + gutil.colors.magenta(opts.key) + ' to: ' + gutil.colors.cyan(ver)); - cb(null, file); + file.contents = new Buffer(res); + cb(null, file); + }); }); }; - -function setDefaultOptions(opts) { - opts = opts || {}; - opts.key = opts.key || 'version'; - opts.indent = opts.indent || void 0; - // default type bump is patch - if (!opts.type || !semver.inc('0.0.1', opts.type)) { - opts.type = 'patch'; - } - // if passed specific version - validate it - if (opts.version && !semver.valid(opts.version, opts.type)) { - gutil.log('invalid version used as option', gutil.colors.red(opts.version)); - opts.version = null; - } - return opts; -} - -// Preserver new line at the end of a file -function possibleNewline(json) { - var lastChar = (json.slice(-1) === '\n') ? '\n' : ''; - return lastChar; -} - -// Figured out which "space" params to be used for JSON.stringfiy. -function space(json) { - var match = json.match(/^(?:(\t+)|( +))"/m); - return match ? (match[1] ? '\t' : match[2].length) : ''; -} diff --git a/package.json b/package.json index bf8aa3b..04e4904 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,22 @@ { "name": "gulp-bump", "description": "Bump npm versions with Gulp (gulpjs.com)", - "version": "0.2.2", + "version": "2.0.0", "homepage": "http://github.com/stevelacy/gulp-bump", "repository": "git://github.com/stevelacy/gulp-bump.git", "author": "Steve Lacy (http://slacy.me)", "main": "./index.js", "dependencies": { - "dot-object": "^0.6.0", - "gulp-util": "^3.0.3", - "semver": "^4.3.0", - "through2": "^0.5.1" + "plugin-error": "^0.1.2", + "plugin-log": "^0.1.0", + "semver": "^5.0.3", + "through2": "^0.5.1", + "bump-regex": "^1.0.0" }, "devDependencies": { "mocha": "*", - "should": "*" + "should": "*", + "vinyl": "^0.5.3" }, "scripts": { "test": "mocha --reporter spec" @@ -32,10 +34,5 @@ "gulp-version", "gulp-plugin" ], - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/stevelacy/gulp-bump/raw/master/LICENSE" - } - ] + "license": "MIT" } diff --git a/test/dotNotation.js b/test/dotNotation.js deleted file mode 100644 index dca2db4..0000000 --- a/test/dotNotation.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -var gutil = require('gulp-util'); -var should = require('should'); -var bump = require('..'); - -require('mocha'); - - describe('gulp-bump: dot notation', function() { - var dotObject = { - subversion: { - version:'1.2.3' - } - }; - - it('should bump dot notation', function (done) { - var fakeFile = new gutil.File({ - base: 'test/', - cwd: 'test/', - path: 'test/fixtures/package.json', - contents: new Buffer(JSON.stringify(dotObject, null, 2)) - }); - var bumpS = bump({key: 'subversion.version'}); - - bumpS.once('data', function(newFile) { - var json = JSON.parse(String(newFile.contents)); - json.subversion.version.should.equal('1.2.4'); - done(); - }); - bumpS.write(fakeFile); - }); - - it('should bump dot notation with type', function (done) { - var fakeFile = new gutil.File({ - base: 'test/', - cwd: 'test/', - path: 'test/fixtures/package.json', - contents: new Buffer(JSON.stringify(dotObject, null, 2)) - }); - var bumpS = bump({ - key: 'subversion.version', - type: 'minor' - }); - - bumpS.once('data', function(newFile) { - var json = JSON.parse(String(newFile.contents)); - json.subversion.version.should.equal('1.3.0'); - done(); - }); - bumpS.write(fakeFile); - }); - - }); diff --git a/test/errorCases.js b/test/errorCases.js index 3556667..0f2e3e5 100644 --- a/test/errorCases.js +++ b/test/errorCases.js @@ -1,6 +1,6 @@ 'use strict'; -var gutil = require('gulp-util'); +var File = require('vinyl'); var should = require('should'); var bump = require('..'); @@ -8,74 +8,18 @@ require('mocha'); describe('Test failure cases cases in gulp-bump', function() { - it('should fail when not detect a valid semver version', function(done) { - var file = 'some-dir/dummyfile.js'; - var fakeFile = new gutil.File({ - path: file, - contents: new Buffer('{ "version": "0.A.1" }') - }); - - var bumpS = bump(); - - bumpS.on('error', function(e) { - should.exist(e); - e.message.should.equal('Detected invalid semver version'); - e.fileName.should.containEql(file); - return done(); - }); - bumpS.write(fakeFile); - bumpS.end(); - }); - - it('should fail when not detect a valid semver version and wrong key', function(done) { - var file = 'some-dir/dummyfile.js'; - var fakeFile = new gutil.File({ - path: file, - contents: new Buffer('{ "version": "0.0.1" }') - }); - - var bumpS = bump({key: 'appversion'}); - - bumpS.on('error', function(e) { - should.exist(e); - e.message.should.containEql('Detected invalid semver appversion'); - e.fileName.should.containEql(file); - return done(); - }); - bumpS.write(fakeFile); - bumpS.end(); + var fakeFile = new File({ + path: 'some-dir/dummyfile.js', + contents: new Buffer('{ "version": "0.A.0" }') }); - it('should fail when supplied with an invalid JSON', function(done) { - var file = 'some-dir/dummyfile.js'; - var fakeFile = new gutil.File({ - path: file, - contents: new Buffer('{ invalid json oh no!!!}') - }); + it('should fail with invalid semver version', function(done) { var bumpS = bump(); bumpS.on('error', function(e) { should.exist(e); - e.name.should.equal('Error'); - e.message.should.containEql('Problem parsing JSON file'); - e.fileName.should.containEql(file); - return done(); - }); - bumpS.write(fakeFile); - bumpS.end(); - }); - - it('should fallback to defaults when supplied with invalid semver version', function(done) { - var fakeFile = new gutil.File({ - contents: new Buffer('{ "version": "0.0.1" }') - }); - var bumpS = bump({version: '0.A.2'}); - - bumpS.once('data', function(newFile) { - should.exist(newFile); - should.exist(newFile.contents); - JSON.parse(newFile.contents.toString()).version.should.equal('0.0.2'); + e.message.should.equal('Invalid semver'); return done(); }); bumpS.write(fakeFile); diff --git a/test/expected/minor.json b/test/expected/minor.json deleted file mode 100644 index 791835c..0000000 --- a/test/expected/minor.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "gulp-bump", - "description": "Bump npm versions with Gulp (gulpjs.com)", - "version": "0.2.0", - "homepage": "http://github.com/stevelacy/gulp-bump", - "repository": "git://github.com/stevelacy/gulp-bump.git", - "author": "Steve Lacy me@slacy.me (slacy.me)", - "main": "./index.js", - "dependencies": { - "semver": "*" - }, - "devDependencies": { - "mocha": "*", - "should": "*", - "gulp-util": "*" - }, - "scripts": { - "test": "mocha" - }, - "engines": { - "node": ">= 0.8.0" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/stevelacy/gulp-bump/raw/master/LICENSE" - } - ] -} diff --git a/test/expected/minor.yml b/test/expected/minor.yml new file mode 100644 index 0000000..67ed22d --- /dev/null +++ b/test/expected/minor.yml @@ -0,0 +1,2 @@ +version: 1.3.0 +name: 'test' diff --git a/test/fileFixtures.js b/test/fileFixtures.js index bda18da..0404018 100644 --- a/test/fileFixtures.js +++ b/test/fileFixtures.js @@ -1,7 +1,7 @@ 'use strict'; var fs = require('fs'); -var gutil = require('gulp-util'); +var File = require('vinyl'); var should = require('should'); var bump = require('..'); @@ -12,7 +12,7 @@ var fixtureFile = fs.readFileSync('test/fixtures/package.json'); describe('gulp-bump: JSON File fixtures', function() { it('should bump minor by default', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ base: 'test/', cwd: 'test/', path: 'test/fixtures/package.json', @@ -32,7 +32,7 @@ describe('gulp-bump: JSON File fixtures', function() { }); it('should bump major if options.bump = major', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ base: 'test/', cwd: 'test/', path: 'test/fixtures/package.json', @@ -52,11 +52,11 @@ describe('gulp-bump: JSON File fixtures', function() { }); it('should bump minor if options.bump = minor', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ base: 'test/', cwd: 'test/', - path: 'test/fixtures/package.json', - contents: fixtureFile + path: 'test/fixtures/minor.yml', + contents: fs.readFileSync('test/fixtures/minor.yml') }); var bumpS = bump({type: 'minor'}); @@ -65,14 +65,14 @@ describe('gulp-bump: JSON File fixtures', function() { should.exist(newFile); should.exist(newFile.path); should.exist(newFile.contents); - String(newFile.contents).should.equal(fs.readFileSync('test/expected/minor.json', 'utf8')); + String(newFile.contents).should.equal(fs.readFileSync('test/expected/minor.yml', 'utf8')); done(); }); bumpS.write(fakeFile); }); it('should set version to value specified by options.version', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ base: 'test/', cwd: 'test/', path: 'test/fixtures/package.json', @@ -92,7 +92,7 @@ describe('gulp-bump: JSON File fixtures', function() { }); it('should set the key to a custom version', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ base: 'test/', cwd: 'test/', path: 'test/fixtures/key.json', diff --git a/test/fixtures/key.json b/test/fixtures/key.json index 889889b..54f5dde 100644 --- a/test/fixtures/key.json +++ b/test/fixtures/key.json @@ -7,7 +7,7 @@ "author": "Steve Lacy me@slacy.me (slacy.me)", "main": "./index.js", "dependencies": { - "semver":"*" + "semver": "*" }, "devDependencies": { "mocha": "*", diff --git a/test/fixtures/minor.yml b/test/fixtures/minor.yml new file mode 100644 index 0000000..f3b2dba --- /dev/null +++ b/test/fixtures/minor.yml @@ -0,0 +1,2 @@ +version: 1.2.0 +name: 'test' diff --git a/test/fixtures/package.json b/test/fixtures/package.json index c29c53a..e588996 100644 --- a/test/fixtures/package.json +++ b/test/fixtures/package.json @@ -7,12 +7,12 @@ "author": "Steve Lacy me@slacy.me (slacy.me)", "main": "./index.js", "dependencies": { - "semver":"*" + "semver": "*" }, "devDependencies": { "mocha": "*", "should": "*", - "gulp-util":"*" + "gulp-util": "*" }, "scripts": { "test": "mocha" diff --git a/test/index.js b/test/index.js index b5490ee..22c2bb0 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,6 @@ 'use strict'; -var gutil = require('gulp-util'); +var File = require('vinyl'); var should = require('should'); var bump = require('..'); @@ -9,7 +9,7 @@ require('mocha'); describe('gulp-bump: JSON comparison fixtures', function() { it('should bump patch version by default', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ contents: new Buffer('{ "version": "0.0.9" }'), path: 'test/fixtures/test.json' }); @@ -27,7 +27,7 @@ describe('gulp-bump: JSON comparison fixtures', function() { }); it('should bump patch version as default and a key=appversion', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ contents: new Buffer('{ "appversion": "0.0.1" }'), path: 'test/fixtures/test.json' }); @@ -45,7 +45,7 @@ describe('gulp-bump: JSON comparison fixtures', function() { }); it('should ignore invalid type and use type=patch', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ contents: new Buffer('{ "version": "0.0.1" }'), path: 'test/fixtures/test.json' }); @@ -64,7 +64,7 @@ describe('gulp-bump: JSON comparison fixtures', function() { }); it('should set the correct version when supplied', function(done) { - var fakeFile = new gutil.File({ + var fakeFile = new File({ contents: new Buffer('{ "version": "0.0.1" }'), path: 'test/fixtures/test.json' }); @@ -81,36 +81,54 @@ describe('gulp-bump: JSON comparison fixtures', function() { bumpS.end(); }); - it('should set the correct version when supplied even if key did not exist', function(done) { - var fakeFile = new gutil.File({ - contents: new Buffer('{}'), + it('should bump prerelease version', function(done) { + var fakeFile = new File({ + contents: new Buffer('{ "version": "0.0.1-0"}'), path: 'test/fixtures/test.json' }); - var bumpS = bump({version: '0.0.2'}); + var bumpS = bump({type: 'prerelease'}); bumpS.once('data', function(newFile) { should.exist(newFile); should.exist(newFile.contents); - JSON.parse(newFile.contents.toString()).version.should.equal('0.0.2'); + JSON.parse(newFile.contents.toString()).version.should.equal('0.0.1-1'); return done(); }); bumpS.write(fakeFile); bumpS.end(); }); - it('should bump prerelease version', function(done) { - var fakeFile = new gutil.File({ - contents: new Buffer('{ "version": "0.0.1-0"}'), + it('should bump to a prerelease version with a preid', function(done) { + var fakeFile = new File({ + contents: new Buffer('{ "version": "0.0.1"}'), path: 'test/fixtures/test.json' }); - var bumpS = bump({type: 'prerelease'}); + var bumpS = bump({type: 'prerelease', preid : 'alphaWhateverTheYWant'}); bumpS.once('data', function(newFile) { should.exist(newFile); should.exist(newFile.contents); - JSON.parse(newFile.contents.toString()).version.should.equal('0.0.1-1'); + JSON.parse(newFile.contents.toString()).version.should.equal('0.0.2-alphaWhateverTheYWant.0'); + return done(); + }); + bumpS.write(fakeFile); + bumpS.end(); + }); + + it('should bump preid version', function(done) { + var fakeFile = new File({ + contents: new Buffer('{ "version": "0.1.0-zeta.1"}'), + path: 'test/fixtures/test.json' + }); + + var bumpS = bump({type: 'prerelease', preid: 'zeta'}); + + bumpS.once('data', function(newFile) { + should.exist(newFile); + should.exist(newFile.contents); + JSON.parse(newFile.contents.toString()).version.should.equal('0.1.0-zeta.2'); return done(); }); bumpS.write(fakeFile); diff --git a/test/whitespacePreserving.js b/test/whitespacePreserving.js deleted file mode 100644 index f832731..0000000 --- a/test/whitespacePreserving.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -var gutil = require('gulp-util'); -var should = require('should'); -var bump = require('..'); - -require('mocha'); - -describe('gulp-bump: Whitespace preserving', function() { - - var fixtureObj = { version: '1.0.0' }; - var expectedObj = { version: '1.0.1' }; - - var createFile = function (tabType) { - return new gutil.File({ - base: 'test/', - cwd: 'test/', - path: 'test/fixtures/package.json', - contents: new Buffer(JSON.stringify(fixtureObj, null, tabType)) - }); - }; - - it('should preserve tab whitespace settings', function (done) { - var fakeFile = createFile('\t'); - var bumpS = bump(); - - bumpS.once('data', function(newFile) { - String(newFile.contents).should.equal(JSON.stringify(expectedObj, null, '\t')); - done(); - }); - bumpS.write(fakeFile); - }); - - it('should preserve spaces whitespace settings', function (done) { - var fakeFile = createFile(3); - var bumpS = bump(); - - bumpS.once('data', function(newFile) { - String(newFile.contents).should.equal(JSON.stringify(expectedObj, null, 3)); - done(); - }); - bumpS.write(fakeFile); - }); - - it('should override whitespace if indent defined', function (done) { - var fakeFile = createFile(3); - var bumpS = bump({ indent: 2 }); - - bumpS.once('data', function(newFile) { - String(newFile.contents).should.equal(JSON.stringify(expectedObj, null, 2)); - done(); - }); - bumpS.write(fakeFile); - }); - - it('should preserve whitespace at end', function (done) { - var fakeFile = new gutil.File({ - base: 'test/', - cwd: 'test/', - path: 'test/fixtures/package.json', - contents: new Buffer(JSON.stringify(fixtureObj, null, 2) + '\n') - }); - var bumpS = bump(); - - bumpS.once('data', function(newFile) { - String(newFile.contents.slice(-1)).should.equal('\n'); - done(); - }); - bumpS.write(fakeFile); - }); - - it('should not add new line to file', function (done) { - var fakeFile = new gutil.File({ - base: 'test/', - cwd: 'test/', - path: 'test/fixtures/package.json', - contents: new Buffer(JSON.stringify(fixtureObj, null, 2)) - }); - var bumpS = bump(); - - bumpS.once('data', function(newFile) { - String(newFile.contents.slice(-1)).should.not.equal('\n'); - done(); - }); - bumpS.write(fakeFile); - }); -}); -