diff --git a/.travis.yml b/.travis.yml index 7747c13..b3c6f89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,5 +9,5 @@ install: script: - source ~/.zshrc - - nvm use 0.12 + - nvm use 4.5.0 - bash test.sh diff --git a/gulp_tasks/common/changelog-script.js b/gulp_tasks/common/changelog-script.js deleted file mode 100644 index 5f76351..0000000 --- a/gulp_tasks/common/changelog-script.js +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env node - -'use strict'; - -var child = require('child_process'); -var fs = require('fs'); -var util = require('util'); -var gutil = require('gulp-util'); -var q = require('q'); -var constants = require('./constants')(); - -var GIT_LOG_CMD = 'git log --grep="%s" -E --format=%s %s..HEAD'; -var GIT_TAG_CMD = 'git describe --tags --abbrev=0'; - -var HEADER_TPL = '\n# %s (%s)\n\n'; -var LINK_ISSUE = '[#%s](' + constants.repository + '/issues/%s)'; -var LINK_COMMIT = '[%s](' + constants.repository + '/commit/%s)'; - -var EMPTY_COMPONENT = '$$'; - -var warn = function() { - gutil.log('WARNING:', util.format.apply(null, arguments)); -}; - -var parseRawCommit = function(raw) { - if (!raw) { - return null; - } - - var lines = raw.split('\n'); - var msg = {}; - var match; - - msg.hash = lines.shift(); - msg.subject = lines.shift(); - msg.closes = []; - msg.breaks = []; - - lines.forEach(function(line) { - match = line.match(/(?:Closes|Fixes)\s#(\d+)/); - if (match) { - msg.closes.push(parseInt(match[1], 10)); - } - }); - - match = raw.match(/BREAKING CHANGE:([\s\S]*)/); - if (match) { - msg.breaking = match[1]; - } - - msg.body = lines.join('\n'); - match = msg.subject.match(/^(.*)\((.*)\)\:\s(.*)$/); - - if (!match || !match[1] || !match[3]) { - warn('Incorrect message: %s %s', msg.hash, msg.subject); - return null; - } - - msg.type = match[1]; - msg.component = match[2]; - msg.subject = match[3]; - - return msg; -}; - -var linkToIssue = function(issue) { - return util.format(LINK_ISSUE, issue, issue); -}; - -var linkToCommit = function(hash) { - return util.format(LINK_COMMIT, hash.substr(0, 8), hash); -}; - -var currentDate = function() { - var now = new Date(); - var pad = function(i) { - var retval = ('0' + i).substr(-2); - return retval; - }; - - return util.format('%d-%s-%s', now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate())); -}; - -var printSection = function(stream, title, section, printCommitLinks) { - printCommitLinks = printCommitLinks === undefined ? true : printCommitLinks; - var components = Object.getOwnPropertyNames(section).sort(); - - if (!components.length) { - return; - } - - stream.write(util.format('\n### %s\n\n', title)); - - components.forEach(function(name) { - var prefix = '-'; - var nested = section[name].length > 1; - - if (name !== EMPTY_COMPONENT) { - if (nested) { - stream.write(util.format('- **%s:**\n', name)); - prefix = ' -'; - } else { - prefix = util.format('- **%s:**', name); - } - } - - section[name].forEach(function(commit) { - if (printCommitLinks) { - stream.write(util.format('%s %s\n (%s', prefix, commit.subject, linkToCommit(commit.hash))); - if (commit.closes.length) { - stream.write(',\n ' + commit.closes.map(linkToIssue).join(', ')); - } - stream.write(')\n'); - } else { - stream.write(util.format('%s %s\n', prefix, commit.subject)); - } - }); - }); - - stream.write('\n'); -}; - -var readGitLog = function(grep, from) { - var deferred = q.defer(); - - child.exec(util.format(GIT_LOG_CMD, grep, '%H%n%s%n%b%n==END==', from), function(code, stdout) { - var commits = []; - - stdout.split('\n==END==\n').forEach(function(rawCommit) { - var commit = parseRawCommit(rawCommit); - if (commit) { - commits.push(commit); - } - }); - - deferred.resolve(commits); - }); - - return deferred.promise; -}; - -var writeChangelog = function(stream, commits, version) { - var sections = { - fix: {}, - feat: {}, - perf: {}, - breaks: {} - }; - - //sections.breaks[EMPTY_COMPONENT] = []; - - commits.forEach(function(commit) { - var section = sections[commit.type]; - var component = commit.component || EMPTY_COMPONENT; - - if (section) { - section[component] = section[component] || []; - section[component].push(commit); - } - - if (commit.breaking) { - sections.breaks[component] = sections.breaks[component] || []; - sections.breaks[component].push({ - subject: util.format('due to %s,\n %s', linkToCommit(commit.hash), commit.breaking), - hash: commit.hash, - closes: [] - }); - } - }); - - stream.write(util.format(HEADER_TPL, version, version, currentDate())); - printSection(stream, 'Bug Fixes', sections.fix); - printSection(stream, 'Features', sections.feat); - printSection(stream, 'Performance Improvements', sections.perf); - printSection(stream, 'Breaking Changes', sections.breaks, false); -}; - -var getPreviousTag = function() { - var deferred = q.defer(); - child.exec(GIT_TAG_CMD, function(code, stdout) { - if (code) { - deferred.reject('Cannot get the previous tag.'); - } else { - deferred.resolve(stdout.replace('\n', '')); - } - }); - return deferred.promise; -}; - -var generate = function(version, from, file) { - - getPreviousTag().then(function(tag) { - //console.log('Reading git log since', tag); - if (from) { - tag = from; - } - readGitLog('^fix|^feat|^perf|BREAKING', tag).then(function(commits) { - //console.log('Parsed', commits.length, 'commits'); - //console.log('Generating changelog to', file || 'stdout', '(', version, ')'); - writeChangelog(file ? fs.createWriteStream(file) : process.stdout, commits, version); - }); - }); -}; - -// publish for testing -exports.parseRawCommit = parseRawCommit; - -// hacky start if not run by jasmine :-D -if (process.argv.join('').indexOf('jasmine-node') === -1) { - generate(process.argv[2], process.argv[3], process.argv[4]); -} diff --git a/gulp_tasks/common/constants.js b/gulp_tasks/common/constants.js deleted file mode 100644 index 46214fe..0000000 --- a/gulp_tasks/common/constants.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -var path = require('path'); - -module.exports = function() { - var cwd = process.env.INIT_CWD || ''; - var clientFolder = 'client'; // the source file folder - var defaultTarget = 'app'; // the name of the app that corresponds to index.html - var constants = { - appname: 'install-mac', - cwd: cwd, - defaultTarget: defaultTarget, - targetName: '{{targetName}}', - targetSuffix: '{{targetSuffix}}', - mode: '{{mode}}', - clientFolder: clientFolder, - repository: 'https://github.com/Yoobic/install-mac', - versionFiles: ['./package.json', './bower.json'], - growly: { - notify: false, - successIcon: path.join(cwd, 'node_modules/karma-growl-reporter/images/success.png'), - failedIcon: path.join(cwd, 'node_modules/karma-growl-reporter/images/failed.png') - }, - cordova: { - src: './' + clientFolder + '/cordova/{{targetName}}', - icon: './' + clientFolder + '/icons/{{targetName}}/icon.png', - platform: 'ios', - iconBackground: '#3D4860' - }, - lint: [ - './' + clientFolder + '/scripts/*/**/*.js', - '!./' + clientFolder + '/scripts/bundle*.js', - './server/**/*.js', 'gulpfile.js', './gulp_tasks/**/*.js', 'karam.conf.js', './test/**/*.js' - ], - fonts: { - src: ['./' + clientFolder + '/fonts/*.*', './' + clientFolder + '/fonts/{{targetName}}/**/*.*'], // you can also add a specific src_appname - dest: 'fonts' - }, - html: { - src: './' + clientFolder + '/index{{targetSuffix}}.html' - }, - images: { - src: [ - './' + clientFolder + '/images/{{targetName}}/**/*', './' + clientFolder + '/images/*.*', - './' + clientFolder + '/icons/{{targetName}}/**/*', './' + clientFolder + '/icons/*.*' - ] - }, - style: { - src: [ - './' + clientFolder + '/styles/main{{targetSuffix}}.scss' - ], - watchFolder: './' + clientFolder + '/styles/**/*.scss', - dest: 'styles', - destName: 'main.css', - sass: { - src: ['./' + clientFolder + '/styles/main{{targetSuffix}}.scss'] - }, - css: { - src: [''] // you can also add a specific src_appname - } - }, - - browserify: { - src: './' + clientFolder + '/scripts/main{{targetSuffix}}.js', - dest: 'scripts', - bundleName: 'bundle.js' - }, - - serve: { - host: 'localhost', //'0.0.0.0', - port: 5000, - open: true, - browser: ['google chrome'], // ['google chrome', 'firefox'], - localtunnel: false // true, false or 'install-mac' - }, - mocha: { - libs: ['server/**/*.js'], - tests: ['test/mocha/**/*.js'], - globals: 'test/mocha/helpers/globals.js', - timeout: 5000 - }, - dist: { - distFolder: './dist/{{targetName}}/{{mode}}' - } - }; - - return constants; -}; diff --git a/gulp_tasks/common/helper.js b/gulp_tasks/common/helper.js deleted file mode 100644 index 25cfc26..0000000 --- a/gulp_tasks/common/helper.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var fs = require('fs'); -var gutil = require('gulp-util'); -var chalk = require('chalk'); -var stripJsonComments = require('strip-json-comments'); -var _ = require('lodash'); -var es = require('event-stream'); -var path = require('path'); - -/** - * Returns true if the target application is mobile - * It checks the presence of a cordova config file - * @param {Object} constants - The constants - * @returns {Boolean} - True if the target app is mobile, false otherwise - */ -var isMobile = exports.isMobile = function(constants) { - return fs.existsSync('./' + constants.clientFolder + '/config' + constants.targetSuffix + '.xml'); -}; - -/** - * A generic handler for require('child_process').exec - * @param {Object} err - The error object - * @param {String} stdout - The stdout string - * @param {String} stderr - The stderr string - */ -var execHandler = function(err, stdout, stderr) { - if (err) { - gutil.log(chalk.red('An error occured executing a command line action')); - } - if (stdout) { - gutil.log(stdout); - } - if (stderr) { - gutil.log(chalk.red('Error: ') + stderr); - } -}; - -var readTextFile = function(filename) { - var body = fs.readFileSync(filename, 'utf8'); - return body; -}; - -var readJsonFile = function(filename) { - var body = readTextFile(filename); - return JSON.parse(stripJsonComments(body)); -}; - -var filterFiles = function(files, extension) { - return _.filter(files, function(file) { - return path.extname(file) === extension; - }); -}; - -/** - * Add new sources in a gulp pipeline - * @returns {Stream} A gulp stream - * @example - * gulp.src('') - * .pipe(addSrc('CHANGELOG.md')) - * .gulp.dest(); - */ -var addSrc = function() { - var pass = es.through(); - return es.duplex(pass, es.merge(gulp.src.apply(gulp.src, arguments), pass)); -}; - -module.exports = { - isMobile: isMobile, - execHandler: execHandler, - readTextFile: readTextFile, - readJsonFile: readJsonFile, - filterFiles: filterFiles, - addSrc: addSrc -}; diff --git a/gulp_tasks/tasks/changelog.js b/gulp_tasks/tasks/changelog.js deleted file mode 100644 index ff95983..0000000 --- a/gulp_tasks/tasks/changelog.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var $ = require('gulp-load-plugins')(); -var changelog = require('conventional-changelog'); -var argv = require('yargs').argv; -var fs = require('fs'); -var q = require('q'); -var path = require('path'); -var gutil = require('gulp-util'); -var exec = $.exec; -var concat = $.concat; -var order = $.order; -var helper = require('../common/helper'); - -var constants = require('../common/constants')(); - -var repository = constants.repository; -if (repository.length <= 0) { - throw new Error('The repository cannot be empty'); -} - -var makeChangelog = function(options) { - var pkg = helper.readJsonFile('./package.json'); - var codename = pkg.codename; - var file = options.standalone ? '' : path.join(__dirname, 'CHANGELOG.md'); - var subtitle = options.subtitle || '"' + codename + '"'; - var from = options.from; - var version = options.version || pkg.version; - var deferred = q.defer(); - changelog({ - repository: repository, - version: version, - subtitle: subtitle, - file: file, - from: from - }, function(err, log) { - if (err) { - deferred.reject(err); - } else { - gutil.log('LOG', log); - deferred.resolve(log); - } - }); - return deferred.promise; -}; - -gulp.task('changelog:conventional', false, function(cb) { - var dest = argv.dest || 'CHANGELOG.md'; - return makeChangelog(argv).then(function(log) { - fs.writeFileSync(dest, log); - cb(); - }); -}); - -gulp.task('changelog:script', false, function(done) { - var pkg = helper.readJsonFile('./package.json'); - var options = argv; - var version = options.version || pkg.version; - var from = options.from || ''; - - gulp.src('') - .pipe(exec('node ./gulp_tasks/common/changelog-script.js ' + version + ' ' + from, { - pipeStdout: true - })) - .pipe(concat('updates.md')) - .pipe(helper.addSrc('CHANGELOG.md')) - .pipe(order(['updates.md', 'CHANGELOG.md'])) - .pipe(concat('CHANGELOG.md')) - .pipe(gulp.dest('./')) - .on('end', done); -}); - -gulp.task('changelog', 'Generates a CHANGELOG.md file.', ['changelog:script']); diff --git a/gulp_tasks/tasks/lint.js b/gulp_tasks/tasks/lint.js deleted file mode 100644 index d864c3c..0000000 --- a/gulp_tasks/tasks/lint.js +++ /dev/null @@ -1,144 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var $ = require('gulp-load-plugins')(); -var map = require('map-stream'); -var combine = require('stream-combiner'); -var chalk = require('chalk'); -var _ = require('lodash'); -var jshint = $.jshint; -var jscs = $.jscs; -var eslint = $.eslint; -var gutil = $.util; -var plumber = $.plumber; -var constants = require('../common/constants')(); - -gulp.task('jshint', false, function() { - var hasError = false; - var hasShown = false; - var successReporter = map(function(file, cb) { - if (!file.jshint.success) { - hasError = true; - } - cb(null, file); - }); - - gulp.src(constants.lint) - .pipe(jshint({ - lookup: true - })) - .pipe(successReporter) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(jshint.reporter('fail')) - .on('error', function() { - gutil.log(chalk.red('Jshint failed')); - throw new Error('jshint failed'); - }) - .pipe(map(function() { - if (!hasError && !hasShown) { - hasShown = true; - gutil.log(chalk.green('All Jshint files passed')); - - } - - })); -}); - -gulp.task('jscs', false, function() { - var hasError = false; - var combined = combine( - gulp.src(constants.lint), - jscs()); - - combined.on('error', function(err) { - hasError = true; - - gutil.log(err.toString()); - gutil.log(chalk.red('Jscs failed')); - - throw new Error('jscs failed'); - }); - - combined.on('end', function() { - if (!hasError) { - gutil.log(chalk.green('All Jscs files passed')); - - } - }); - -}); - -gulp.task('eslint', false, function() { - var hasError = false; - var hasShown = false; - gulp.src(constants.lint) - .pipe(eslint()) - .pipe(eslint.format()) - .on('data', function(file) { - - if (file.eslint.messages && file.eslint.messages.length && _.any(file.eslint.messages, function(item) { - return item.severity === 2; - })) { - hasError = true; - } - }) - .on('end', function() { - if (!hasError && !hasShown) { - hasShown = true; - gutil.log(chalk.green('All EsLint files passed')); - - } else { - gutil.log(chalk.red('EsLint failed')); - - throw new Error('eslint failed'); - } - - }); - -}); - -gulp.task('static', false, function() { - - var status = { - hasShown: false, - hasError: false, - errs: [] - }; - return gulp.src(constants.lint) - .pipe(plumber({ - errorHandler: function(err) { - if (err.plugin === 'gulp-jscs') { - gutil.log(err.toString()); - } - status.hasError = true; - status.errs.push(err); - if (!status.hasShown) { - status.hasShown = true; - - this.emit('end'); - } - } - })) - .pipe(jshint({ - lookup: true - })) - .pipe(jshint.reporter('jshint-stylish')) - .pipe(jscs()) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(jshint.reporter('fail')) - .pipe(eslint.failOnError()) - .on('end', function() { - if (status.hasError) { - gutil.log(chalk.red('lint failed')); - throw new Error('lint_error'); - - } else { - gutil.log(chalk.green('All lint files passed')); - - } - }); - -}); -//gulp.task('lint', ['jshint', 'jscs', 'eslint']); -gulp.task('lint', 'Lint all javascript files.', ['static']); diff --git a/gulp_tasks/tasks/release.js b/gulp_tasks/tasks/release.js deleted file mode 100644 index 2feefd1..0000000 --- a/gulp_tasks/tasks/release.js +++ /dev/null @@ -1,239 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var args = require('yargs').argv; -var $ = require('gulp-load-plugins')(); -var exec = require('child_process').exec; -var bump = $.bump; -var tap = $.tap; -var XML = require('node-jsxml').XML; -var git = $.git; -var gulpif = $.if; -var gutil = require('gulp-util'); -var GitHubApi = require('github'); -var runSequence = require('run-sequence').use(gulp); -var del = require('del'); -var inquirer = require('inquirer'); -var Q = require('q'); -var githubUsername = require('github-username'); -var helper = require('../common/helper'); -var constants = require('../common/constants')(); - -/** - * Bumps any version in the constants.versionFiles - * - * USAGE: - * gulp bump --minor (or --major or --prerelease or --patch which is the default) - * - or - - * gulp bump --ver=1.2.3 - * @param {function} cb - The gulp callback - * @returns {void} - */ -gulp.task('bump', false, function(cb) { - var bumpType = 'patch'; - // major.minor.patch - if (args.patch) { - bumpType = 'patch'; - } - if (args.minor) { - bumpType = 'minor'; - } - if (args.major) { - bumpType = 'major'; - } - if (args.prerelease) { - bumpType = 'prerelease'; - } - bumpType = process.env.BUMP || bumpType; - - var version; - var srcjson = helper.filterFiles(constants.versionFiles, '.json'); - var srcxml = helper.filterFiles(constants.versionFiles, '.xml'); - - // first we bump the json files - gulp.src(srcjson) - .pipe(gulpif(args.ver !== undefined, bump({ - version: args.ver - }), bump({ - type: bumpType - }))) - .pipe(tap(function(file) { - if (!version) { - var json = JSON.parse(String(file.contents)); - version = json.version; - } - })) - .pipe(gulp.dest('./')) - .on('end', function() { - // then after we have the correct value for version, we take care of the xml files - if (srcxml.length > 0) { - gulp.src(srcxml) - .pipe(tap(function(file) { - var xml = new XML(String(file.contents)); - xml.attribute('version').setValue(version); - file.contents = Buffer.concat([new Buffer(xml.toXMLString())]); - })) - .pipe(gulp.dest('./' + constants.clientFolder)) - .on('end', function() { - cb(); - }); - } else { - cb(); - } - - }); - -}); - -gulp.task('commit', false, ['bump'], function() { - var pkg = helper.readJsonFile('./package.json'); - var message = 'docs(changelog): version ' + pkg.version; - return gulp.src(constants.versionFiles) - .pipe(git.add({ - args: '.' - })) - .pipe(git.commit(message)); -}); - -gulp.task('tag', false, ['commit'], function(cb) { - var pkg = helper.readJsonFile('./package.json'); - var v = 'v' + pkg.version; - var message = pkg.version; - git.tag(v, message, function(err) { - if (err) { - throw new Error(err); - } - cb(); - }); -}); - -gulp.task('push', false, ['tag'], function(cb) { - exec('git push origin master && git push origin master --tags', function(err) { - if (err) { - throw new Error(err); - } - cb(); - }); -}); - -// gulp.task('npm', ['push'], function(done) { -// spawm('npm', ['publish'], { -// stdio: 'inherit' -// }).on('close', done); -// }); - -gulp.task('release', 'Publish a new release version.', ['push']); - -// ############GITHUB SECTION######### - -var github = new GitHubApi({ - version: '3.0.0', - protocol: 'https', - timeout: 0 -}); - -var gitGetEmailAsync = Q.nbind(git.exec, git, { - args: 'config --get user.email', - quiet: true -}); - -var githubUsernameAsync = Q.nfbind(githubUsername); - -var inquireAsync = function(result) { - var deferred = Q.defer(); - inquirer.prompt(result.questions, function(answers) { - // only resolving what we need - deferred.resolve({ - username: answers.username || result.username, - password: answers.password - }); - }); - return deferred.promise; -}; - -var githubAuthSetupAndTestAsync = function(result) { - var deferred = Q.defer(); - github.authenticate({ - type: 'basic', - username: result.username, - password: result.password - }); - github.misc.rateLimit({}, function(err, res) { - if (err) { - deferred.reject(gutil.colors.red('Github api failed! ') + ' Response from server: ' + gutil.colors.yellow(err.message)); - deferred.reject(err.message); - } - deferred.resolve(gutil.colors.green('Github authentication successful!')); - }); - return deferred.promise; -}; - -gulp.task('githubAuth', false, function(cb) { - return gitGetEmailAsync() - .then(githubUsernameAsync) - .fail(function() { - return null; - }) - .then(function(username) { - return { - username: username, - questions: [{ - type: 'input', - message: 'Please enter your GitHub username', - name: 'username', - default: username, - validate: function(input) { - return input !== ''; - }, - when: function() { - return username === null; - } - }, { - type: 'password', - message: 'Please enter your GitHub password', - name: 'password', - validate: function(input) { - return input !== ''; - } - }] - }; - }) - .then(inquireAsync) - .then(githubAuthSetupAndTestAsync) - .tap(gutil.log); -}); - -gulp.task('release:createRelease', false, function(cb) { - var pkg = helper.readJsonFile('./package.json'); - var v = 'v' + pkg.version; - var message = pkg.version; - var ownerRepo = constants.repository.split('/').slice(-2); - - return gulp.src('CHANGELOG.md') - .pipe(tap(function(file) { - var body = file.contents.toString(); - body = body.slice(body.indexOf('###')); - var msg = { - owner: ownerRepo[0], - repo: ownerRepo[1], - tag_name: v, - name: v + ': version ' + message, - body: body - }; - github.releases.createRelease(msg, function(err, res) { - if (err) { - gutil.log(gutil.colors.red('Error: ' + err)); - } else { - del('CHANGELOG.md'); - } - }); - })); -}); - -gulp.task('delay', false, function(cb) { - setTimeout(cb, 1000); -}); - -gulp.task('release:full', 'Publish a new release version on GitHub and upload a changelog.', function() { - return runSequence('githubAuth', 'changelog', 'push', 'delay', 'release:createRelease'); -}); diff --git a/package.json b/package.json index 0e8176d..e6df2e7 100644 --- a/package.json +++ b/package.json @@ -27,39 +27,6 @@ }, "homepage": "https://github.com/Yoobic/install-mac", "devDependencies": { - "babel-eslint": "^3.1.23", - "chalk": "^1.0.0", - "conventional-changelog": "0.0.17", - "del": "1.2.0", - "eslint-plugin-nodeca": "^1.0.3", - "event-stream": "^3.3.1", - "github": "0.2.4", - "github-username": "2.0.0", - "gulp": "3.9.0", - "gulp-bump": "0.3.1", - "gulp-concat": "^2.6.0", - "gulp-eslint": "^0.15.0", - "gulp-exec": "2.1.1", - "gulp-git": "1.2.4", - "gulp-help": "1.6.0", - "gulp-if": "1.2.5", - "gulp-jscs": "^1.6.0", - "gulp-jshint": "^1.11.2", - "gulp-load-plugins": "1.0.0-rc.1", - "gulp-mux": "0.2.12", - "gulp-order": "^1.1.1", - "gulp-plumber": "^1.0.1", - "gulp-tap": "0.1.3", - "gulp-util": "3.0.5", - "inquirer": "0.8.5", - "jshint-stylish": "^2.0.1", - "lodash": "3.9.3", - "marked": "0.3.3", - "node-jsxml": "0.6.0", - "q": "1.4.1", - "require-dir": "0.3.0", - "run-sequence": "1.1.0", - "strip-json-comments": "1.0.2", - "yargs": "3.10.0" + "mcfly-semantic-release": "^1.0.16" } }