From b9db70e872d9c28fe17620ff0e8d20e2ba2bd032 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 10:59:24 -0700 Subject: [PATCH 01/10] doc: use mdx to check examples --- README.md | 10 +++++----- dune | 5 +++++ dune-project | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2d4910a..e7835a0 100644 --- a/README.md +++ b/README.md @@ -29,24 +29,24 @@ let hello_world = @@ fun plugin user_data -> (* Get the input *) - let s = Host_function.param plugin Type.string in - print_endline ("Original input: " ^ s); + let s = Host_function.input plugin Type.string in + print_endline ("Original input: " ^ Error.unwrap s); (* Print the userdata *) let () = print_endline user_data in (* Return a JSON value *) - Host_function.result plugin Type.json (`Assoc [ ("count", `Int 999) ]) + Host_function.output plugin Type.json (`Assoc [ ("count", `Int 999) ]) let () = (* Create a manifest using a file from disk *) - let manifest = Manifest.(create [ Wasm.file "test/code-functions.wasm" ]) in + let manifest = Manifest.(create [ Wasm.file "wasm/code-functions.wasm" ]) in (* Create a plugin from the manifest with the [hello_world] host function *) let plugin = Plugin.of_manifest manifest ~functions:[hello_world] ~wasi:true |> Error.unwrap in (* Call [count_vowels] *) - let output = Plugin.call_string plugin ~name:"count_vowels" "this is a test" in + let output = Plugin.call_string plugin ~name:"count_vowels" "this is a test" |> Error.unwrap in (* Print the result *) print_endline output diff --git a/dune b/dune index 5bb482c..ef3c6c1 100644 --- a/dune +++ b/dune @@ -1 +1,6 @@ (dirs :standard \ runtime) + +(mdx + (libraries extism-manifest extism yojson) + (deps wasm/code-functions.wasm) +) diff --git a/dune-project b/dune-project index a253365..bd634bc 100644 --- a/dune-project +++ b/dune-project @@ -2,6 +2,8 @@ (name extism) +(using mdx 0.3) + (generate_opam_files true) (source From e75db126449ef6e72a91a734080df7405901573a Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 11:02:50 -0700 Subject: [PATCH 02/10] ci: use github token --- .github/actions/libextism/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/libextism/action.yml b/.github/actions/libextism/action.yml index cd36dc2..72e50dc 100644 --- a/.github/actions/libextism/action.yml +++ b/.github/actions/libextism/action.yml @@ -13,3 +13,5 @@ runs: - name: Install shell: bash run: sudo extism lib install --version git + env: + GITHUB_TOKEN: ${{ github.token }} From a5869927ad24f5ae7801135b67c4464af3e809a1 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 11:06:54 -0700 Subject: [PATCH 03/10] doc: improve formatting --- .ocamlformat | 4 +++ dune | 5 ++-- lib/extism.mli | 66 +++++++++++++++++++++++++++----------------------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/.ocamlformat b/.ocamlformat index f41b107..bc311ab 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1 +1,5 @@ version = 0.26.1 +doc-comments = after-when-possible +doc-comments-padding = 2 +doc-comments-tag-only = default +parse-docstrings = true diff --git a/dune b/dune index ef3c6c1..38a1292 100644 --- a/dune +++ b/dune @@ -1,6 +1,5 @@ (dirs :standard \ runtime) (mdx - (libraries extism-manifest extism yojson) - (deps wasm/code-functions.wasm) -) + (libraries extism-manifest extism yojson) + (deps wasm/code-functions.wasm)) diff --git a/lib/extism.mli b/lib/extism.mli index 108c7fc..53e3367 100644 --- a/lib/extism.mli +++ b/lib/extism.mli @@ -14,10 +14,10 @@ module Error : sig (** Exception type *) val unwrap : ('a, t) result -> 'a - (** Like {!Result.get_ok} for {!t} *) + (** Like [Result.get_ok] for {!t} *) val throw : t -> 'a - (** Raise [t] as an exception *) + (** Raise {!t} as an exception *) end (** [Val] represents low-level WebAssembly values *) @@ -110,9 +110,9 @@ module Type : sig (** Encode a value to a string *) val decode : Bigstringaf.t -> (t, Error.t) result - (** Decode a value from a bigstring. The bigstring argument uses a direct pointer - into the plugin memory, this means it shouldn't be stored outside of this function - without being copied first *) + (** Decode a value from a bigstring. The bigstring argument uses a direct + pointer into the plugin memory, this means it shouldn't be stored + outside of this function without being copied first *) end module String : S with type t = string @@ -128,16 +128,20 @@ module Type : sig (** Json type *) val string : (module S with type t = string) - (** String type helper, this can be passed to a function expecting a wrapped module *) + (** String type helper, this can be passed to a function expecting a wrapped + module *) val bytes : (module S with type t = bytes) - (** Bytes type helper, this can be passed to a function expecting a wrapped module *) + (** Bytes type helper, this can be passed to a function expecting a wrapped + module *) val bigstring : (module S with type t = Bigstringaf.t) - (** Bigstring type helper, this can be passed to a function expecting a wrapped module *) + (** Bigstring type helper, this can be passed to a function expecting a + wrapped module *) val json : (module S with type t = Yojson.Safe.t) - (** Json type helper, this can be passed to a function expecting a wrapped module *) + (** Json type helper, this can be passed to a function expecting a wrapped + module *) end (** [Host_function] represents the plugin that is currently running, it should @@ -156,16 +160,18 @@ module Host_function : sig (** Represents a block of guest memory *) val output_string : t -> ?index:int -> string -> unit - (** Return a string from a host function, this copies the string into memory and - sets the results array at [index] with the pointer to the allocated value *) + (** Return a string from a host function, this copies the string into memory + and sets the results array at [index] with the pointer to the allocated + value *) val output_bigstring : t -> ?index:int -> Bigstringaf.t -> unit - (** Return a bigstring from a host function, this copies the bigstring into memory and - sets the results array at [index] with the pointer to the allocated value *) + (** Return a bigstring from a host function, this copies the bigstring into + memory and sets the results array at [index] with the pointer to the + allocated value *) val input_string : ?index:int -> t -> string - (** Get a string argument, the parameter at [index] should be an int64 value that points to the - string in linear memory *) + (** Get a string argument, the parameter at [index] should be an int64 value + that points to the string in linear memory *) val input_bigstring : ?index:int -> t -> Bigstringaf.t (** Load a parameter directly from memory *) @@ -198,8 +204,8 @@ module Host_function : sig (** Convert [Val] to memory block *) val of_val_exn : t -> Val.t -> memory_handle - (** Convert [Val] to memory block, raises [Invalid_argument] if the value is not a pointer - to a valid memory block *) + (** Convert [Val] to memory block, raises [Invalid_argument] if the value is + not a pointer to a valid memory block *) val get_string : t -> memory_handle -> string (** Get a string from memory stored at the provided offset *) @@ -215,8 +221,8 @@ module Host_function : sig end end -(** [Function] is used to create new a new function, which can be called - from a WebAssembly plugin *) +(** [Function] is used to create new a new function, which can be called from a + WebAssembly plugin *) module Function : sig type t (** Function type *) @@ -229,12 +235,11 @@ module Function : sig user_data:'a -> (Host_function.t -> 'a -> unit) -> t - (** Create a new function, [Function.v name ~params ~results ~user_data f] creates - a new [Function] with the given [name], [params] specifies the argument types, - [results] specifies the return types, [user_data] is used to pass arbitrary - OCaml values into the function and [f] is the OCaml function that will be - called. - *) + (** Create a new function, [Function.v name ~params ~results ~user_data f] + creates a new [Function] with the given [name], [params] specifies the + argument types, [results] specifies the return types, [user_data] is used + to pass arbitrary OCaml values into the function and [f] is the OCaml + function that will be called. *) val with_namespace : t -> string -> t (** Update a function's namespace *) @@ -277,11 +282,12 @@ module Plugin : sig name:string -> 'a -> ('b, Error.t) result - (** [call t ~name input_type output_type input] executes a function with typed input and output *) + (** [call t ~name input_type output_type input] executes a function with typed + input and output *) val free : t -> unit - (** Free a plugin immediately, this isn't normally required unless there are a lot of plugins ope - at once *) + (** Free a plugin immediately, this isn't normally required unless there are a + lot of plugins ope at once *) val function_exists : t -> string -> bool (** Check if a function is exported by a plugin *) @@ -301,5 +307,5 @@ module Plugin : sig end val with_plugin : (Plugin.t -> 'a) -> Plugin.t -> 'a -(** Create a Plugin that can be used within the scope of the provided callback, it will - automatically be freed when the function returns *) +(** Create a Plugin that can be used within the scope of the provided callback, + it will automatically be freed when the function returns *) From 174417e2d434d66b4c2e505b269514d80545b94f Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 11:56:25 -0700 Subject: [PATCH 04/10] fix: add mdx as dependency --- dune | 1 + dune-project | 1 + extism.opam | 1 + 3 files changed, 3 insertions(+) diff --git a/dune b/dune index 38a1292..2f6155a 100644 --- a/dune +++ b/dune @@ -1,5 +1,6 @@ (dirs :standard \ runtime) (mdx + (package extism) (libraries extism-manifest extism yojson) (deps wasm/code-functions.wasm)) diff --git a/dune-project b/dune-project index bd634bc..a8b1c42 100644 --- a/dune-project +++ b/dune-project @@ -32,6 +32,7 @@ (ppx_inline_test (>= v0.15.0)) (cmdliner (>= 1.1.1)) (uuidm (>= 0.9.0)) + (mdx (and (>= 2.0.0) :with-test)) ) (tags (topics wasm plugin))) diff --git a/extism.opam b/extism.opam index 13a151a..f75eb0f 100644 --- a/extism.opam +++ b/extism.opam @@ -20,6 +20,7 @@ depends: [ "ppx_inline_test" {>= "v0.15.0"} "cmdliner" {>= "1.1.1"} "uuidm" {>= "0.9.0"} + "mdx" {>= "2.0.0" & with-test} "odoc" {with-doc} ] build: [ From 33da4ebc74e46211631b9359c85b116a4f0c2b11 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 12:04:03 -0700 Subject: [PATCH 05/10] fix: typo --- lib/extism.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/extism.mli b/lib/extism.mli index 53e3367..731f923 100644 --- a/lib/extism.mli +++ b/lib/extism.mli @@ -287,7 +287,7 @@ module Plugin : sig val free : t -> unit (** Free a plugin immediately, this isn't normally required unless there are a - lot of plugins ope at once *) + lot of plugins open at once *) val function_exists : t -> string -> bool (** Check if a function is exported by a plugin *) From b2cd8cf8a5bc68f0e8eba2831d766357199e30ac Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 12:16:16 -0700 Subject: [PATCH 06/10] ci: install all deps --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea06250..2cc6cf0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: if: steps.cache-ocaml.outputs.cache-hit != 'true' run: | opam upgrade -y - opam install -y --deps-only . + opam install -y --deps-only --with-test --with-doc . LD_LIBRARY_PATH=/usr/local/lib opam exec -- dune build - name: Test OCaml Host SDK run: | From afc86d4599ad9294f79663cfaa8f2b34c849dadd Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 13:07:21 -0700 Subject: [PATCH 07/10] ci: use pinned mdx --- extism.opam | 3 +++ extism.opam.template | 3 +++ 2 files changed, 6 insertions(+) diff --git a/extism.opam b/extism.opam index f75eb0f..5940f27 100644 --- a/extism.opam +++ b/extism.opam @@ -40,3 +40,6 @@ build: [ dev-repo: "git+https://github.com/extism/ocaml-sdk.git" build-env: [EXTISM_TEST_NO_LIB = ""] post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"] +pin-depends: [ + [ "mdx" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] +] diff --git a/extism.opam.template b/extism.opam.template index ea415be..70e5e38 100644 --- a/extism.opam.template +++ b/extism.opam.template @@ -1,2 +1,5 @@ build-env: [EXTISM_TEST_NO_LIB = ""] post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"] +pin-depends: [ + [ "mdx" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] +] From ba04e85347dedf1135a08ec7df05676b50059aa1 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 13:19:35 -0700 Subject: [PATCH 08/10] ci: use pinned mdx --- extism.opam.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extism.opam.template b/extism.opam.template index 70e5e38..4886a87 100644 --- a/extism.opam.template +++ b/extism.opam.template @@ -1,5 +1,5 @@ build-env: [EXTISM_TEST_NO_LIB = ""] post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"] pin-depends: [ - [ "mdx" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] + [ "mdx.dev" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] ] From e961b4a30959bd97a2e6326e652134a0a636e5c3 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 13:30:50 -0700 Subject: [PATCH 09/10] ci --- dune-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dune-project b/dune-project index a8b1c42..4546cf9 100644 --- a/dune-project +++ b/dune-project @@ -32,7 +32,7 @@ (ppx_inline_test (>= v0.15.0)) (cmdliner (>= 1.1.1)) (uuidm (>= 0.9.0)) - (mdx (and (>= 2.0.0) :with-test)) + (mdx :with-test) ) (tags (topics wasm plugin))) From 9f3bb64477516e037f3d893075fdc67f65900a36 Mon Sep 17 00:00:00 2001 From: zach Date: Fri, 22 Sep 2023 14:05:34 -0700 Subject: [PATCH 10/10] docs: improve doc comments --- dune-project | 2 +- extism.opam | 4 ++-- lib/extism.mli | 10 +++++++++- manifest/extism_manifest.ml | 2 +- manifest/extism_manifest.mli | 35 +++++++++++++++++++++-------------- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/dune-project b/dune-project index 4546cf9..8433706 100644 --- a/dune-project +++ b/dune-project @@ -32,7 +32,7 @@ (ppx_inline_test (>= v0.15.0)) (cmdliner (>= 1.1.1)) (uuidm (>= 0.9.0)) - (mdx :with-test) + (mdx (and :dev :with-test)) ) (tags (topics wasm plugin))) diff --git a/extism.opam b/extism.opam index 5940f27..70cbb2c 100644 --- a/extism.opam +++ b/extism.opam @@ -20,7 +20,7 @@ depends: [ "ppx_inline_test" {>= "v0.15.0"} "cmdliner" {>= "1.1.1"} "uuidm" {>= "0.9.0"} - "mdx" {>= "2.0.0" & with-test} + "mdx" {dev & with-test} "odoc" {with-doc} ] build: [ @@ -41,5 +41,5 @@ dev-repo: "git+https://github.com/extism/ocaml-sdk.git" build-env: [EXTISM_TEST_NO_LIB = ""] post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"] pin-depends: [ - [ "mdx" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] + [ "mdx.dev" "git+https://github.com/realworldocaml/mdx#9586620d81c923b98819042f67a8ce664b2552ac" ] ] diff --git a/lib/extism.mli b/lib/extism.mli index 731f923..4edaffb 100644 --- a/lib/extism.mli +++ b/lib/extism.mli @@ -1,4 +1,12 @@ -(** Extism bindings for OCaml *) +(** Extism bindings for OCaml + + {1 Introduction} + + Extism is a framework for executing WebAssembly plugins. The OCaml bindings require libextism, + installation information is available on {{: https://extism.org/docs/install }the Extism website} + + {1 API 1} +*) val extism_version : unit -> string (** Returns the libextism version, not the version of the OCaml library *) diff --git a/manifest/extism_manifest.ml b/manifest/extism_manifest.ml index 60ce8ef..52719f1 100644 --- a/manifest/extism_manifest.ml +++ b/manifest/extism_manifest.ml @@ -50,8 +50,8 @@ module Wasm = struct type url = { url : string; headers : dict option; [@yojson.option] - name : string option; [@yojson.option] meth : string option; [@yojson.option] [@key "method"] + name : string option; [@yojson.option] hash : string option; [@yojson.option] } [@@deriving yojson] diff --git a/manifest/extism_manifest.mli b/manifest/extism_manifest.mli index 71f4842..96e8a33 100644 --- a/manifest/extism_manifest.mli +++ b/manifest/extism_manifest.mli @@ -1,41 +1,48 @@ -type memory_options = { max_pages : int option } [@@deriving yojson] +(** Extism manifest + + This package provides an OCaml interface for the {{: https://extism.org/docs/concepts/manifest} Extism manifest} +*) + +type memory_options = { +max_pages : int option (** [max_pages] can be used to limit the total number of pages used by the runtime *) +} [@@deriving yojson] (** Memory options *) type dict = (string * string) list [@@deriving yojson] (** Key/value dictionary *) type config = (string * string option) list [@@deriving yojson] -(** Key/value dictionary with optional values *) +(** Key/value dictionary with optional values, used for passing values into a plugin at runtime *) module Wasm : sig type file = { - path : string; - name : string option; [@yojson.option] - hash : string option; [@yojson.option] + path : string; (** Path to Wasm module on disk *) + name : string option; [@yojson.option] (** Optional name of module for linking *) + hash : string option; [@yojson.option] (** Optional hash for verification *) } [@@deriving yojson] (** WebAssembly file *) type data = { - data : string; - name : string option; [@yojson.option] - hash : string option; [@yojson.option] + data : string; (** A string containing a Wasm module *) + name : string option; [@yojson.option] (** Optional name of module for linking *) + hash : string option; [@yojson.option] (** Optional hash for verification *) } [@@deriving yojson] (** WebAssembly module data *) type url = { - url : string; - headers : dict option; [@yojson.option] - name : string option; [@yojson.option] - meth : string option; [@yojson.option] [@key "method"] - hash : string option; [@yojson.option] + url : string; (** A URL to a Wasm module *) + headers : dict option; [@yojson.option] (** Request headers *) + meth : string option; [@yojson.option] [@key "method"] (** Request method *) + name : string option; [@yojson.option] (** Optional name of module for linking *) + hash : string option; [@yojson.option] (** Optional hash for verification *) } [@@deriving yojson] (** WebAssembly URL *) - (** WebAssembly from a file, module data or URL *) type t = File of file | Data of data | Url of url [@@deriving yojson] + (** WebAssembly from a file, module data or URL *) val file : ?name:string -> ?hash:string -> string -> t (** Create [wasm] from filename *)