diff --git a/lib/config/definitions.js b/lib/config/definitions.js index 06509ca99eb8f66575ac76b386844be0cde5ba5f..02ff369a400773bb46529f28def0bf579167aba9 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -780,6 +780,13 @@ const options = [ default: { enabled: false }, mergeable: true, }, + { + name: 'nvm', + description: 'Configuration object for .nvmrc files', + state: 'repository', + type: 'json', + default: { enabled: true }, + }, { name: 'docker', description: 'Configuration object for Dockerfile renovation', diff --git a/lib/manager/index.js b/lib/manager/index.js index 9ec78db90be80e7dd1efbce131d357f036c5e28a..c1c1a6ef115267ea0623087f9169c5a1812aa8ab 100644 --- a/lib/manager/index.js +++ b/lib/manager/index.js @@ -3,7 +3,7 @@ const { mergeChildConfig } = require('../config'); const { checkMonorepos } = require('../manager/npm/monorepos'); const managers = {}; -const managerList = ['bazel', 'docker', 'meteor', 'npm', 'travis']; +const managerList = ['bazel', 'docker', 'meteor', 'npm', 'nvm', 'travis']; for (const manager of managerList) { // eslint-disable-next-line global-require,import/no-dynamic-require managers[manager] = require(`./${manager}`); @@ -112,6 +112,7 @@ async function resolvePackageFiles(config) { : await detectPackageFiles(config); logger.debug({ allPackageFiles }, 'allPackageFiles'); const managerFileMappings = { + '.nvmrc': 'nvm', '.travis.yml': 'travis', Dockerfile: 'docker', WORKSPACE: 'bazel', diff --git a/lib/manager/nvm/detect.js b/lib/manager/nvm/detect.js new file mode 100644 index 0000000000000000000000000000000000000000..922bc40d1885abc5a6f9a2beb04e356c82c7f577 --- /dev/null +++ b/lib/manager/nvm/detect.js @@ -0,0 +1,13 @@ +module.exports = { + detectPackageFiles, +}; + +function detectPackageFiles(config, fileList) { + logger.debug('nvm.detectPackageFiles()'); + if (config.nvm.enabled) { + if (fileList.includes('.nvmrc')) { + return ['.nvmrc']; + } + } + return []; +} diff --git a/lib/manager/nvm/extract.js b/lib/manager/nvm/extract.js new file mode 100644 index 0000000000000000000000000000000000000000..9d2111943345bc66b17527b0cc451a9146a30bb2 --- /dev/null +++ b/lib/manager/nvm/extract.js @@ -0,0 +1,13 @@ +module.exports = { + extractDependencies, +}; + +function extractDependencies(packageContent) { + return [ + { + depName: 'node', + depType: '.nvmrc', + currentVersion: packageContent.trim(), + }, + ]; +} diff --git a/lib/manager/nvm/index.js b/lib/manager/nvm/index.js new file mode 100644 index 0000000000000000000000000000000000000000..6b0c9b22a06d47a8c79c7a0517cb7f30bafde0cd --- /dev/null +++ b/lib/manager/nvm/index.js @@ -0,0 +1,13 @@ +const { detectPackageFiles } = require('./detect'); +const { extractDependencies } = require('./extract'); +const { getPackageUpdates } = require('./package'); +const { resolvePackageFile } = require('./resolve'); +const { setNewValue } = require('./update'); + +module.exports = { + detectPackageFiles, + extractDependencies, + getPackageUpdates, + resolvePackageFile, + setNewValue, +}; diff --git a/lib/manager/nvm/package.js b/lib/manager/nvm/package.js new file mode 100644 index 0000000000000000000000000000000000000000..75a8b35efd88c4ffd15798cc5c3cef244da476c3 --- /dev/null +++ b/lib/manager/nvm/package.js @@ -0,0 +1,10 @@ +const nodeManager = require('../_helpers/node/package'); + +module.exports = { + getPackageUpdates, +}; + +function getPackageUpdates(config) { + logger.debug('nvm.getPackageUpdates()'); + return nodeManager.getPackageUpdates(config); +} diff --git a/lib/manager/nvm/resolve.js b/lib/manager/nvm/resolve.js new file mode 100644 index 0000000000000000000000000000000000000000..f39498a03f6d7dc4a66cac37978bc33dd77050a3 --- /dev/null +++ b/lib/manager/nvm/resolve.js @@ -0,0 +1,19 @@ +const { mergeChildConfig } = require('../../config'); + +module.exports = { + resolvePackageFile, +}; + +async function resolvePackageFile(config, inputFile) { + const nvmConfig = mergeChildConfig(config.node, config.nvm); + const packageFile = mergeChildConfig(nvmConfig, inputFile); + logger.debug( + `Resolving packageFile ${JSON.stringify(packageFile.packageFile)}` + ); + packageFile.content = await platform.getFile(packageFile.packageFile); + if (!packageFile.content) { + logger.debug('No packageFile content'); + return null; + } + return packageFile; +} diff --git a/lib/manager/nvm/update.js b/lib/manager/nvm/update.js new file mode 100644 index 0000000000000000000000000000000000000000..3d371c5a8ca319c413361e82a560731c9b73b616 --- /dev/null +++ b/lib/manager/nvm/update.js @@ -0,0 +1,8 @@ +module.exports = { + setNewValue, +}; + +function setNewValue(currentFileContent, upgrade) { + logger.debug(`nvm.setNewValue: ${upgrade.newVersions}`); + return `${upgrade.newVersion}\n`; +} diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.js index c5b945846a799d61c5b718328b94f4e11f6b1fd6..88d8a12b477d34070703808a74fc2e8b51e8a75b 100644 --- a/lib/workers/pr/index.js +++ b/lib/workers/pr/index.js @@ -111,7 +111,11 @@ async function ensurePr(prConfig) { processedUpgrades.push(upgradeKey); let logJSON; - if (upgrade.depType !== 'engines') { + if ( + upgrade.manager !== 'travis' && + upgrade.manager !== 'nvm' && + upgrade.depType !== 'engines' + ) { logJSON = await changelogHelper.getChangeLogJSON( upgrade.depName, upgrade.changeLogFromVersion, diff --git a/test/manager/__snapshots__/index.spec.js.snap b/test/manager/__snapshots__/index.spec.js.snap index cf561e12e6197a3c13093efd72b0dbd5f8d42f08..91c455b74987ecbea361deba72e76d2c7f69b849 100644 --- a/test/manager/__snapshots__/index.spec.js.snap +++ b/test/manager/__snapshots__/index.spec.js.snap @@ -7,6 +7,12 @@ Array [ ] `; +exports[`manager detectPackageFiles(config) finds .nvmrc files 1`] = ` +Array [ + ".nvmrc", +] +`; + exports[`manager detectPackageFiles(config) finds .travis.yml files 1`] = ` Array [ ".travis.yml", diff --git a/test/manager/__snapshots__/resolve.spec.js.snap b/test/manager/__snapshots__/resolve.spec.js.snap index 6f661ff19a652d8bd900fcf2023bbdbcc2bd9449..643d46f1b717183c71939924e5c798f6ae08a26c 100644 --- a/test/manager/__snapshots__/resolve.spec.js.snap +++ b/test/manager/__snapshots__/resolve.spec.js.snap @@ -42,7 +42,7 @@ Array [ ] `; -exports[`manager/resolve resolvePackageFiles() detects meteor and docker and travis and bazel 1`] = ` +exports[`manager/resolve resolvePackageFiles() detects meteor and docker and travis and bazel and nvm 1`] = ` Array [ Object { "content": "{}", @@ -270,8 +270,7 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).", "prTitle": "Update {{{depName}}} Dockerfile tag to {{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newTag}}}{{/if}}", }, Object { - "content": "hello: world -", + "content": "# travis", "enabled": false, "groupName": "node.js", "lazyGrouping": false, @@ -279,11 +278,20 @@ This PR has been generated by [Renovate Bot](https://renovateapp.com).", "packageFile": ".travis.yml", }, Object { - "content": "# travis", + "content": "# WORKSPACE", "enabled": true, "manager": "bazel", "packageFile": "WORKSPACE", }, + Object { + "content": "8.9 +", + "enabled": true, + "groupName": "node.js", + "lazyGrouping": false, + "manager": "nvm", + "packageFile": ".nvmrc", + }, ] `; diff --git a/test/manager/index.spec.js b/test/manager/index.spec.js index e6f5687d20a2ff2dc559070bb488af0e113d5291..cc56dc3f959de5d3f60ec0c0f057ae6531d2178e 100644 --- a/test/manager/index.spec.js +++ b/test/manager/index.spec.js @@ -78,6 +78,13 @@ describe('manager', () => { expect(res).toMatchSnapshot(); expect(res).toHaveLength(1); }); + it('finds .nvmrc files', async () => { + config.travis.enabled = true; + platform.getFileList.mockReturnValueOnce(['.nvmrc', 'other/.nvmrc']); + const res = await manager.detectPackageFiles(config); + expect(res).toMatchSnapshot(); + expect(res).toHaveLength(1); + }); it('finds WORKSPACE files', async () => { config.bazel.enabled = true; platform.getFileList.mockReturnValueOnce([ diff --git a/test/manager/nvm/__snapshots__/extract.spec.js.snap b/test/manager/nvm/__snapshots__/extract.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..1b783d2a472554b8ecbe40794794c87bc50aca59 --- /dev/null +++ b/test/manager/nvm/__snapshots__/extract.spec.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lib/manager/nvm/extract extractDependencies() returns a result 1`] = ` +Array [ + Object { + "currentVersion": "8.4.0", + "depName": "node", + "depType": ".nvmrc", + }, +] +`; diff --git a/test/manager/nvm/__snapshots__/package.spec.js.snap b/test/manager/nvm/__snapshots__/package.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..acf0751f45a19504773edababc727b79911b109c --- /dev/null +++ b/test/manager/nvm/__snapshots__/package.spec.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lib/workers/package/node getPackageUpdates returns result if needing updates 1`] = `Array []`; diff --git a/test/manager/nvm/__snapshots__/update.spec.js.snap b/test/manager/nvm/__snapshots__/update.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..e938db537a6e2efde93d1459c9eeba39f1df6e80 --- /dev/null +++ b/test/manager/nvm/__snapshots__/update.spec.js.snap @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`manager/nvm/update setNewValue updates values 1`] = ` +"8.9.1 +" +`; diff --git a/test/manager/nvm/extract.spec.js b/test/manager/nvm/extract.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..d13e4d2d45346fe88ee23e36090b0a7cd2187458 --- /dev/null +++ b/test/manager/nvm/extract.spec.js @@ -0,0 +1,10 @@ +const { extractDependencies } = require('../../../lib/manager/nvm/extract'); + +describe('lib/manager/nvm/extract', () => { + describe('extractDependencies()', () => { + it('returns a result', () => { + const res = extractDependencies('8.4.0\n'); + expect(res).toMatchSnapshot(); + }); + }); +}); diff --git a/test/manager/nvm/package.spec.js b/test/manager/nvm/package.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..1c53f378b2474e072f6d1e4231d8fbcd505a1370 --- /dev/null +++ b/test/manager/nvm/package.spec.js @@ -0,0 +1,22 @@ +const node = require('../../../lib/manager/nvm/package'); +const defaultConfig = require('../../../lib/config/defaults').getConfig(); + +describe('lib/workers/package/node', () => { + describe('getPackageUpdates', () => { + let config; + beforeEach(() => { + config = { + ...defaultConfig, + }; + }); + it('returns empty if matching', async () => { + config.currentVersion = ['6', '8']; + config.supportPolicy = ['lts_active']; + expect(await node.getPackageUpdates(config)).toEqual([]); + }); + it('returns result if needing updates', async () => { + config.currentVersion = ['6', '8']; + expect(await node.getPackageUpdates(config)).toMatchSnapshot(); + }); + }); +}); diff --git a/test/manager/nvm/update.spec.js b/test/manager/nvm/update.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..529499f6007895949c9188f5277ed7e782f07bcc --- /dev/null +++ b/test/manager/nvm/update.spec.js @@ -0,0 +1,13 @@ +const nodefile = require('../../../lib/manager/nvm/update'); + +describe('manager/nvm/update', () => { + describe('setNewValue', () => { + it('updates values', () => { + const upgrade = { + newVersion: '8.9.1', + }; + const res = nodefile.setNewValue('8.9.0\n', upgrade); + expect(res).toMatchSnapshot(); + }); + }); +}); diff --git a/test/manager/resolve.spec.js b/test/manager/resolve.spec.js index c30ff35c6d4f2d9d752d041a78026c2679d9cd1a..78c9d002b421cbf5d42ed0a6d77b1114bf257bbe 100644 --- a/test/manager/resolve.spec.js +++ b/test/manager/resolve.spec.js @@ -94,18 +94,19 @@ describe('manager/resolve', () => { expect(res.packageFiles).toMatchSnapshot(); expect(res.warnings).toHaveLength(0); }); - it('detects meteor and docker and travis and bazel', async () => { + it('detects meteor and docker and travis and bazel and nvm', async () => { config.packageFiles = [ 'package.js', 'Dockerfile', '.travis.yml', 'WORKSPACE', + '.nvmrc', ]; platform.getFile.mockReturnValueOnce('{}'); // package.js platform.getFile.mockReturnValueOnce('# comment\nFROM node:8\n'); // Dockerfile - platform.getFile.mockReturnValueOnce('hello: world\n'); // Dockerfile platform.getFile.mockReturnValueOnce('# travis'); // .travis.yml platform.getFile.mockReturnValueOnce('# WORKSPACE'); // Dockerfile + platform.getFile.mockReturnValueOnce('8.9\n'); // Dockerfile const res = await resolvePackageFiles(config); expect(res.packageFiles).toMatchSnapshot(); }); @@ -116,6 +117,7 @@ describe('manager/resolve', () => { '.travis.yml', 'WORKSPACE', 'package.js', + '.nvmrc', ]; platform.getFile.mockReturnValueOnce('# comment\n'); // Dockerfile const res = await resolvePackageFiles(config); diff --git a/website/docs/_posts/2017-10-05-configuration-options.md b/website/docs/_posts/2017-10-05-configuration-options.md index 991e8b6b65aa5b4774aaa04fae92d560a73b28a5..f41a95b7d221f3782772ba7c2b7b146539e27403 100644 --- a/website/docs/_posts/2017-10-05-configuration-options.md +++ b/website/docs/_posts/2017-10-05-configuration-options.md @@ -551,6 +551,17 @@ A string copy of npmrc file. See https://renovateapp.com/docs/deep-dives/private-modules for details on how this is used. +## nvm + +Configuration specific for `.nvmrc` files. + +| name | value | +| ------- | ----------------- | +| type | object | +| default | { enabled: true } | + +For settings common to all node.js version updates (e.g. travis, nvm, etc) you can use the `node` object instead. + ## optionalDependencies Configuration specific for `package.json > optionalDependencies`.