diff --git a/lib/lifecycles/bump.js b/lib/lifecycles/bump.js index a177ecf30..deaf0831c 100644 --- a/lib/lifecycles/bump.js +++ b/lib/lifecycles/bump.js @@ -3,8 +3,6 @@ const chalk = require('chalk') const checkpoint = require('../checkpoint') const conventionalRecommendedBump = require('conventional-recommended-bump') -const detectIndent = require('detect-indent') -const detectNewline = require('detect-newline') const figures = require('figures') const fs = require('fs') const DotGitignore = require('dotgitignore') @@ -12,8 +10,8 @@ const path = require('path') const presetLoader = require('../preset-loader') const runLifecycleScript = require('../run-lifecycle-script') const semver = require('semver') -const stringifyPackage = require('stringify-package') const writeFile = require('../write-file') +const JSON_BUMP_FILES = require('../../defaults').bumpFiles let configsToUpdate = {} @@ -139,6 +137,19 @@ function bumpVersion (releaseAs, currentVersion, args) { }) } +function getUpdaterByFileName (filename) { + if (JSON_BUMP_FILES.includes(filename)) { + return require('../package-files/json') + } + try { + return require(`../package-files/${filename}.js`) + } catch (err) { + throw Error( + `Unsupported file (${filename}) provided for updating – please provide a custom updater.` + ) + } +} + /** * attempt to update the version number in provided `bumpFiles` * @param args config object @@ -153,40 +164,34 @@ function updateConfigs (args, newVersion) { filename: bumpFile } } - let configPath = path.resolve(process.cwd(), bumpFile.filename) try { if (dotgit.ignore(configPath)) return let stat = fs.lstatSync(configPath) - if (stat.isFile()) { - let data = fs.readFileSync(configPath, 'utf8') - let indent = detectIndent(data).indent - let newline = detectNewline(data) - - 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[bumpFile.filename] = true + + if (!stat.isFile()) return + + if (!bumpFile.updater) { + bumpFile.updater = getUpdaterByFileName(bumpFile.filename) + } else { + bumpFile.updater = require( + path.resolve(process.cwd(), bumpFile.updater) + ) } + let contents = fs.readFileSync(configPath, 'utf8') + checkpoint( + args, + 'bumping version in ' + bumpFile.filename + ' from %s to %s', + [bumpFile.updater.readVersion(contents), newVersion] + ) + writeFile( + args, + configPath, + bumpFile.updater.writeVersion(contents, newVersion) + ) + // flag any config files that we modify the version # for + // as having been updated. + configsToUpdate[bumpFile.filename] = true } catch (err) { if (err.code !== 'ENOENT') console.warn(err.message) } diff --git a/lib/package-files/json.js b/lib/package-files/json.js new file mode 100644 index 000000000..dbe5b6f3f --- /dev/null +++ b/lib/package-files/json.js @@ -0,0 +1,15 @@ +const stringifyPackage = require('stringify-package') +const detectIndent = require('detect-indent') +const detectNewline = require('detect-newline') + +module.exports.readVersion = function (contents) { + return JSON.parse(contents).version +} + +module.exports.writeVersion = function (contents, version) { + const json = JSON.parse(contents) + let indent = detectIndent(contents).indent + let newline = detectNewline(contents) + json.version = version + return stringifyPackage(json, indent, newline) +} diff --git a/lib/package-files/version.txt.js b/lib/package-files/version.txt.js new file mode 100644 index 000000000..18bcabed2 --- /dev/null +++ b/lib/package-files/version.txt.js @@ -0,0 +1,7 @@ +module.exports.readVersion = function (contents) { + return contents +} + +module.exports.writeVersion = function (_contents, version) { + return version +} diff --git a/test.js b/test.js index eeaca5c61..bf3e8c681 100644 --- a/test.js +++ b/test.js @@ -908,23 +908,27 @@ describe('standard-version', function () { }) describe('custom `bumpFiles` support', function () { - it('mix.exs', function () { + it('mix.exs + version.txt', function () { // @todo This file path is relative to the `tmp` directory, which is a little confusing fs.copyFileSync('../test/mocks/mix.exs', 'mix.exs') + fs.copyFileSync('../test/mocks/version.txt', 'version.txt') + fs.copyFileSync('../test/mocks/updater/customer-updater.js', 'custom-updater.js') 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: [ + 'version.txt', { filename: 'mix.exs', - replacer: /version: "(.*)"/ + updater: 'custom-updater.js' } ] }) .then(() => { fs.readFileSync('mix.exs', 'utf-8').should.contain('version: "1.1.0"') + fs.readFileSync('version.txt', 'utf-8').should.equal('1.1.0') }) }) }) diff --git a/test/mocks/updater/customer-updater.js b/test/mocks/updater/customer-updater.js new file mode 100644 index 000000000..989aba3c0 --- /dev/null +++ b/test/mocks/updater/customer-updater.js @@ -0,0 +1,12 @@ +const REPLACER = /version: "(.*)"/ + +module.exports.readVersion = function (contents) { + return REPLACER.exec(contents)[1] +} + +module.exports.writeVersion = function (contents, version) { + return contents.replace( + REPLACER.exec(contents)[0], + `version: "${version}"` + ) +} diff --git a/test/mocks/version.txt b/test/mocks/version.txt new file mode 100644 index 000000000..e69de29bb