From ee1c796c21edc9f8841b7b7002bb797a3f48387b Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Wed, 8 Apr 2020 12:37:21 +0200 Subject: [PATCH] refactor(terraform): use autoReplace --- lib/manager/common.ts | 2 - .../__snapshots__/extract.spec.ts.snap | 126 +------------- lib/manager/terraform/extract.spec.ts | 14 -- lib/manager/terraform/extract.ts | 31 ++-- lib/manager/terraform/index.ts | 3 +- lib/manager/terraform/update.spec.ts | 163 ------------------ lib/manager/terraform/update.ts | 42 ----- 7 files changed, 18 insertions(+), 363 deletions(-) delete mode 100644 lib/manager/terraform/update.spec.ts delete mode 100644 lib/manager/terraform/update.ts diff --git a/lib/manager/common.ts b/lib/manager/common.ts index 749bc36624..eba78df889 100644 --- a/lib/manager/common.ts +++ b/lib/manager/common.ts @@ -146,12 +146,10 @@ export interface PackageDependency<T = Record<string, any>> extends Package<T> { displayTo?: string; fromVersion?: string; lockedVersion?: string; - moduleName?: string; propSource?: string; registryUrls?: string[]; rangeStrategy?: RangeStrategy; skipReason?: SkipReason; - source?: string; sourceLine?: number; toVersion?: string; updates?: PackageUpdateResult[]; diff --git a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap index 0f2af52ae1..d1cdedfa31 100644 --- a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap @@ -10,12 +10,6 @@ Object { "depNameShort": "hashicorp/example", "depType": "github", "lookupName": "hashicorp/example", - "managerData": Object { - "lineNumber": 1, - "terraformDependencyType": "module", - }, - "moduleName": "foo", - "source": "github.com/hashicorp/example?ref=v1.0.0", }, Object { "currentValue": "next", @@ -24,13 +18,7 @@ Object { "depNameShort": "hashicorp/example", "depType": "github", "lookupName": "hashicorp/example", - "managerData": Object { - "lineNumber": 5, - "terraformDependencyType": "module", - }, - "moduleName": "bar", "skipReason": "unsupported-version", - "source": "github.com/hashicorp/example?ref=next", }, Object { "currentValue": "0.1.0", @@ -38,12 +26,6 @@ Object { "depName": "hashicorp/consul/aws", "depNameShort": "hashicorp/consul/aws", "depType": "terraform", - "managerData": Object { - "lineNumber": 10, - "terraformDependencyType": "module", - }, - "moduleName": "consul", - "source": "hashicorp/consul/aws", }, Object { "currentValue": "v0.1.0", @@ -52,12 +34,6 @@ Object { "depNameShort": "tieto-cem/terraform-aws-ecs-task-definition", "depType": "github", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", - "managerData": Object { - "lineNumber": 14, - "terraformDependencyType": "module", - }, - "moduleName": "container_definition", - "source": "github.com/tieto-cem/terraform-aws-ecs-task-definition//modules/container-definition?ref=v0.1.0", }, Object { "currentValue": "v0.1.0", @@ -66,12 +42,6 @@ Object { "depNameShort": "tieto-cem/terraform-aws-ecs-task-definition", "depType": "github", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", - "managerData": Object { - "lineNumber": 25, - "terraformDependencyType": "module", - }, - "moduleName": "task_definition", - "source": "github.com/tieto-cem/terraform-aws-ecs-task-definition?ref=v0.1.0", }, Object { "currentValue": "v2.0.0", @@ -80,24 +50,12 @@ Object { "depNameShort": "hashicorp/example", "depType": "github", "lookupName": "hashicorp/example", - "managerData": Object { - "lineNumber": 31, - "terraformDependencyType": "module", - }, - "moduleName": "consul", - "source": "git@github.com:hashicorp/example.git?ref=v2.0.0", }, Object { "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", "depNameShort": "terraform-aws-modules/security-group/aws", "depType": "terraform", - "managerData": Object { - "lineNumber": undefined, - "terraformDependencyType": "module", - }, - "moduleName": "web_server_sg", - "source": "terraform-aws-modules/security-group/aws//modules/http-80", }, Object { "currentValue": "<= 2.4.0", @@ -105,12 +63,6 @@ Object { "depName": "terraform-aws-modules/security-group/aws", "depNameShort": "terraform-aws-modules/security-group/aws", "depType": "terraform", - "managerData": Object { - "lineNumber": 46, - "terraformDependencyType": "module", - }, - "moduleName": "vote_service_sg", - "source": "terraform-aws-modules/security-group/aws", }, Object { "currentValue": "~> 1.1.0", @@ -118,12 +70,6 @@ Object { "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depNameShort": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depType": "terraform", - "managerData": Object { - "lineNumber": 71, - "terraformDependencyType": "module", - }, - "moduleName": "consul", - "source": "app.terraform.io/example-corp/k8s-cluster/azurerm", }, Object { "currentValue": "~> 1.1", @@ -131,12 +77,6 @@ Object { "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depNameShort": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depType": "terraform", - "managerData": Object { - "lineNumber": 76, - "terraformDependencyType": "module", - }, - "moduleName": "consul2", - "source": "app.terraform.io/example-corp/k8s-cluster/azurerm", }, Object { "currentValue": "~~ 1.1", @@ -144,12 +84,6 @@ Object { "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depNameShort": "app.terraform.io/example-corp/k8s-cluster/azurerm", "depType": "terraform", - "managerData": Object { - "lineNumber": 81, - "terraformDependencyType": "module", - }, - "moduleName": "consul3", - "source": "app.terraform.io/example-corp/k8s-cluster/azurerm", }, Object { "currentValue": ">= 1.0.0, <= 2.0.0", @@ -157,26 +91,11 @@ Object { "depName": "hashicorp/consul/aws", "depNameShort": "hashicorp/consul/aws", "depType": "terraform", - "managerData": Object { - "lineNumber": 86, - "terraformDependencyType": "module", - }, - "moduleName": "consul3", - "source": "hashicorp/consul/aws", }, Object { - "managerData": Object { - "terraformDependencyType": "module", - }, - "moduleName": "relative", "skipReason": "local", - "source": "../../modules/fe", }, Object { - "managerData": Object { - "terraformDependencyType": "module", - }, - "moduleName": "nosauce", "skipReason": "no-source", }, Object { @@ -185,11 +104,6 @@ Object { "depName": "azurerm", "depNameShort": "azurerm", "depType": "terraform", - "managerData": Object { - "lineNumber": 99, - "terraformDependencyType": "provider", - }, - "moduleName": "azurerm", }, Object { "currentValue": "=2.4", @@ -197,11 +111,6 @@ Object { "depName": "gitlab", "depNameShort": "gitlab", "depType": "terraform", - "managerData": Object { - "lineNumber": 104, - "terraformDependencyType": "provider", - }, - "moduleName": "gitlab", }, Object { "currentValue": "=1.3", @@ -209,22 +118,12 @@ Object { "depName": "gitlab", "depNameShort": "gitlab", "depType": "terraform", - "managerData": Object { - "lineNumber": 109, - "terraformDependencyType": "provider", - }, - "moduleName": "gitlab", }, Object { "datasource": "terraform-provider", "depName": "helm", "depNameShort": "helm", "depType": "terraform", - "managerData": Object { - "lineNumber": undefined, - "terraformDependencyType": "provider", - }, - "moduleName": "helm", "skipReason": "no-version", }, Object { @@ -233,20 +132,9 @@ Object { "depName": "newrelic", "depNameShort": "newrelic", "depType": "terraform", - "managerData": Object { - "lineNumber": 125, - "terraformDependencyType": "provider", - }, - "moduleName": "newrelic", "skipReason": "unsupported-version", }, - Object { - "managerData": Object { - "terraformDependencyType": "module", - }, - "moduleName": "foobar", - "source": "https://bitbucket.com/hashicorp/example?ref=v1.0.0", - }, + Object {}, Object { "currentValue": "v1.0.0", "datasource": "git-tags", @@ -254,12 +142,6 @@ Object { "depNameShort": "hashicorp/example", "depType": "gitTags", "lookupName": "https://bitbucket.com/hashicorp/example", - "managerData": Object { - "lineNumber": 135, - "terraformDependencyType": "module", - }, - "moduleName": "gittags", - "source": "git::https://bitbucket.com/hashicorp/example?ref=v1.0.0", }, Object { "currentValue": "next", @@ -268,13 +150,7 @@ Object { "depNameShort": "hashicorp/example", "depType": "gitTags", "lookupName": "https://bitbucket.com/hashicorp/example", - "managerData": Object { - "lineNumber": 139, - "terraformDependencyType": "module", - }, - "moduleName": "gittags_badversion", "skipReason": "unsupported-version", - "source": "git::https://bitbucket.com/hashicorp/example?ref=next", }, ], } diff --git a/lib/manager/terraform/extract.spec.ts b/lib/manager/terraform/extract.spec.ts index 5814c51dcd..8e795f2802 100644 --- a/lib/manager/terraform/extract.spec.ts +++ b/lib/manager/terraform/extract.spec.ts @@ -21,20 +21,6 @@ describe('lib/manager/terraform/extract', () => { expect(res).toMatchSnapshot(); expect(res.deps).toHaveLength(22); expect(res.deps.filter(dep => dep.skipReason)).toHaveLength(6); - expect( - res.deps.filter( - dep => - dep.managerData.terraformDependencyType === - TerraformDependencyTypes.module - ) - ).toHaveLength(17); - expect( - res.deps.filter( - dep => - dep.managerData.terraformDependencyType === - TerraformDependencyTypes.provider - ) - ).toHaveLength(5); }); it('returns null if only local deps', () => { expect(extractPackageFile(tf2)).toBeNull(); diff --git a/lib/manager/terraform/extract.ts b/lib/manager/terraform/extract.ts index adaa6cf62f..943ed94459 100644 --- a/lib/manager/terraform/extract.ts +++ b/lib/manager/terraform/extract.ts @@ -48,8 +48,8 @@ export function extractPackageFile(content: string): PackageFile | null { terraformDependency[1] ); const dep: PackageDependency = { - moduleName: terraformDependency[2], managerData: { + moduleName: terraformDependency[2], terraformDependencyType: tfDepType, }, }; @@ -66,10 +66,10 @@ export function extractPackageFile(content: string): PackageFile | null { const [, key, value] = kvMatch; if (key === 'version') { dep.currentValue = value; - dep.versionLine = lineNumber; + dep.managerData.versionLine = lineNumber; } else if (key === 'source') { - dep.source = value; - dep.sourceLine = lineNumber; + dep.managerData.source = value; + dep.managerData.sourceLine = lineNumber; } } } while (line.trim() !== '}'); @@ -86,11 +86,11 @@ export function extractPackageFile(content: string): PackageFile | null { TerraformDependencyTypes.module ) { const githubRefMatch = /github.com(\/|:)([^/]+\/[a-z0-9-]+).*\?ref=(.*)$/.exec( - dep.source + dep.managerData.source ); // Regex would need to be updated to support ssh:// const gitTagsRefMatch = /git::(http|https:\/\/(.*.*\/(.*\/.*)))(?:|\/\/.*)\?ref=(.*)$/.exec( - dep.source + dep.managerData.source ); /* eslint-disable no-param-reassign */ if (githubRefMatch) { @@ -100,7 +100,7 @@ export function extractPackageFile(content: string): PackageFile | null { dep.currentValue = githubRefMatch[3]; dep.datasource = datasourceGithubTags.id; dep.lookupName = githubRefMatch[2]; - dep.managerData.lineNumber = dep.sourceLine; + dep.managerData.lineNumber = dep.managerData.sourceLine; if (!isVersion(dep.currentValue)) { dep.skipReason = SkipReason.UnsupportedVersion; } @@ -111,19 +111,19 @@ export function extractPackageFile(content: string): PackageFile | null { dep.currentValue = gitTagsRefMatch[4]; dep.datasource = datasourceGitTags.id; dep.lookupName = gitTagsRefMatch[1]; - dep.managerData.lineNumber = dep.sourceLine; + dep.managerData.lineNumber = dep.managerData.sourceLine; if (!isVersion(dep.currentValue)) { dep.skipReason = SkipReason.UnsupportedVersion; } - } else if (dep.source) { - const moduleParts = dep.source.split('//')[0].split('/'); + } else if (dep.managerData.source) { + const moduleParts = dep.managerData.source.split('//')[0].split('/'); if (moduleParts[0] === '..') { dep.skipReason = SkipReason.Local; } else if (moduleParts.length >= 3) { dep.depType = 'terraform'; dep.depName = moduleParts.join('/'); dep.depNameShort = dep.depName; - dep.managerData.lineNumber = dep.versionLine; + dep.managerData.lineNumber = dep.managerData.versionLine; dep.datasource = datasourceTerraformModule.id; } } else { @@ -135,9 +135,9 @@ export function extractPackageFile(content: string): PackageFile | null { TerraformDependencyTypes.provider ) { dep.depType = 'terraform'; - dep.depName = dep.moduleName; - dep.depNameShort = dep.moduleName; - dep.managerData.lineNumber = dep.versionLine; + dep.depName = dep.managerData.moduleName; + dep.depNameShort = dep.managerData.moduleName; + dep.managerData.lineNumber = dep.managerData.versionLine; dep.datasource = datasourceTerraformProvider.id; if (dep.managerData.lineNumber) { if (!isValid(dep.currentValue)) { @@ -147,8 +147,7 @@ export function extractPackageFile(content: string): PackageFile | null { dep.skipReason = SkipReason.NoVersion; } } - delete dep.sourceLine; - delete dep.versionLine; + delete dep.managerData; /* eslint-enable no-param-reassign */ }); if (deps.some(dep => dep.skipReason !== 'local')) { diff --git a/lib/manager/terraform/index.ts b/lib/manager/terraform/index.ts index 76e4cbde6b..1fc4cbb4a2 100644 --- a/lib/manager/terraform/index.ts +++ b/lib/manager/terraform/index.ts @@ -1,7 +1,8 @@ import * as hashicorpVersioning from '../../versioning/hashicorp'; export { extractPackageFile } from './extract'; -export { updateDependency } from './update'; + +export const autoReplace = true; export const defaultConfig = { commitMessageTopic: diff --git a/lib/manager/terraform/update.spec.ts b/lib/manager/terraform/update.spec.ts deleted file mode 100644 index 2afde0d4ed..0000000000 --- a/lib/manager/terraform/update.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { readFileSync } from 'fs'; -import { updateDependency } from './update'; - -const tf1 = readFileSync('lib/manager/terraform/__fixtures__/1.tf', 'utf8'); - -describe('manager/terraform/update', () => { - describe('updateDependency', () => { - describe('github', () => { - it('replaces existing value', () => { - const upgrade = { - depType: 'github', - depName: 'foo', - managerData: { lineNumber: 1 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.1', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('returns same', () => { - const upgrade = { - depType: 'github', - depName: 'foo', - managerData: { lineNumber: 1 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).toEqual(tf1); - }); - it('returns null if wrong line', () => { - const upgrade = { - depType: 'github', - depName: 'foo', - managerData: { lineNumber: 2 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).toBeNull(); - }); - it('updates github versions', () => { - const upgrade = { - depType: 'github', - currentValue: 'v0.1.0', - newValue: 'v0.1.3', - depName: 'github.com/tieto-cem/terraform-aws-ecs-task-definition', - depNameShort: 'tieto-cem/terraform-aws-ecs-task-definition', - managerData: { lineNumber: 14 }, - moduleName: 'container_definition', - source: - 'github.com/tieto-cem/terraform-aws-ecs-task-definition//modules/container-definition?ref=v0.1.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - }); - describe('gitTags', () => { - it('replaces existing value', () => { - const upgrade = { - depType: 'gitTags', - depName: 'bitbucket.com/hashicorp/example', - managerData: { lineNumber: 131 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.1', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('returns same', () => { - const upgrade = { - depType: 'gitTags', - depName: 'foobar', - managerData: { lineNumber: 131 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).toEqual(tf1); - }); - it('returns null if wrong line', () => { - const upgrade = { - depType: 'gitTags', - depName: 'foobar', - managerData: { lineNumber: 2 }, - depNameShort: 'hashicorp/example', - newValue: 'v1.0.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).toBeNull(); - }); - }); - it('skips terraform versions wrong line', () => { - const upgrade = { - currentValue: '0.1.0', - depName: 'hashicorp/consul/aws', - depNameShort: 'hashicorp/consul/aws', - depType: 'terraform', - managerData: { lineNumber: 11 }, - moduleName: 'consul', - source: 'hashicorp/consul/aws', - newValue: '0.4.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).toBeNull(); - }); - it('updates terraform versions', () => { - const upgrade = { - currentValue: '0.1.0', - depName: 'hashicorp/consul/aws', - depNameShort: 'hashicorp/consul/aws', - depType: 'terraform', - managerData: { lineNumber: 10 }, - moduleName: 'consul', - source: 'hashicorp/consul/aws', - newValue: '0.4.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('updates terraform versions with terraformDependencyType `module` ', () => { - const upgrade = { - currentValue: '0.1.0', - depName: 'hashicorp/consul/aws', - depNameShort: 'hashicorp/consul/aws', - depType: 'terraform', - managerData: { - lineNumber: 10, - terraformDependencyType: 'module', - }, - moduleName: 'consul', - source: 'hashicorp/consul/aws', - newValue: '0.4.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('updates terraform versions with terraformDependencyType `provider` ', () => { - const upgrade = { - currentValue: '1.36.1', - depName: 'azurerm', - depNameShort: 'azurerm', - depType: 'terraform', - managerData: { - lineNumber: 99, - terraformDependencyType: 'provider', - }, - moduleName: 'azurerm', - source: - 'https://github.com/terraform-providers/terraform-provider-azurerm', - newValue: '1.38.0', - }; - const res = updateDependency({ fileContent: tf1, upgrade }); - expect(res).not.toEqual(tf1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - }); -}); diff --git a/lib/manager/terraform/update.ts b/lib/manager/terraform/update.ts deleted file mode 100644 index 2db0076949..0000000000 --- a/lib/manager/terraform/update.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { logger } from '../../logger'; -import { UpdateDependencyConfig } from '../common'; - -export function updateDependency({ - fileContent, - upgrade, -}: UpdateDependencyConfig): string | null { - try { - logger.debug(`terraform.updateDependency: ${upgrade.newValue}`); - const lines = fileContent.split('\n'); - const lineToChange = lines[upgrade.managerData.lineNumber]; - let newLine = lineToChange; - if (upgrade.depType === 'github') { - if (!lineToChange.includes(upgrade.depNameShort)) { - return null; - } - newLine = lineToChange.replace(/\?ref=.*"/, `?ref=${upgrade.newValue}"`); - } else if (upgrade.depType === 'gitTags') { - if (!lineToChange.includes(upgrade.depNameShort)) { - return null; - } - newLine = lineToChange.replace(/\?ref=.*"/, `?ref=${upgrade.newValue}"`); - } else if (upgrade.depType === 'terraform') { - if (!/version\s*=\s*"/.test(lineToChange)) { - return null; - } - newLine = lineToChange.replace( - /(version\s*=\s*)"[^"]*"/, - `$1"${upgrade.newValue}"` - ); - } - if (newLine === lineToChange) { - logger.debug('No changes necessary'); - return fileContent; - } - lines[upgrade.managerData.lineNumber] = newLine; - return lines.join('\n'); - } catch (err) /* istanbul ignore next */ { - logger.debug({ err }, 'Error setting new terraform module version'); - return null; - } -} -- GitLab