diff --git a/changelog.md b/changelog.md index 18cb187..26c5603 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) +## [Unreleased] + +### Fixed + +- Manage unknown component. + ## [0.8.1] - 2024/06/19 ### Changed diff --git a/public/icons/unknown.svg b/public/icons/unknown.svg new file mode 100644 index 0000000..cbfea5b --- /dev/null +++ b/public/icons/unknown.svg @@ -0,0 +1 @@ + diff --git a/src/parser/TerraformListener.js b/src/parser/TerraformListener.js index 944374f..0da2519 100644 --- a/src/parser/TerraformListener.js +++ b/src/parser/TerraformListener.js @@ -2,8 +2,8 @@ import antlr4 from 'antlr4'; import TerraformVariable from 'src/models/TerraformVariable'; import TerraformComponentAttribute from 'src/models/TerraformComponentAttribute'; -import TerraformComponentDefinition from 'src/models/TerraformComponentDefinition'; import TerraformComponent from 'src/models/TerraformComponent'; +import TerraformComponentDefinition from 'src/models/TerraformComponentDefinition'; const getText = (ctx) => ctx.getText().replaceAll('"', '').trim(); @@ -28,6 +28,16 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { this.idCounter = 1; } + getUnknownDefinition(type) { + return new TerraformComponentDefinition({ + isContainer: false, + model: 'DefaultModel', + icon: 'unknown', + type: type || 'unknown', + blockType: this.currentBlockType, + }); + } + addComponent() { const typeExternalId = `${this.currentComponent.definition.type}.${this.currentComponent.externalId}`; @@ -149,7 +159,8 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { this.currentComponent = new TerraformComponent(); const type = getText(ctx.name()); this.currentComponent.definition = this.definitions - .find((definition) => definition.blockType === 'module' && definition.type === type) || null; + .find((definition) => definition.blockType === 'module' && definition.type === type) + || this.getUnknownDefinition(type); } // Exit a parse tree produced by terraformParser#module. @@ -217,10 +228,7 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { this.currentComponent.definition = this.definitions .find((definition) => definition.blockType === this.currentBlockType - && definition.type === type) || new TerraformComponentDefinition({ - blockType: this.currentBlockType, - type, - }); + && definition.type === type) || this.getUnknownDefinition(type); if (this.currentBlockType === 'provider') { // special case for provider, we do not have any externalId diff --git a/tests/resources/js/main.js b/tests/resources/js/main.js index 61e60f2..4cc3557 100644 --- a/tests/resources/js/main.js +++ b/tests/resources/js/main.js @@ -26,6 +26,8 @@ const awsInternetGatewayVpcIdDefinition = awsInternetGatewayDefinition.definedAt const awsRouteTableAssociationDefinition = new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_route_table_association', + icon: 'unknown', + model: 'DefaultModel', }); const awsSecurityGroupDefinition = metadata.pluginData.definitions.components.find(({ type }) => type === 'aws_security_group'); @@ -147,6 +149,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'data', type: 'aws_rds_engine_version', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -169,6 +173,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'data', type: 'aws_availability_zones', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -296,6 +302,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_route_table', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -894,6 +902,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_s3_bucket', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -911,6 +921,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_s3_bucket_acl', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -934,6 +946,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_lb', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -998,6 +1012,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_lb_target_group', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1035,6 +1051,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_launch_configuration', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1067,6 +1085,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_autoscaling_group', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1131,6 +1151,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_autoscaling_policy', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1168,6 +1190,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_cloudwatch_metric_alarm', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1242,6 +1266,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_autoscaling_policy', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1279,6 +1305,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_cloudwatch_metric_alarm', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1353,6 +1381,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_efs_file_system', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1377,6 +1407,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_lb_listener', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1421,6 +1453,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'aws_efs_mount_target', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1463,6 +1497,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'random_string', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ @@ -1485,6 +1521,8 @@ export const mainComponents = [ definition: new TerraformComponentDefinition({ blockType: 'resource', type: 'random_password', + icon: 'unknown', + model: 'DefaultModel', }), attributes: [ new TerraformComponentAttribute({ diff --git a/tests/resources/js/unknown_components.js b/tests/resources/js/unknown_components.js new file mode 100644 index 0000000..d567db3 --- /dev/null +++ b/tests/resources/js/unknown_components.js @@ -0,0 +1,53 @@ +import TerraformComponent from 'src/models/TerraformComponent'; +import TerraformComponentAttribute from 'src/models/TerraformComponentAttribute'; +import { getTerraformMetadata } from 'tests/resources/utils'; +import TerraformComponentDefinition from 'src/models/TerraformComponentDefinition'; + +const metadata = getTerraformMetadata( + 'aws', + 'src/assets/metadata/aws.json', +); +metadata.parse(); + +export default [ + new TerraformComponent({ + id: 'id_1', + externalId: 'id_1', + path: 'new_file.tf', + definition: new TerraformComponentDefinition({ + isContainer: false, + model: 'DefaultModel', + icon: 'unknown', + type: 'unknown_ressource', + blockType: 'resource', + }), + attributes: [ + new TerraformComponentAttribute({ + name: 'value', + type: 'String', + definition: null, + value: 'test', + }), + ], + }), + new TerraformComponent({ + id: 'id_2', + externalId: 'unknown_module', + path: 'new_file.tf', + definition: new TerraformComponentDefinition({ + isContainer: false, + model: 'DefaultModel', + icon: 'unknown', + type: 'unknown_module', + blockType: 'module', + }), + attributes: [ + new TerraformComponentAttribute({ + name: 'source', + type: 'String', + definition: null, + value: 'test', + }), + ], + }), +]; diff --git a/tests/resources/tf/unknown_components.tf b/tests/resources/tf/unknown_components.tf new file mode 100644 index 0000000..9ef49ac --- /dev/null +++ b/tests/resources/tf/unknown_components.tf @@ -0,0 +1,7 @@ +resource "unknown_ressource" "id_1" { + value = "test" +} + +module "unknown_module" { + source = "test" +} diff --git a/tests/unit/parser/TerraformParser.spec.js b/tests/unit/parser/TerraformParser.spec.js index 401c18f..f3a4717 100644 --- a/tests/unit/parser/TerraformParser.spec.js +++ b/tests/unit/parser/TerraformParser.spec.js @@ -33,6 +33,7 @@ import subObject from 'tests/resources/js/subObject'; import objectAttributeDefinition from 'tests/resources/js/objectAttributeDefinition'; import missingDefinitionOnAttribute from 'tests/resources/js/bug67_missingDefinitionOnAttribute'; import emptyListAttribute from 'tests/resources/js/bug78_emptyListAttribute'; +import unknownDefinition from 'tests/resources/js/unknown_components'; describe('Test TerraformParser', () => { describe('Test methods', () => { @@ -576,6 +577,27 @@ describe('Test TerraformParser', () => { parser.parse(new FileInformation({ path: '' }), inputs); expect(metadata.pluginData.components).toEqual(emptyResource); }); + + it('Should set unknown definition', () => { + const metadata = getTerraformMetadata( + 'aws', + 'src/assets/metadata/aws.json', + ); + + metadata.parse(); + metadata.pluginData.initLinkDefinitions(); + + const parser = new TerraformParser(metadata.pluginData); + const inputs = [ + new FileInput({ + path: 'new_file.tf', + content: fs.readFileSync('tests/resources/tf/unknown_components.tf', 'utf8'), + }), + ]; + + parser.parse(new FileInformation({ path: '' }), inputs); + expect(metadata.pluginData.components).toEqual(unknownDefinition); + }); }); }); }); diff --git a/tests/unit/render/TerraformRenderer.spec.js b/tests/unit/render/TerraformRenderer.spec.js index ad1945c..c3a8e10 100644 --- a/tests/unit/render/TerraformRenderer.spec.js +++ b/tests/unit/render/TerraformRenderer.spec.js @@ -560,6 +560,25 @@ describe('Test TerraformRenderer', () => { expect(new TerraformRender(metadata.pluginData).renderFiles()).toEqual([input]); }); + + it('Should generate unknown definition', () => { + const input = new FileInput({ + path: 'new_file.tf', + content: fs.readFileSync('tests/resources/tf/unknown_components.tf', 'utf8'), + }); + const metadata = getTerraformMetadata( + 'aws', + 'src/assets/metadata/aws.json', + ); + + metadata.parse(); + + const parser = new TerraformParser(metadata.pluginData); + + parser.parse(new FileInformation({ path: '' }), [input]); + + expect(new TerraformRender(metadata.pluginData).renderFiles()).toEqual([input]); + }); }); }); });