-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
extract.ts
128 lines (126 loc) · 4.02 KB
/
extract.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { logger } from '../../logger';
import type { PackageDependency, PackageFile } from '../types';
import { analyseTerraformModule, extractTerraformModule } from './modules';
import {
analyzeTerraformProvider,
extractTerraformProvider,
} from './providers';
import {
analyzeTerraformRequiredProvider,
extractTerraformRequiredProviders,
} from './required-providers';
import {
analyseTerraformVersion,
extractTerraformRequiredVersion,
} from './required-version';
import {
analyseTerraformResource,
extractTerraformResource,
} from './resources';
import {
TerraformDependencyTypes,
TerraformManagerData,
checkFileContainsDependency,
getTerraformDependencyType,
} from './util';
const dependencyBlockExtractionRegex = /^\s*(?<type>[a-z_]+)\s+("(?<lookupName>[^"]+)"\s+)?("(?<terraformName>[^"]+)"\s+)?{\s*$/;
const contentCheckList = [
'module "',
'provider "',
'required_providers ',
' "helm_release" ',
' "docker_image" ',
];
export function extractPackageFile(content: string): PackageFile | null {
logger.trace({ content }, 'terraform.extractPackageFile()');
if (!checkFileContainsDependency(content, contentCheckList)) {
return null;
}
let deps: PackageDependency<TerraformManagerData>[] = [];
try {
const lines = content.split('\n');
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
const line = lines[lineNumber];
const terraformDependency = dependencyBlockExtractionRegex.exec(line);
if (terraformDependency) {
logger.trace(
`Matched ${terraformDependency.groups.type} on line ${lineNumber}`
);
const tfDepType = getTerraformDependencyType(
terraformDependency.groups.type
);
let result = null;
switch (tfDepType) {
case TerraformDependencyTypes.required_providers: {
result = extractTerraformRequiredProviders(lineNumber, lines);
break;
}
case TerraformDependencyTypes.provider: {
result = extractTerraformProvider(
lineNumber,
lines,
terraformDependency.groups.lookupName
);
break;
}
case TerraformDependencyTypes.module: {
result = extractTerraformModule(
lineNumber,
lines,
terraformDependency.groups.lookupName
);
break;
}
case TerraformDependencyTypes.resource: {
result = extractTerraformResource(lineNumber, lines);
break;
}
case TerraformDependencyTypes.terraform_version: {
result = extractTerraformRequiredVersion(lineNumber, lines);
break;
}
/* istanbul ignore next */
default:
logger.trace(
`Could not identify TerraformDependencyType ${terraformDependency.groups.type} on line ${lineNumber}.`
);
break;
}
if (result) {
lineNumber = result.lineNumber;
deps = deps.concat(result.dependencies);
result = null;
}
}
}
} catch (err) /* istanbul ignore next */ {
logger.warn({ err }, 'Error extracting terraform plugins');
}
deps.forEach((dep) => {
switch (dep.managerData.terraformDependencyType) {
case TerraformDependencyTypes.required_providers:
analyzeTerraformRequiredProvider(dep);
break;
case TerraformDependencyTypes.provider:
analyzeTerraformProvider(dep);
break;
case TerraformDependencyTypes.module:
analyseTerraformModule(dep);
break;
case TerraformDependencyTypes.resource:
analyseTerraformResource(dep);
break;
case TerraformDependencyTypes.terraform_version:
analyseTerraformVersion(dep);
break;
/* istanbul ignore next */
default:
}
// eslint-disable-next-line no-param-reassign
delete dep.managerData;
});
if (deps.some((dep) => dep.skipReason !== 'local')) {
return { deps };
}
return null;
}