diff --git a/__snapshots__/generic-json.js b/__snapshots__/generic-json.js index 7bc725d39..78d6383ef 100644 --- a/__snapshots__/generic-json.js +++ b/__snapshots__/generic-json.js @@ -46,3 +46,14 @@ exports['GenericJson updateContent updates matching entry 1'] = ` } ` + +exports['GenericJson updateContent updates substring in matching entry 1'] = ` +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>abc/foo:xyz/sub#2.3.4", + "github>abc/bar:xyz/sub#2.3.4" + ] +} + +` diff --git a/src/updaters/generic-json.ts b/src/updaters/generic-json.ts index 64d7355c9..95e822b29 100644 --- a/src/updaters/generic-json.ts +++ b/src/updaters/generic-json.ts @@ -18,6 +18,9 @@ import * as jp from 'jsonpath'; import {jsonStringify} from '../util/json-stringify'; import {logger as defaultLogger, Logger} from '../util/logger'; +const VERSION_REGEX = + /(?\d+)\.(?\d+)\.(?\d+)(-(?[\w.]+))?(\+(?[-\w.]+))?/; + export class GenericJson implements Updater { readonly jsonpath: string; readonly version: Version; @@ -33,8 +36,16 @@ export class GenericJson implements Updater { */ updateContent(content: string, logger: Logger = defaultLogger): string { const data = JSON.parse(content); - const nodes = jp.apply(data, this.jsonpath, _val => { - return this.version.toString(); + const nodes = jp.apply(data, this.jsonpath, value => { + if (typeof value !== 'string') { + logger.warn(`No string in ${this.jsonpath}. Skipping.`); + return value; + } + if (!value.match(VERSION_REGEX)) { + logger.warn(`No version found in ${this.jsonpath}. Skipping.`); + return value; + } + return value.replace(VERSION_REGEX, this.version.toString()); }); if (!nodes) { logger.warn(`No entries modified in ${this.jsonpath}`); diff --git a/test/updaters/fixtures/renovate-shared-preset.json b/test/updaters/fixtures/renovate-shared-preset.json new file mode 100644 index 000000000..1f0caca2d --- /dev/null +++ b/test/updaters/fixtures/renovate-shared-preset.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>abc/foo:xyz/sub#1.2.3", + "github>abc/bar:xyz/sub#1.2.3" + ] +} diff --git a/test/updaters/generic-json.ts b/test/updaters/generic-json.ts index 00431bc68..d25cf6d9e 100644 --- a/test/updaters/generic-json.ts +++ b/test/updaters/generic-json.ts @@ -45,6 +45,15 @@ describe('GenericJson', () => { const newContent = updater.updateContent(oldContent); snapshot(newContent); }); + it('updates substring in matching entry', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './renovate-shared-preset.json'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericJson('$.extends.*', Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + snapshot(newContent); + }); it('ignores non-matching entry', async () => { const oldContent = readFileSync( resolve(fixturesPath, './esy.json'), @@ -54,6 +63,24 @@ describe('GenericJson', () => { const newContent = updater.updateContent(oldContent); expect(newContent).to.eql(oldContent); }); + it('ignore array entry', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './renovate-shared-preset.json'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericJson('$.extends', Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + expect(newContent).to.eql(oldContent); + }); + it('ignore non-matching string', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './esy.json'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericJson('$.author', Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + expect(newContent).to.eql(oldContent); + }); it('warns on invalid jsonpath', async () => { const oldContent = readFileSync( resolve(fixturesPath, './esy.json'),