Skip to content

Commit 6479204

Browse files
committed
Validation of zip using javascript
1 parent 1e13380 commit 6479204

File tree

7 files changed

+133
-23
lines changed

7 files changed

+133
-23
lines changed

code/go-wasm/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.wasm

code/go-wasm/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
include ../go/common.mk
2+
3+
build:
4+
GOOS=js GOARCH=wasm go build -o validator.wasm .
5+
6+
test:
7+
GOOS=js GOARCH=wasm go test -v -exec="`go env GOROOT`/misc/wasm/go_js_wasm_exec" . ../go/...

code/go-wasm/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* Build wasm with `make build`.
2+
* Run `./validate.js /path/to/package.zip` (or `node validate.js /path/to/package.zip`).
3+
4+
Node.js and Go are required.

code/go-wasm/main.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package main
6+
7+
import (
8+
"fmt"
9+
"syscall/js"
10+
11+
"github.com/elastic/package-spec/code/go/pkg/validator"
12+
)
13+
14+
const moduleName = "elasticPackageSpec"
15+
16+
// asyncFunc helps creating functions that return a promise.
17+
//
18+
// Calling async JavaScript APIs causes deadlocks in the JS event loop. Not sure
19+
// how to find if a Go code does it, but for example ValidateFromZip does, so
20+
// we need to run this code in a goroutine and return the result as a promise.
21+
// Related: https://github.com/golang/go/issues/41310
22+
func asyncFunc(fn func(this js.Value, args []js.Value) interface{}) js.Func {
23+
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
24+
handler := js.FuncOf(func(_ js.Value, handlerArgs []js.Value) interface{} {
25+
resolve := handlerArgs[0]
26+
reject := handlerArgs[1]
27+
28+
go func() {
29+
result := fn(this, args)
30+
if err, ok := result.(error); ok {
31+
reject.Invoke(err.Error())
32+
return
33+
}
34+
resolve.Invoke(result)
35+
}()
36+
37+
return nil
38+
})
39+
40+
return js.Global().Get("Promise").New(handler)
41+
})
42+
}
43+
44+
func main() {
45+
// It doesn't seem to be possible yet to export values as part of the compiled instance.
46+
// So we have to expose it by setting a global value. It may worth to explore tinygo for this.
47+
// Related: https://github.com/golang/go/issues/42372
48+
js.Global().Set(moduleName, make(map[string]interface{}))
49+
module := js.Global().Get(moduleName)
50+
module.Set("validateFromZip", asyncFunc(
51+
func(this js.Value, args []js.Value) interface{} {
52+
if len(args) == 0 || args[0].IsNull() || args[0].IsUndefined() {
53+
return fmt.Errorf("package path expected")
54+
}
55+
56+
pkgPath := args[0].String()
57+
return validator.ValidateFromZip(pkgPath)
58+
},
59+
))
60+
61+
// Go runtime must be always available at any moment where exported functionality
62+
// can be executed, so keep it running till done.
63+
done := make(chan struct{})
64+
module.Set("stop", js.FuncOf(func(_ js.Value, _ []js.Value) interface{} {
65+
close(done)
66+
return nil
67+
}))
68+
<-done
69+
}

code/go-wasm/validate.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env node
2+
3+
if (process.argv.length < 3) {
4+
console.error("usage: " + process.argv[1] + " [package path]");
5+
process.exit(1);
6+
}
7+
8+
const path = require('path')
9+
const fs = require('fs');
10+
11+
require(path.join(process.env.GOROOT, "misc/wasm/wasm_exec.js"));
12+
const go = new Go();
13+
14+
const wasmBuffer = fs.readFileSync('validator.wasm');
15+
WebAssembly.instantiate(wasmBuffer, go.importObject).then((validator) => {
16+
go.run(validator.instance);
17+
18+
elasticPackageSpec.validateFromZip(process.argv[2]).then(() =>
19+
console.log("OK")
20+
).catch((err) =>
21+
console.error(err)
22+
).finally(() =>
23+
elasticPackageSpec.stop()
24+
)
25+
}).catch((err) => {
26+
console.error(err);
27+
});

code/go/Makefile

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,4 @@
1-
SPEC_DIR=internal
2-
3-
golicenser_cmd = go run github.com/elastic/go-licenser
4-
golint_cmd = go run golang.org/x/lint/golint
5-
6-
7-
update:
8-
# Add license headers
9-
@$(golicenser_cmd) -license Elastic
10-
11-
check: lint check-license check-spec
12-
13-
# "yamlschema" directory has been excluded from linting, because it contains implementations of gojsonschema interfaces
14-
# which are not compliant with linter rules. The golint tool doesn't support ignore comments.
15-
lint:
16-
@go list ./... | grep -v yamlschema | xargs -n 1 $(golint_cmd) -set_exit_status
17-
18-
check-license:
19-
@$(golicenser_cmd) -license Elastic -d
20-
21-
# Checks that the spec is up-to-date
22-
check-spec:
23-
@$(golicenser_cmd) -license Elastic
1+
include ./common.mk
242

253
# Runs tests
264
test:

code/go/common.mk

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
SPEC_DIR=internal
2+
3+
golicenser_cmd = go run github.com/elastic/go-licenser
4+
golint_cmd = go run golang.org/x/lint/golint
5+
6+
7+
update:
8+
# Add license headers
9+
@$(golicenser_cmd) -license Elastic
10+
11+
check: lint check-license check-spec
12+
13+
# "yamlschema" directory has been excluded from linting, because it contains implementations of gojsonschema interfaces
14+
# which are not compliant with linter rules. The golint tool doesn't support ignore comments.
15+
lint:
16+
@go list ./... | grep -v yamlschema | xargs -n 1 $(golint_cmd) -set_exit_status
17+
18+
check-license:
19+
@$(golicenser_cmd) -license Elastic -d
20+
21+
# Checks that the spec is up-to-date
22+
check-spec:
23+
@$(golicenser_cmd) -license Elastic
24+

0 commit comments

Comments
 (0)