Skip to content
This repository has been archived by the owner on Apr 16, 2022. It is now read-only.

Commit

Permalink
remove cloudformation-js-yaml-parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarrad Whitaker authored and akdor1154 committed Apr 26, 2018
1 parent cc4ade3 commit 1b5c3df
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 58 deletions.
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -14,7 +14,6 @@
"url": "https://github.com/martysweet/cfn-lint/issues"
},
"dependencies": {
"cloudformation-js-yaml-schema": "0.3.0",
"colors": "^1.2.1",
"commander": "^2.15.0",
"core-js": "^2.5.1",
Expand Down
61 changes: 4 additions & 57 deletions src/parser.ts
@@ -1,6 +1,8 @@
import yaml = require('js-yaml');
const { CLOUDFORMATION_SCHEMA } = require('cloudformation-js-yaml-schema');
import fs = require('fs');
import buildYamlSchema from './yamlSchema';

const yamlSchema = buildYamlSchema();

export function openFile(path: string){

Expand Down Expand Up @@ -30,15 +32,12 @@ function openYaml(path: string){
// Try and load the Yaml
let yamlParse = yaml.safeLoad(fs.readFileSync(path, 'utf8'), {
filename: path,
schema: CLOUDFORMATION_SCHEMA,
schema: yamlSchema,
onWarning: (warning) => {
console.error(warning);
}
});

lastPlaceInTemplate = yamlParse;
cleanupYaml(yamlParse);

if(typeof yamlParse == 'object'){
return yamlParse
}
Expand All @@ -53,55 +52,3 @@ function openJson(path: string){
return JSON.parse(fs.readFileSync(path, 'utf8'));

}

let lastPlaceInTemplate = null;
let lastKeyInTemplate = null;
function cleanupYaml(ref: any){

// Step into next attribute
for(let i=0; i < Object.keys(ref).length; i++){
let key = Object.keys(ref)[i];

// Resolve the function
if( ref[key] !== null && ref[key].hasOwnProperty('class') && ref[key].hasOwnProperty('data')){

// We have a Yaml generated object

// Define the name of the intrinsic function
let outputKeyName = "Ref";
if(ref[key]["class"] != "Ref"){
outputKeyName = "Fn::" + ref[key]["class"];
}

// Convert the object to expected object type
let outputData = null;
let data = ref[key]['data'];
// Specify the data of the key outputKeyName: {}
if(typeof data == 'string'){
// Split . into array if Fn::GetAtt
if(outputKeyName == "Fn::GetAtt"){
outputData = data.split('.');
}else {
outputData = data;
}
}else{
// If Data is a yaml resolution object, check it doesn't need resolving
lastPlaceInTemplate = ref[key];
lastKeyInTemplate = 'data';
cleanupYaml(data);
// Set the resolved object
outputData = data;
}

ref[key] = {};
ref[key][outputKeyName] = outputData;

}else if(key != 'Attributes' && typeof ref[key] == "object" && ref[key] !== null){
lastPlaceInTemplate = ref;
lastKeyInTemplate = key;
cleanupYaml(ref[key]);
}


}
}
38 changes: 38 additions & 0 deletions src/test/yamlSchema.ts
@@ -0,0 +1,38 @@
import buildYamlSchema, * as yamlSchema from '../yamlSchema';
import yaml = require('js-yaml');
import assert = require('assert');

describe('yamlSchema', () => {
describe('buildYamlSchema', () => {
it('should build a yaml schema', () => {
assert(buildYamlSchema() instanceof yaml.Schema, 'yamlSchema didn\'t return a yaml schema');
})
});

describe('functionTag', () => {
it('should work on a Fn::Thing', () => {
assert.strictEqual(yamlSchema.functionTag('Fn::Name'), 'Name');
})
it('should work on a Thing', () => {
assert.strictEqual(yamlSchema.functionTag('Name'), 'Name');
})
});

describe('buildYamlType', () => {
it('should return a type that builds the JSON representation of the yaml tag', () => {
const type = yamlSchema.buildYamlType('Fn::Join', 'sequence');
const input = ['asdf', 'asdf'];
const representation = type.construct(input);
assert.deepStrictEqual(representation, {'Fn::Join': ['asdf', 'asdf']});
});

it('should special-case Fn::GetAtt', () => {
const type = yamlSchema.buildYamlType('Fn::GetAtt', 'scalar');
const input = 'Resource.Attribute';
const representation = type.construct(input);
assert.deepStrictEqual(representation, {'Fn::GetAtt': ['Resource', 'Attribute']});
})
})


})
36 changes: 36 additions & 0 deletions src/yamlSchema.ts
@@ -0,0 +1,36 @@
import yaml = require('js-yaml');

export function functionTag(functionName: string) {
const splitFunctionName = functionName.split('::');
return splitFunctionName[splitFunctionName.length-1];
}

export default function buildYamlSchema() {
const intrinsicFunctions = require('../data/aws_intrinsic_functions.json');
const yamlTypes = [];
for (const fn in intrinsicFunctions) {
yamlTypes.push(...buildYamlTypes(fn));
}
return yaml.Schema.create(yamlTypes);
}

export type YamlKind = 'scalar' | 'mapping' | 'sequence';
const kinds: YamlKind[] = ['scalar', 'mapping', 'sequence'];

export function buildYamlTypes(fnName: string) {
return kinds.map((kind) => buildYamlType(fnName, kind));
}

export function buildYamlType(fnName: string, kind: YamlKind) {
const tagName = functionTag(fnName);
const tag = `!${tagName}`;

const constructFn = (fnName === 'Fn::GetAtt')
? (data: any) => ({'Fn::GetAtt': data.split('.')})
: (data: any) => ({[fnName]: data});

return new yaml.Type(tag, {
kind,
construct: constructFn
});
}

0 comments on commit 1b5c3df

Please sign in to comment.