From 65e5708b3d830eb43d4fbebf760aee03ad7a77a8 Mon Sep 17 00:00:00 2001 From: Joe Bottigliero Date: Mon, 3 Jun 2019 20:39:11 -0500 Subject: [PATCH] feat: custom 'bumpFiles' and 'packageFiles' support --- command.js | 8 ++++++ defaults.js | 13 ++++++++++ index.js | 6 ++--- lib/lifecycles/bump.js | 58 ++++++++++++++++++++++++------------------ test.js | 22 ++++++++++++++++ test/mocks/mix.exs | 12 +++++++++ 6 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 test/mocks/mix.exs diff --git a/command.js b/command.js index c03ce5604..b053cbc8b 100755 --- a/command.js +++ b/command.js @@ -9,6 +9,14 @@ const { START_OF_LAST_RELEASE_PATTERN } = require('./lib/lifecycles/changelog') const yargs = require('yargs') .usage('Usage: $0 [options]') + .option('packageFiles', { + default: defaults.packageFiles, + array: true + }) + .option('bumpFiles', { + default: defaults.bumpFiles, + array: true + }) .option('release-as', { alias: 'r', describe: 'Specify the release type manually (like npm version )', diff --git a/defaults.js b/defaults.js index 202b8f4d4..65ffc61d9 100644 --- a/defaults.js +++ b/defaults.js @@ -23,4 +23,17 @@ Object.keys(spec.properties).forEach(propertyKey => { defaults[propertyKey] = property.default }) +defaults.packageFiles = [ + 'package.json', + 'bower.json', + 'manifest.json', + 'composer.json' +] + +defaults.bumpFiles = defaults.packageFiles.concat([ + 'package-lock.json', + 'npm-shrinkwrap.json', + 'composer.lock' +]) + module.exports = defaults diff --git a/index.js b/index.js index e40339887..464c721ee 100755 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ const printError = require('./lib/print-error') const tag = require('./lib/lifecycles/tag') module.exports = function standardVersion (argv) { + let defaults = require('./defaults') /** * `--message` (`-m`) support will be removed in the next major version. */ @@ -24,8 +25,9 @@ module.exports = function standardVersion (argv) { } } + let args = Object.assign({}, defaults, argv) let pkg - bump.pkgFiles.forEach((filename) => { + args.packageFiles.forEach((filename) => { if (pkg) return let pkgPath = path.resolve(process.cwd(), filename) try { @@ -34,8 +36,6 @@ module.exports = function standardVersion (argv) { } catch (err) {} }) let newVersion - let defaults = require('./defaults') - let args = Object.assign({}, defaults, argv) return Promise.resolve() .then(() => { diff --git a/lib/lifecycles/bump.js b/lib/lifecycles/bump.js index 2661ec029..a177ecf30 100644 --- a/lib/lifecycles/bump.js +++ b/lib/lifecycles/bump.js @@ -51,19 +51,6 @@ Bump.getUpdatedConfigs = function () { return configsToUpdate } -Bump.pkgFiles = [ - 'package.json', - 'bower.json', - 'manifest.json', - 'composer.json' -] - -Bump.lockFiles = [ - 'package-lock.json', - 'npm-shrinkwrap.json', - 'composer.lock' -] - function getReleaseType (prerelease, expectedReleaseType, currentVersion) { if (isString(prerelease)) { if (isInPrerelease(currentVersion)) { @@ -153,17 +140,21 @@ function bumpVersion (releaseAs, currentVersion, args) { } /** - * attempt to update the version # in a collection of common config - * files, e.g., package.json, bower.json. - * + * attempt to update the version number in provided `bumpFiles` * @param args config object - * @param newVersion version # to update to. - * @return {string} + * @param newVersion version number to update to. + * @return void */ function updateConfigs (args, newVersion) { const dotgit = DotGitignore() - Bump.pkgFiles.concat(Bump.lockFiles).forEach(function (filename) { - let configPath = path.resolve(process.cwd(), filename) + args.bumpFiles.forEach(function (bumpFile) { + if (typeof bumpFile !== 'object') { + bumpFile = { + filename: bumpFile + } + } + + let configPath = path.resolve(process.cwd(), bumpFile.filename) try { if (dotgit.ignore(configPath)) return let stat = fs.lstatSync(configPath) @@ -171,13 +162,30 @@ function updateConfigs (args, newVersion) { let data = fs.readFileSync(configPath, 'utf8') let indent = detectIndent(data).indent let newline = detectNewline(data) - let config = JSON.parse(data) - checkpoint(args, 'bumping version in ' + filename + ' from %s to %s', [config.version, newVersion]) - config.version = newVersion - writeFile(args, configPath, stringifyPackage(config, indent, newline)) + + let config + if (!bumpFile.replacer) { + config = JSON.parse(data) + checkpoint(args, 'bumping version in ' + bumpFile.filename + ' from %s to %s', [config.version, newVersion]) + config.version = newVersion + writeFile(args, configPath, stringifyPackage(config, indent, newline)) + } else { + let matches + let replacement = false + while ( + (matches = bumpFile.replacer.exec(data)) !== null && + matches[0] !== replacement + ) { + if (!replacement) { + replacement = matches[0].replace(matches[1], newVersion) + } + data = data.replace(matches[1], newVersion) + } + writeFile(args, configPath, data) + } // flag any config files that we modify the version # for // as having been updated. - configsToUpdate[filename] = true + configsToUpdate[bumpFile.filename] = true } } catch (err) { if (err.code !== 'ENOENT') console.warn(err.message) diff --git a/test.js b/test.js index 4b1371ff7..5324c9975 100644 --- a/test.js +++ b/test.js @@ -922,6 +922,28 @@ describe('standard-version', function () { }) }) + describe('custom `bumpFiles` support', function () { + it('mix.exs', function () { + // @todo This file path is relative to the `tmp` directory, which is a little confusing + fs.copyFileSync('../test/mocks/mix.exs', 'mix.exs') + commit('feat: first commit') + shell.exec('git tag -a v1.0.0 -m "my awesome first release"') + commit('feat: new feature!') + return require('./index')({ + silent: true, + bumpFiles: [ + { + filename: 'mix.exs', + replacer: /version: "(.*)"/ + } + ] + }) + .then(() => { + fs.readFileSync('mix.exs', 'utf-8').should.contain('version: "1.1.0"') + }) + }) + }) + describe('npm-shrinkwrap.json support', function () { beforeEach(function () { writeNpmShrinkwrapJson('1.0.0') diff --git a/test/mocks/mix.exs b/test/mocks/mix.exs new file mode 100644 index 000000000..c48db130c --- /dev/null +++ b/test/mocks/mix.exs @@ -0,0 +1,12 @@ +defmodule StandardVersion.MixProject do + use Mix.Project + def project do + [ + app: :standard_version + version: "0.0.1", + elixir: "~> 1.8", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end +end \ No newline at end of file