diff --git a/.gitignore b/.gitignore index e52ae10..d626cb1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ wrap /target results.json /wrappers -yarn.lock \ No newline at end of file +yarn.lock +.env +venv/ +pyexpr/ \ No newline at end of file diff --git a/cases/asyncify/client-config.ts b/cases/asyncify/client-config.ts index dfbeb4e..b5ba271 100644 --- a/cases/asyncify/client-config.ts +++ b/cases/asyncify/client-config.ts @@ -24,7 +24,7 @@ export function configure(builder: ClientConfigBuilder): ClientConfigBuilder { } class MemoryStoragePlugin extends PluginModule> { - private _value: number; + private _value: number = 0; async getData(_: {}): Promise { await this.sleep(50); diff --git a/cases/asyncify/implementations/go/module.go b/cases/asyncify/implementations/go/module.go new file mode 100644 index 0000000..2537052 --- /dev/null +++ b/cases/asyncify/implementations/go/module.go @@ -0,0 +1,80 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + storage "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/storage" + "strconv" +) + +func GetData() uint32 { + v, err := storage.Storage_GetData(&storage.Storage_ArgsGetData{}) + if err != nil { + panic(err.Error()) + } + return uint32(v) +} + +func SetDataWithLargeArgs(args *types.ArgsSetDataWithLargeArgs) string { + largeString := args.Value + _, err := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: 66}) + if err != nil { + panic(err.Error()) + } + return largeString +} + +func SetDataWithManyArgs(args *types.ArgsSetDataWithManyArgs) string { + _, err := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: 55}) + if err != nil { + panic(err.Error()) + } + return args.ValueA + args.ValueB + args.ValueC + args.ValueD + args.ValueE + args.ValueF + args.ValueG + args.ValueH + args.ValueI + args.ValueJ + args.ValueK + args.ValueL +} + +func SetDataWithManyStructuredArgs(args *types.ArgsSetDataWithManyStructuredArgs) bool { + _, err := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: 44}) + if err != nil { + panic(err.Error()) + } + return true +} + +func LocalVarMethod() bool { + _, err := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: 88}) + if err != nil { + panic(err.Error()) + } + return true +} + +func GlobalVarMethod() bool { + _, err := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: 77}) + if err != nil { + panic(err.Error()) + } + return true +} + +func SubsequentInvokes(args *types.ArgsSubsequentInvokes) []string { + var result []string + var err error + + for i := 0; i < int(args.NumberOfTimes); i++ { + _, errSet := storage.Storage_SetData(&storage.Storage_ArgsSetData{Value: int32(i)}) + if errSet != nil { + err = errSet + break + } + data, errGet := storage.Storage_GetData(&storage.Storage_ArgsGetData{}) + if errGet != nil { + err = errGet + break + } + str := strconv.Itoa(int(data)) + result = append(result, str) + } + if err != nil { + panic(err.Error()) + } + return result +} diff --git a/cases/bigint-type/implementations/go/module.go b/cases/bigint-type/implementations/go/module.go new file mode 100644 index 0000000..c6704cd --- /dev/null +++ b/cases/bigint-type/implementations/go/module.go @@ -0,0 +1,19 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + big "github.com/polywrap/go-wrap/msgpack/big" +) + +func Method(args *types.ArgsMethod) (*big.Int) { + result := new(big.Int).Mul(args.Arg1, args.Obj.Prop1) + + if args.Arg2 != nil { + result.Mul(result, args.Arg2) + } + if args.Obj.Prop2 != nil { + result.Mul(result, args.Obj.Prop2) + } + + return result +} diff --git a/cases/bignumber-type/implementations/go/module.go b/cases/bignumber-type/implementations/go/module.go new file mode 100644 index 0000000..1a08bef --- /dev/null +++ b/cases/bignumber-type/implementations/go/module.go @@ -0,0 +1,19 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + big "github.com/polywrap/go-wrap/msgpack/big" +) + +func Method(args *types.ArgsMethod) (*big.Int) { + result := big.NewInt(0).Mul(args.Arg1, args.Obj.Prop1) + + if args.Arg2 != nil { + result.Mul(result, args.Arg2) + } + if args.Obj.Prop2 != nil { + result.Mul(result, args.Obj.Prop2) + } + + return result +} diff --git a/cases/bytes-type/implementations/go/module.go b/cases/bytes-type/implementations/go/module.go new file mode 100644 index 0000000..fdaaf5d --- /dev/null +++ b/cases/bytes-type/implementations/go/module.go @@ -0,0 +1,11 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func BytesMethod(args *types.ArgsBytesMethod) ([]byte) { + s := string(args.Arg.Prop) + result := []byte(s + " Sanity!") + return result +} diff --git a/cases/enum-type/implementations/go/module.go b/cases/enum-type/implementations/go/module.go new file mode 100644 index 0000000..b85eed9 --- /dev/null +++ b/cases/enum-type/implementations/go/module.go @@ -0,0 +1,11 @@ +package module + +import "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + +func Method1(args *types.ArgsMethod1) types.SanityEnum { + return args.En +} + +func Method2(args *types.ArgsMethod2) []types.SanityEnum { + return args.EnumArray +} diff --git a/cases/env-type/00-main/implementations/go/module.go b/cases/env-type/00-main/implementations/go/module.go new file mode 100644 index 0000000..fcd0a5b --- /dev/null +++ b/cases/env-type/00-main/implementations/go/module.go @@ -0,0 +1,17 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func MethodNoEnv(args *types.ArgsMethodNoEnv) string { + return args.Arg +} + +func MethodRequireEnv(env *types.Env) types.Env { + return *env +} + +func MethodOptionalEnv(env *types.Env) *types.Env { + return env +} diff --git a/cases/env-type/01-subinvoker/implementations/go/module.go b/cases/env-type/01-subinvoker/implementations/go/module.go new file mode 100644 index 0000000..c12b96a --- /dev/null +++ b/cases/env-type/01-subinvoker/implementations/go/module.go @@ -0,0 +1,30 @@ +package module + +import ( + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/subinvoked" + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func SubinvokeMethodNoEnv(args *types.ArgsSubinvokeMethodNoEnv) string { + value, err := Subinvoked_MethodNoEnv(&Subinvoked_ArgsMethodNoEnv{Arg: args.Arg}) + if err != nil { + panic(err.Error()) + } + return value +} + +func SubinvokeMethodRequireEnv() Subinvoked_Env { + value, err := Subinvoked_MethodRequireEnv(&Subinvoked_ArgsMethodRequireEnv{}) + if err != nil { + panic(err.Error()) + } + return value +} + +func SubinvokeMethodOptionalEnv() *Subinvoked_Env { + value, err := Subinvoked_MethodOptionalEnv(&Subinvoked_ArgsMethodOptionalEnv{}) + if err != nil { + panic(err.Error()) + } + return value +} diff --git a/cases/env-type/02-subinvoker-with-env/implementations/go/module.go b/cases/env-type/02-subinvoker-with-env/implementations/go/module.go new file mode 100644 index 0000000..d4cd380 --- /dev/null +++ b/cases/env-type/02-subinvoker-with-env/implementations/go/module.go @@ -0,0 +1,11 @@ +package module + +import ( + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/subinvoked" + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func SubinvokeMethodRequireEnv(_ *types.Env) Subinvoked_Env { + res, _ := Subinvoked_MethodRequireEnv(&Subinvoked_ArgsMethodRequireEnv{}) + return res +} diff --git a/cases/interface-invoke/01-implementation/implementations/go/module.go b/cases/interface-invoke/01-implementation/implementations/go/module.go new file mode 100644 index 0000000..d0bc12d --- /dev/null +++ b/cases/interface-invoke/01-implementation/implementations/go/module.go @@ -0,0 +1,13 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func ModuleMethod(args *types.ArgsModuleMethod) types.ImplementationType { + return args.Arg +} + +func AbstractModuleMethod(args *types.ArgsAbstractModuleMethod) string { + return args.Arg.Str +} diff --git a/cases/interface-invoke/02-wrapper/implementations/go/module.go b/cases/interface-invoke/02-wrapper/implementations/go/module.go new file mode 100644 index 0000000..c572187 --- /dev/null +++ b/cases/interface-invoke/02-wrapper/implementations/go/module.go @@ -0,0 +1,24 @@ +package module + +import ( + . "github.com/polywrap/wrap-test-harness/go/module/wrap/interfaces" + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/pkginterface" + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func ModuleMethod(args *types.ArgsModuleMethod) types.ImplementationType { + return args.Arg +} + +func AbstractModuleMethod(args *types.ArgsAbstractModuleMethod) string { + impls := Interface_GetImplementations() + uri := impls[1] + methodArgs := &Interface_ArgsAbstractModuleMethod{ + Arg: args.Arg, + } + result, err := Interface_AbstractModuleMethod(uri, methodArgs) + if err != nil { + panic(err.Error()) + } + return result +} diff --git a/cases/invalid-type/implementations/go/module.go b/cases/invalid-type/implementations/go/module.go new file mode 100644 index 0000000..4c5a987 --- /dev/null +++ b/cases/invalid-type/implementations/go/module.go @@ -0,0 +1,23 @@ +package module + +import "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + +func BoolMethod(args *types.ArgsBoolMethod) (bool) { + return args.Arg +} + +func IntMethod(args *types.ArgsIntMethod) (int32) { + return args.Arg +} + +func UIntMethod(args *types.ArgsUIntMethod) (uint32) { + return args.Arg +} + +func BytesMethod(args *types.ArgsBytesMethod) ([]uint8) { + return args.Arg +} + +func ArrayMethod(args *types.ArgsArrayMethod) ([]string) { + return args.Arg +} diff --git a/cases/json-type/implementations/go/module.go b/cases/json-type/implementations/go/module.go new file mode 100644 index 0000000..e184c23 --- /dev/null +++ b/cases/json-type/implementations/go/module.go @@ -0,0 +1,60 @@ +package module + +import ( + "encoding/json" + "github.com/valyala/fastjson" + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func Stringify(args *types.ArgsStringify) (string) { + var newString string + for _, object := range args.Values { + newString += object.String() + } + return newString +} + +func Parse(args *types.ArgsParse) *fastjson.Value { + p := fastjson.Parser{} + value, err := p.Parse(args.Value) + if err != nil { + panic(err) + } + return value +} + +func StringifyObject(args *types.ArgsStringifyObject) (string) { + var newString string + newString += args.Object.JsonA.String() + newString += args.Object.JsonB.String() + return newString +} + +func MethodJSON(args *types.ArgsMethodJSON) *fastjson.Value { + jsonValue, jsonErr := json.Marshal(args) + if jsonErr != nil { + panic(jsonErr) + } + value, err := fastjson.ParseBytes(jsonValue) + if err != nil { + panic(err) + } + return value +} + +func ParseReserved(args *types.ArgsParseReserved) types.Reserved { + var reserved types.Reserved + err := json.Unmarshal([]byte(args.Json), &reserved) + if err != nil { + panic(err) + } + return reserved +} + +func StringifyReserved(args *types.ArgsStringifyReserved) (string) { + jsonString, err := json.Marshal(args.Reserved) + if err != nil { + panic(err) + } + return string(jsonString) +} diff --git a/cases/map-type/implementations/go/module.go b/cases/map-type/implementations/go/module.go new file mode 100644 index 0000000..b7079d2 --- /dev/null +++ b/cases/map-type/implementations/go/module.go @@ -0,0 +1,26 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func GetKey(args *types.ArgsGetKey) int32 { + value, exists := args.Foo.M_map[args.Key] + if !exists { + // Return a default value or handle the case when the key is not found + return 0 + } + return value +} + +func ReturnMap(args *types.ArgsReturnMap) map[string]int32 { + return args.M_map +} + +func ReturnCustomMap(args *types.ArgsReturnCustomMap) types.CustomMap { + return args.Foo +} + +func ReturnNestedMap(args *types.ArgsReturnNestedMap) map[string]map[string]int32 { + return args.Foo +} diff --git a/cases/no-args/implementations/go/module.go b/cases/no-args/implementations/go/module.go new file mode 100644 index 0000000..154651a --- /dev/null +++ b/cases/no-args/implementations/go/module.go @@ -0,0 +1,5 @@ +package module + +func NoArgsMethod() bool { + return true +} diff --git a/cases/numbers-type/implementations/go/module.go b/cases/numbers-type/implementations/go/module.go new file mode 100644 index 0000000..96235dd --- /dev/null +++ b/cases/numbers-type/implementations/go/module.go @@ -0,0 +1,27 @@ +package module + +import "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + +func I8Method(args *types.ArgsI8Method) int8 { + return args.First + args.Second +} + +func U8Method(args *types.ArgsU8Method) uint8 { + return args.First + args.Second +} + +func I16Method(args *types.ArgsI16Method) int16 { + return args.First + args.Second +} + +func U16Method(args *types.ArgsU16Method) uint16 { + return args.First + args.Second +} + +func I32Method(args *types.ArgsI32Method) int32 { + return args.First + args.Second +} + +func U32Method(args *types.ArgsU32Method) uint32 { + return args.First + args.Second +} diff --git a/cases/object-type/implementations/go/module.go b/cases/object-type/implementations/go/module.go new file mode 100644 index 0000000..be2cd6a --- /dev/null +++ b/cases/object-type/implementations/go/module.go @@ -0,0 +1,65 @@ +package module + +import "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + +func Method1(args *types.ArgsMethod1) []types.Output { + outputs := []types.Output{ + { + Prop: args.Arg1.Prop, + Nested: types.Nested{ + Prop: args.Arg1.Nested.Prop, + }, + }, + } + if args.Arg2 != nil { + arg2 := args.Arg2 + outputs = append(outputs, types.Output{ + Prop: arg2.Prop, + Nested: types.Nested{ + Prop: arg2.Circular.Prop, + }, + }) + } else { + outputs = append(outputs, types.Output{ + Prop: "", + Nested: types.Nested{ + Prop: "", + }, + }) + } + return outputs +} + +func Method2(args *types.ArgsMethod2) *types.Output { + if args.Arg.Prop == "null" { + return nil + } + return &types.Output{ + Prop: args.Arg.Prop, + Nested: types.Nested{ + Prop: args.Arg.Nested.Prop, + }, + } +} + +func Method3(args *types.ArgsMethod3) []*types.Output { + outputs := []*types.Output{ + nil, + } + outputs = append(outputs, &types.Output{ + Prop: args.Arg.Prop, + Nested: types.Nested{ + Prop: args.Arg.Nested.Prop, + }, + }) + return outputs +} + +func Method4(args *types.ArgsMethod4) types.Output { + return types.Output{ + Prop: string(args.Arg.Prop), + Nested: types.Nested{ + Prop: "nested prop", + }, + } +} diff --git a/cases/resolver/01-redirect/implementations/go/module.go b/cases/resolver/01-redirect/implementations/go/module.go new file mode 100644 index 0000000..965ad11 --- /dev/null +++ b/cases/resolver/01-redirect/implementations/go/module.go @@ -0,0 +1,28 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/uri_resolver" + + "fmt" +) + +func TryResolveUri(args *types.ArgsTryResolveUri) *UriResolver_MaybeUriOrManifest { + if args.Authority == "custom-authority" { + uri := fmt.Sprintf("wrap://%s/%s", args.Authority, args.Path) + return &UriResolver_MaybeUriOrManifest{ + Uri: &uri, + Manifest: nil, + } + } else { + uri := fmt.Sprintf("wrap://custom-fs/%s", args.Path) + return &UriResolver_MaybeUriOrManifest{ + Uri: &uri, + Manifest: nil, + } + } +} + +func GetFile(args *types.ArgsGetFile) []byte { + return nil +} diff --git a/cases/resolver/02-fs/implementations/go/module.go b/cases/resolver/02-fs/implementations/go/module.go new file mode 100644 index 0000000..6ef5ac6 --- /dev/null +++ b/cases/resolver/02-fs/implementations/go/module.go @@ -0,0 +1,27 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/uri_resolver" + "fmt" +) + +func TryResolveUri(args *types.ArgsTryResolveUri) *UriResolver_MaybeUriOrManifest { + if args.Authority == "custom-fs" { + uri := fmt.Sprintf("wrap://file/%s", args.Path) + return &UriResolver_MaybeUriOrManifest{ + Uri: &uri, + Manifest: nil, + } + } else { + uri := fmt.Sprintf("wrap://%s/%s", args.Authority, args.Path) + return &UriResolver_MaybeUriOrManifest{ + Uri: &uri, + Manifest: nil, + } + } +} + +func GetFile(args *types.ArgsGetFile) []byte { + return nil +} diff --git a/cases/subinvoke/00-invoke/implementations/go/module.go b/cases/subinvoke/00-invoke/implementations/go/module.go new file mode 100644 index 0000000..22a163a --- /dev/null +++ b/cases/subinvoke/00-invoke/implementations/go/module.go @@ -0,0 +1,13 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" +) + +func Add(args *types.ArgsAdd) int32 { + return args.A + args.B +} + +func InvokeThrowError(args *types.ArgsInvokeThrowError) bool { + panic(args.Error) +} diff --git a/cases/subinvoke/01-subinvoke/implementations/go/module.go b/cases/subinvoke/01-subinvoke/implementations/go/module.go new file mode 100644 index 0000000..c74524f --- /dev/null +++ b/cases/subinvoke/01-subinvoke/implementations/go/module.go @@ -0,0 +1,53 @@ +package module + +import ( + "github.com/polywrap/go-wrap/wrap" + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/imported_subinvoke" +) + +func AddAndIncrement(args *types.ArgsAddAndIncrement) int32 { + value, err := ImportedSubinvoke_Add(&ImportedSubinvoke_ArgsAdd{ + A: args.A, + B: args.B, + }) + if err != nil { + panic(err.Error()) + } + return value + 1 +} + +func SubinvokeThrowError(args *types.ArgsSubinvokeThrowError) bool { + result, err := ImportedSubinvoke_InvokeThrowError(&ImportedSubinvoke_ArgsInvokeThrowError{ + Error: args.Error, + }) + if err != nil { + panic(err.Error()) + } + return result +} + +func SubinvokeMethodNotFound() bool { + argsAdd := &ImportedSubinvoke_ArgsAdd{ + A: 1, + B: 1, + } + argsBuf := SerializeImportedSubinvoke_AddArgs(argsAdd) + _, err := wrap.WrapSubinvoke("authority/imported-subinvoke", "methodNotFound", argsBuf) + if err != nil { + return false + } + return true +} + +func SubinvokeArgsIncorrect() bool { + wrongArgs := &ImportedSubinvoke_ArgsInvokeThrowError{ + Error: "Oops!", + } + argsBuf := SerializeImportedSubinvoke_InvokeThrowErrorArgs(wrongArgs) + _, err := wrap.WrapSubinvoke("authority/imported-subinvoke", "add", argsBuf) + if err != nil { + return false + } + return true +} diff --git a/cases/subinvoke/02-consumer/implementations/go/module.go b/cases/subinvoke/02-consumer/implementations/go/module.go new file mode 100644 index 0000000..69d14df --- /dev/null +++ b/cases/subinvoke/02-consumer/implementations/go/module.go @@ -0,0 +1,37 @@ +package module + +import ( + "github.com/polywrap/wrap-test-harness/go/module/wrap/types" + . "github.com/polywrap/wrap-test-harness/go/module/wrap/imported/imported_invoke" +) + +func AddAndIncrement(args *types.ArgsAddAndIncrement) int32 { + value, err := ImportedInvoke_AddAndIncrement(&ImportedInvoke_ArgsAddAndIncrement{ + A: args.A, + B: args.B, + }) + if err != nil { + panic(err.Error()) + } + return value + 1 +} + +func ThrowError(args *types.ArgsThrowError) bool { + result, err := ImportedInvoke_SubinvokeThrowError(&ImportedInvoke_ArgsSubinvokeThrowError{ + Error: args.Error, + }) + if err != nil { + panic(err.Error()) + } + return result +} + +func RethrowError(args *types.ArgsRethrowError) bool { + result, err := ImportedInvoke_SubinvokeThrowError(&ImportedInvoke_ArgsSubinvokeThrowError{ + Error: args.Error, + }) + if err != nil { + panic(err.Error()) + } + return result +} diff --git a/defaults/Cargo.toml b/defaults/Cargo.toml index 55f2e79..e96cfac 100644 --- a/defaults/Cargo.toml +++ b/defaults/Cargo.toml @@ -7,10 +7,10 @@ license = "MIT" edition = "2021" [dependencies] -polywrap-wasm-rs = "0.11.0" +polywrap-wasm-rs = "~0.11.0" polywrap_msgpack_serde = "0.0.2-beta.4" serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", features = ["preserve_order"]} +serde_json = { version = "1.0", features = ["preserve_order"] } serde_bytes = "0.11.5" [lib] diff --git a/defaults/go.mod b/defaults/go.mod new file mode 100644 index 0000000..e212331 --- /dev/null +++ b/defaults/go.mod @@ -0,0 +1,7 @@ +module github.com/polywrap/wrap-test-harness/go + +go 1.18 + +require github.com/polywrap/go-wrap wrap-0.1 + +require github.com/valyala/fastjson v1.6.3 // indirect diff --git a/defaults/package.json b/defaults/package.json index b00b623..c7b239f 100644 --- a/defaults/package.json +++ b/defaults/package.json @@ -2,7 +2,7 @@ "name": "test-cases-default", "private": true, "dependencies": { - "@polywrap/wasm-as": "0.10.3", + "@polywrap/wasm-as": "~0.11.0", "assemblyscript": "0.19.5" } } \ No newline at end of file diff --git a/package.json b/package.json index e959924..4f2a5e1 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "version:apply": "yarn version --new-version $(cat VERSION) --no-git-tag-version" }, "dependencies": { - "@polywrap/client-js": "0.12.0", - "@polywrap/plugin-js": "0.12.0", - "polywrap": "0.11.0" + "@polywrap/plugin-js": "~0.12.0", + "polywrap": "~0.11.0" } } diff --git a/src/constants.rs b/src/constants.rs index 4a8a4b9..892e413 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -24,6 +24,12 @@ lazy_static! { module: "./Cargo.toml", id: "rs" }); + map.insert("go", Implementation { + dependency: "go.mod", + name: "golang", + module: "./go.mod", + id: "go" + }); map }; } \ No newline at end of file diff --git a/src/engine.rs b/src/engine.rs index 257f344..ce26b41 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,3 +1,12 @@ +use crate::error::{BuildError, ExecutionError, TestError}; +use crate::generator::Generate; +use crate::polywrap_cli::PolywrapCli; +use crate::Results; +use futures::future::try_join_all; +use futures::{future::join_all, Future, StreamExt}; +use log::debug; +use log::info; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt::Debug; use std::fs; @@ -5,15 +14,6 @@ use std::path::{Path, PathBuf}; use std::pin::Pin; use std::sync::Arc; use std::sync::Mutex; -use futures::future::try_join_all; -use log::{debug}; -use serde::{Deserialize, Serialize}; -use futures::{Future,future::join_all,StreamExt}; -use log::{info}; -use crate::error::{ExecutionError, TestError, BuildError}; -use crate::Results; -use crate::generator::{Generate}; -use crate::polywrap_cli::PolywrapCli; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Engine { @@ -30,35 +30,37 @@ pub struct EnginePath { type ComplexCase = HashMap>>; -type ExecutorFuture = Pin> + Send>>; +type ExecutorFuture = Pin> + Send>>; type Executor = Box, Option) -> ExecutorFuture + Send>; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] enum CaseType { Simple(Vec), - Complex(ComplexCase) + Complex(ComplexCase), } impl Engine { - pub fn start( - destination: &Path, - source: &Path - ) -> Self { + pub fn start(destination: &Path, source: &Path) -> Self { Self { path: EnginePath { destination: destination.to_path_buf(), source: source.to_path_buf(), }, feature: None, - implementation: None + implementation: None, } } - pub async fn execute(&self, feature: Option<&str>, implementation: Option<&str>, generate_built_cases: bool) -> Result<(), ExecutionError> { + pub async fn execute( + &self, + feature: Option<&str>, + implementation: Option<&str>, + generate_built_cases: bool, + ) -> Result<(), ExecutionError> { let generator = Generate::new( self.path.destination.to_path_buf(), self.path.source.to_path_buf(), - generate_built_cases + generate_built_cases, ); let generator = Arc::new(generator); let engine = Arc::new(self.clone()); @@ -67,64 +69,64 @@ impl Engine { fs::create_dir("./wrappers")?; } - let project_generator_executor: Executor = Box::new( - move |feature, implementation, subpath| { + let project_generator_executor: Executor = + Box::new(move |feature, implementation, subpath| { let generator = generator.clone(); Box::pin(async move { - generator.project( - feature.as_str(), - implementation.as_deref(), - subpath.as_deref() - ).await.map_err(ExecutionError::GenerateError) + generator + .project( + feature.as_str(), + implementation.as_deref(), + subpath.as_deref(), + ) + .await + .map_err(ExecutionError::GenerateError) }) - } - ); + }); info!("Running generator executor"); self.handler( project_generator_executor, feature.map(|f| f.to_string()), implementation.map(|i| i.to_string()), - ).await?; - - let build_executor: Executor = Box::new( - move |feature, implementation, subpath| { - let e = engine.clone(); - Box::pin(async move { - e.build( - feature.as_str(), - implementation.as_deref(), - subpath.as_deref(), - generate_built_cases - ).await.map_err(ExecutionError::BuildError) - }) - } - ); + ) + .await?; + + let build_executor: Executor = Box::new(move |feature, implementation, subpath| { + let e = engine.clone(); + Box::pin(async move { + e.build( + feature.as_str(), + implementation.as_deref(), + subpath.as_deref(), + generate_built_cases, + ) + .await + .map_err(ExecutionError::BuildError) + }) + }); info!("Running build executor"); self.handler( build_executor, feature.map(|f| f.to_string()), implementation.map(|i| i.to_string()), - ).await?; + ) + .await?; let engine = Arc::new(self.clone()); - let test_executor: Executor = Box::new( - move |feature, implementation, subpath| { - let e = engine.clone(); - Box::pin(async move { - if let Some(i) = implementation { - e.test( - feature.as_str(), - &i, - subpath.as_deref(), - ).await.map_err(ExecutionError::TestError) - } else { - Ok(()) - } - }) - } - ); + let test_executor: Executor = Box::new(move |feature, implementation, subpath| { + let e = engine.clone(); + Box::pin(async move { + if let Some(i) = implementation { + e.test(feature.as_str(), &i, subpath.as_deref()) + .await + .map_err(ExecutionError::TestError) + } else { + Ok(()) + } + }) + }); if !generate_built_cases { info!("Running test executor"); @@ -132,7 +134,8 @@ impl Engine { test_executor, feature.map(|f| f.to_string()), implementation.map(|i| i.to_string()), - ).await? + ) + .await? } Ok(()) } @@ -141,25 +144,28 @@ impl Engine { &self, executor: Executor, feature: Option, - implementation: Option + implementation: Option, ) -> Result<(), ExecutionError> { type FeatureImplMap = HashMap; - let mut feature_map : FeatureImplMap = HashMap::new(); + let mut feature_map: FeatureImplMap = HashMap::new(); match feature { None => { - feature_map = fs::read_dir(&self.path.source)?.fold(feature_map, |mut current, f| { - current.insert(String::from(f.unwrap().file_name().to_str().unwrap()), CaseType::Simple(vec![])); - current - }); - }, + feature_map = + fs::read_dir(&self.path.source)?.fold(feature_map, |mut current, f| { + current.insert( + String::from(f.unwrap().file_name().to_str().unwrap()), + CaseType::Simple(vec![]), + ); + current + }); + } Some(f) => { f.split(',') - .map(|feature| - feature.trim().to_string() - ).into_iter().for_each(|f| { + .map(|feature| feature.trim().to_string()) + .into_iter() + .for_each(|f| { feature_map.insert(f, CaseType::Simple(vec![])); - } - ); + }); } } @@ -169,48 +175,54 @@ impl Engine { match implementation.clone() { None => { if implementation_folder.exists() { - let implementations = fs::read_dir(implementation_folder)?.map(|i| { - i.unwrap().file_name().into_string().unwrap() - }).collect::>(); + let implementations = fs::read_dir(implementation_folder)? + .map(|i| i.unwrap().file_name().into_string().unwrap()) + .collect::>(); feature_map.insert(feature.to_string(), CaseType::Simple(implementations)); } else { let mut complex_case_map: ComplexCase = HashMap::new(); - fs::read_dir(feature_folder)?.into_iter().filter(|i| { - i.as_ref().unwrap().metadata().unwrap().is_dir() - }).for_each(|entry| { - let dir = entry.unwrap(); - let step_name = dir.file_name().into_string().unwrap(); - let step_implementations = dir.path().join("implementations"); - if step_implementations.exists() { - let implementations = fs::read_dir(step_implementations).unwrap().map(|i| { - i.unwrap().file_name().into_string().unwrap() - }).collect::>(); - complex_case_map.insert(step_name, Some(implementations)); - } else { - complex_case_map.insert(step_name, None); - } - }); - feature_map.insert(feature.to_string(), CaseType::Complex(complex_case_map)); + fs::read_dir(feature_folder)? + .into_iter() + .filter(|i| i.as_ref().unwrap().metadata().unwrap().is_dir()) + .for_each(|entry| { + let dir = entry.unwrap(); + let step_name = dir.file_name().into_string().unwrap(); + let step_implementations = dir.path().join("implementations"); + if step_implementations.exists() { + let implementations = fs::read_dir(step_implementations) + .unwrap() + .map(|i| i.unwrap().file_name().into_string().unwrap()) + .collect::>(); + complex_case_map.insert(step_name, Some(implementations)); + } else { + complex_case_map.insert(step_name, None); + } + }); + feature_map + .insert(feature.to_string(), CaseType::Complex(complex_case_map)); }; - }, + } Some(i) => { if implementation_folder.exists() { - feature_map.insert(feature.to_string(), CaseType::Simple(vec![i.to_string()])); + feature_map + .insert(feature.to_string(), CaseType::Simple(vec![i.to_string()])); } else { let mut complex_case_map: ComplexCase = HashMap::new(); - fs::read_dir(feature_folder)?.into_iter().filter(|i| { - i.as_ref().unwrap().metadata().unwrap().is_dir() - }).for_each(|entry| { - let dir = entry.unwrap(); - let step_name = dir.file_name().into_string().unwrap(); - let step_implementations = dir.path().join("implementations"); - if step_implementations.exists() { - complex_case_map.insert(step_name, Some(vec![i.to_string()])); - } else { - complex_case_map.insert(step_name, None); - } - }); - feature_map.insert(feature.to_string(), CaseType::Complex(complex_case_map)); + fs::read_dir(feature_folder)? + .into_iter() + .filter(|i| i.as_ref().unwrap().metadata().unwrap().is_dir()) + .for_each(|entry| { + let dir = entry.unwrap(); + let step_name = dir.file_name().into_string().unwrap(); + let step_implementations = dir.path().join("implementations"); + if step_implementations.exists() { + complex_case_map.insert(step_name, Some(vec![i.to_string()])); + } else { + complex_case_map.insert(step_name, None); + } + }); + feature_map + .insert(feature.to_string(), CaseType::Complex(complex_case_map)); } } } @@ -223,9 +235,11 @@ impl Engine { match f.unwrap() { CaseType::Simple(implementations) => { for implementation in implementations { - current_executions.push( - executor(feature.clone(), Some(implementation.to_string()), None) - ); + current_executions.push(executor( + feature.clone(), + Some(implementation.to_string()), + None, + )); } } CaseType::Complex(cases) => { @@ -235,14 +249,18 @@ impl Engine { let implementations = cases.get(step.as_str()).unwrap(); if let Some(implementation) = implementations { for i in implementation { - current_executions.push( - executor(feature.clone(), Some(i.to_string()), Some(step.to_string())) - ); + current_executions.push(executor( + feature.clone(), + Some(i.to_string()), + Some(step.to_string()), + )); } } else { - current_executions.push( - executor(feature.clone(), None, Some(step.to_string())) - ); + current_executions.push(executor( + feature.clone(), + None, + Some(step.to_string()), + )); } } } @@ -252,11 +270,14 @@ impl Engine { let execution_futures = features_execution_futures .into_values() - .map(|f| { - tokio::spawn(join_all(f)) - } - ); - let futures = try_join_all(futures::stream::iter(execution_futures).collect::>().await).await.unwrap(); + .map(|f| tokio::spawn(join_all(f))); + let futures = try_join_all( + futures::stream::iter(execution_futures) + .collect::>() + .await, + ) + .await + .unwrap(); for feature in futures { for result in feature { @@ -268,7 +289,13 @@ impl Engine { Ok(()) } - async fn build(&self, feature: &str, implementation: Option<&str>, subpath: Option<&str>, generate_built_cases: bool) -> Result<(), BuildError> { + async fn build( + &self, + feature: &str, + implementation: Option<&str>, + subpath: Option<&str>, + generate_built_cases: bool, + ) -> Result<(), BuildError> { let mut directory = self.path.destination.join(feature); let mut copy_dest = self.path.source.join("..").join("wrappers").join(feature); @@ -279,17 +306,19 @@ impl Engine { if let Some(i) = implementation { copy_dest = copy_dest.join("implementations").join(i); - directory = directory - .join("implementations") - .join(i); + directory = directory.join("implementations").join(i); debug!("Building wrapper in path: {}", directory.to_str().unwrap()); } else { - debug!("Building interface in path: {}", directory.to_str().unwrap()); + debug!( + "Building interface in path: {}", + directory.to_str().unwrap() + ); }; let cli = PolywrapCli::new(); let mut command = cli.command.unwrap(); - let build = command.arg("build") + let build = command + .arg("build") .arg("-v") .arg("-l") .arg("./log.txt") @@ -298,7 +327,10 @@ impl Engine { if let Ok(output) = build.output() { let message = if let Some(i) = implementation { if let Some(s) = subpath { - format!("Build of feature: {}, with implementation: {} and subpath: {}", feature, i, s) + format!( + "Build of feature: {}, with implementation: {} and subpath: {}", + feature, i, s + ) } else { format!("Build of feature: {}, with implementation: {}", feature, i) } @@ -309,7 +341,11 @@ impl Engine { if output.status.code() == Some(0) { debug!("{} succeed", message); } else { - return Err(BuildError::BuildExecutionError(format!("{} failed with error: {}", message, String::from_utf8(output.stderr).unwrap()))); + return Err(BuildError::BuildExecutionError(format!( + "{} failed with error: {}", + message, + String::from_utf8(output.stderr).unwrap() + ))); } if generate_built_cases { @@ -323,30 +359,37 @@ impl Engine { } else { let error = build.output().unwrap_err(); - return Err(BuildError::BuildExecutionError(format!("Error on polywrap cli build command: {:?}", error))); + return Err(BuildError::BuildExecutionError(format!( + "Error on polywrap cli build command: {:?}", + error + ))); } Ok(()) } - async fn test(&self, feature: &str, implementation: &str, subpath: Option<&str>) -> Result<(), TestError> { + async fn test( + &self, + feature: &str, + implementation: &str, + subpath: Option<&str>, + ) -> Result<(), TestError> { let mut directory = self.path.destination.join(feature); let cli = PolywrapCli::new(); let mut command = cli.command.unwrap(); - let test = command.arg("test") - .arg("-o") - .arg("./output.json"); + let test = command.arg("test").arg("-o").arg("./output.json"); if let Some(p) = subpath { - let mut folders = fs::read_dir(&directory)? - .filter_map(|f| { - let file = f.unwrap(); - if file.metadata().unwrap().is_dir() { + let mut folders = fs::read_dir(&directory)? + .filter_map(|f| { + let file = f.unwrap(); + if file.metadata().unwrap().is_dir() { return Some(file.file_name().into_string().unwrap()); - } + } - None - }).collect::>(); + None + }) + .collect::>(); folders.sort(); if !folders.last().eq(&Some(&String::from(p))) { @@ -362,9 +405,7 @@ impl Engine { test.arg("-c").arg("../../../client-config.ts"); }; } else { - directory = directory - .join("implementations") - .join(implementation); + directory = directory.join("implementations").join(implementation); test.arg("-m").arg("../../polywrap.test.yaml"); let custom_config = directory.join("../../client-config.ts").exists(); if custom_config { @@ -374,19 +415,20 @@ impl Engine { test.current_dir(&directory); - let mut message_error = String::new(); - if test.output().is_err() { - message_error = test.output().unwrap_err().to_string(); - }; + let test_result = test.output(); - let stderr = test.output().unwrap().stderr; - if !stderr.is_empty() { - message_error = String::from_utf8(stderr).unwrap(); + if test_result.is_err() { + return Err(TestError::TestExecutionError(test_result.unwrap_err().to_string())); } - if !message_error.is_empty() { - let message = format!("Error on polywrap CLI Test command: {}", message_error); - return Err(TestError::TestExecutionError(message)) + let test_output = test.output().unwrap(); + + let stderr = test_output.stderr; + if !stderr.is_empty() { + let stdout_str = String::from_utf8(test_output.stdout).unwrap(); + let stderr_str = String::from_utf8(stderr).unwrap(); + let message = format!("Error on polywrap CLI Test command. STDOUT:\n{}\n\nSTDERR:\n{}", stdout_str, stderr_str); + return Err(TestError::TestExecutionError(message)); } let impl_name = directory.file_name().unwrap().to_str().unwrap(); @@ -407,17 +449,16 @@ impl Engine { if let Ok(f) = fs::read(&info_path) { let result_str = String::from_utf8_lossy(&f).parse::().unwrap(); let mut results: Results = serde_json::from_str(result_str.as_str()).unwrap(); - results.info.entry(impl_name.to_string()).or_default().insert(feature.to_string(), summary); - let results_file = fs::OpenOptions::new() - .write(true) - .open(&info_path) - .unwrap(); + results + .info + .entry(impl_name.to_string()) + .or_default() + .insert(feature.to_string(), summary); + let results_file = fs::OpenOptions::new().write(true).open(&info_path).unwrap(); serde_json::to_writer_pretty(results_file, &results).unwrap(); } else { let mut results = Results::new(); - let summaries = HashMap::from([ - (feature.to_string(), summary) - ]); + let summaries = HashMap::from([(feature.to_string(), summary)]); results.info.insert(impl_name.to_string(), summaries); let results_file = fs::OpenOptions::new() .write(true) diff --git a/src/generator.rs b/src/generator.rs index e8babe2..d2e9865 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -151,7 +151,14 @@ impl Generate { // Generate implementation files (i.e: index.ts/lib.rs) let files = fs::read_dir(&source_path)?; for file in files { - let destination_source_folder = &destination_path.join("src"); + // HACK: fix this + let subpath: &str; + if implementation == "go" { + subpath = "module"; + } else { + subpath = "src"; + } + let destination_source_folder = &destination_path.join(subpath); fs::create_dir(destination_source_folder)?; let name = file?.file_name(); let impl_source = source_path.join(&name); diff --git a/src/main.rs b/src/main.rs index 7d4497d..2a4a20d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,11 @@ async fn main() -> Result<(), HarnessError> { Engine::start( destination_path, source_path - ).execute(feature, implementation, sanitized_args.wrappers_path.is_some()).await?; + ).execute( + feature, + implementation, + sanitized_args.wrappers_path.is_some() + ).await?; if let Some(p) = sanitized_args.wrappers_path.as_deref() { if !p.eq("./wrappers") {