Skip to content

Commit

Permalink
feat: Add hcltojson-v2 generator for parsing hcl and variables with G…
Browse files Browse the repository at this point in the history
…opherJS.

This commit uses gopherJS to integrate with the external snyk/snyk-iac-parsers Go package and compile it into JS. This exposes the functionality for implementing variable dereferencing, which we can use in a next commit directly via a call to the exposed functions in the generated minified JS.
It includes a Makefile for generation of the js bundles for any new changes.

Co-authored-by: Teodora Sandu <teodora.sandu@snyk.io>
[CFG-1499]

This commit creates a duplicate of the current hcltojson parser with some small tweaks to work with snyk-iac-parsers.
  • Loading branch information
Ilianna Papastefanou committed Feb 8, 2022
1 parent 0985c91 commit dbba988
Show file tree
Hide file tree
Showing 10 changed files with 595 additions and 0 deletions.
6 changes: 6 additions & 0 deletions release-scripts/hcl-to-json-parser-generator-v2/.gitignore
@@ -0,0 +1,6 @@
bin
pkg
src/*
!src/hcltojson-v2
src/hcltojson-v2/vendor
src/hcltojson-v2/dist
25 changes: 25 additions & 0 deletions release-scripts/hcl-to-json-parser-generator-v2/Makefile
@@ -0,0 +1,25 @@
GOPATH := $(CURDIR)
GOBIN := $(CURDIR)/bin
PROJECT_SRC := $(CURDIR)/src/hcltojson-v2
PROJECT_OUT := $(CURDIR)/src/hcltojson-v2/dist

.PHONY: build
build: $(PROJECT_OUT)/hcltojson-v2.js

.PHONY: test
test: $(PROJECT_OUT)/hcltojson-v2.js
node $(PROJECT_SRC)/test.js

.PHONY: clean
clean:
rm -rf $(PROJECT_OUT) bin pkg $(PROJECT_SRC)/vendor

$(GOBIN)/gopherjs:
go get github.com/gopherjs/gopherjs

$(PROJECT_SRC)/vendor: $(PROJECT_SRC)/go.mod $(PROJECT_SRC)/go.sum
cd $(PROJECT_SRC); go mod vendor

$(PROJECT_OUT)/hcltojson-v2.js $(PROJECT_OUT)/hcltojson-v2.js.map: $(GOBIN)/gopherjs $(PROJECT_SRC)/hcltojson-v2.go $(PROJECT_SRC)/vendor
cd $(PROJECT_SRC); GOOS=linux $(GOBIN)/gopherjs build -m -o $(PROJECT_OUT)/hcltojson-v2.js $(PROJECT_SRC)/hcltojson-v2.go

96 changes: 96 additions & 0 deletions release-scripts/hcl-to-json-parser-generator-v2/README.md
@@ -0,0 +1,96 @@
# HCL to JSON v2

This package uses GopherJS[1] to convert the snyk/snyk-iac-parsers
Golang package into JavaScript and provide it as a CommonJS module.
It is suffixed with v2 as we already have an existing hcl2json implementation,
which we will deprecate when we fully switch to this implementation.

## Build

The current path of this folder has to be added into the \$GOPATH environment variable for
the build to work (this is currently a requirement of GopherJS).
e.g:

```
export GOPATH=$HOME/dev/snyk/release-scripts/hcl-to-json-parser-generator-v2
```

Make sure that your `$GOROOT` environment variable is set to where go is installed, for example:

```
GOROOT="/usr/local/go"
```

Then, from this working directory run:

% make build

This will generate two files a hcltojson-v2.js and an hcltojson-v2.js.map with
source maps for the minified file.
You can find these files under `/release-scripts/hcl-to-json-parser-generator-v2/src/hcltojson-v2/dist/`

The output file is ~4.0M minified and ~716K gzipped.

## Usage

The module exposes one function:

- `func parseModule(files map[string]interface{}) map[string]interface{}` this takes a map of files as input and returns a map of parsedFiles and failedFiles as output:
```javascript
const { parseHCL2JSON } = require('./hcltojson-v2');
const fileContent = fs.readFileSync('../path/to/terraform.tf', 'utf-8');
const { parsedFiles, failedFiles } = parseModule({
'../path/to/terraform.tf': fileContent,
'file2.tf': 'content2',
});
```

## Test

A simple assertion that the compiled file works can be run via:

% make test

## Local development

To point to a different version of the `snyk/snyk-iac-parsers` locally, you will need to follow these steps:

- copy your preferred commit(https://github.com/snyk/snyk-iac-parsers/commits/)
- and then, while in `/release-scripts/hcl-to-json-parser-generator-v2/src/hcltojson-v2` directory, run:

```shell
go get github.com/snyk/snyk-iac-parsers@commithash
```

- then, going back to this directory (`/release-scripts/hcl-to-json-parser-generator-v2/`), run:

```shell
make build
```

- Run `make test` to validate that tests are still passing.

## Updating the snyk/snyk-iac-parsers package for production use

The generated GopherJS artefact is used... TBC (not used yet by the CLI)

This is a similar process to the local development, but you also need a couple of extra steps:

- copy the targeted tag from https://github.com/snyk/snyk-iac-parsers/tags
- and then, while in `/release-scripts/hcl-to-json-parser-generator-v2/src/hcltojson-v2` directory, run:

```shell
go get github.com/snyk/snyk-iac-parsers@tag
```

- then, going back to this directory (`/release-scripts/hcl-to-json-parser-generator-v2/`), run:

```shell
make build
```

- Run `make test` to validate that tests are still passing.
- Run the following shell script: `copy-artefact-to-destination.sh`, this will overwrite the current artefact being used by the Terraform parser.

TBC: This still needs confirmation and update when we decide where we are going to use it. Currently it copies the artifact at the same place as before (iac-local-execution/parsers/terraform-parser).
We need to change this accordingly when we decide the use of it.
@@ -0,0 +1,2 @@
#!/bin/bash
cp ./dist/hcltojson-v2.js ../../../../src/cli/commands/test/iac-local-execution/parsers/hcl-to-json-v2/parser.js
@@ -0,0 +1,14 @@
module example.com/m

go 1.16

require (
github.com/go-test/deep v1.0.7 // indirect
github.com/gopherjs/gopherjs v0.0.0-20210413103415-7d3cbed7d026
github.com/hashicorp/hcl/v2 v2.11.1 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/snyk/snyk-iac-parsers v0.1.0
github.com/zclconf/go-cty v1.10.0 // indirect
)

0 comments on commit dbba988

Please sign in to comment.