Packages

Run WebAssembly from Elixir. Load WASM modules in Rust, Go, C β€” call them like native functions.

Current section

Files

Jump to
firebird lib mix tasks firebird.target.verify.ex
Raw

lib/mix/tasks/firebird.target.verify.ex

defmodule Mix.Tasks.Firebird.Target.Verify do
@moduledoc """
Verify compiled WASM modules by loading and optionally running smoke tests.
## Usage
# Verify all WASM files in output directory
mix firebird.target.verify
# Verify specific directory
mix firebird.target.verify --dir _build/wasm
# Verify specific file
mix firebird.target.verify --file _build/wasm/MyMath.wasm
# Run with smoke tests (auto-detected from source annotations)
mix firebird.target.verify --smoke
## Output
Reports for each WASM file:
- Whether it loads successfully
- Number and names of exports
- Smoke test results (if enabled)
"""
use Mix.Task
@shortdoc "Verify compiled WASM modules"
@switches [
dir: :string,
file: :string,
smoke: :boolean,
json: :boolean,
verbose: :boolean
]
@aliases [
d: :dir,
f: :file,
v: :verbose
]
@impl Mix.Task
def run(args) do
{opts, _rest, _invalid} = OptionParser.parse(args, switches: @switches, aliases: @aliases)
verbose = Keyword.get(opts, :verbose, false)
json_mode = Keyword.get(opts, :json, false)
cond do
file = Keyword.get(opts, :file) ->
verify_file(file, verbose, json_mode)
dir = Keyword.get(opts, :dir) ->
verify_directory(dir, verbose, json_mode)
true ->
# Default: verify _build/wasm
config = Firebird.Target.Config.from_mix_project()
verify_directory(config.output_dir, verbose, json_mode)
end
end
defp verify_file(path, _verbose, json_mode) do
Mix.shell().info("πŸ” Verifying #{path}...")
case File.read(path) do
{:ok, binary} ->
{:ok, report} = Firebird.Target.Verify.verify_binary(binary)
if json_mode do
Mix.shell().info(Jason.encode!(report, pretty: true))
else
Mix.shell().info(Firebird.Target.Verify.format_report(report))
end
{:error, reason} ->
Mix.shell().error(" ❌ Cannot read #{path}: #{reason}")
end
end
defp verify_directory(dir, verbose, json_mode) do
unless File.dir?(dir) do
Mix.shell().info(
"Directory #{dir} does not exist. Run `mix firebird.target.compile` first."
)
:ok
else
Mix.shell().info("πŸ” Verifying WASM modules in #{dir}/")
Mix.shell().info("")
case Firebird.Target.Verify.verify_dir(dir) do
{:ok, reports} ->
if Enum.empty?(reports) do
Mix.shell().info(" No WASM files found in #{dir}/")
else
if json_mode do
data =
Enum.map(reports, fn r ->
%{file: r.file, valid: r.result.valid, exports: r.result.export_count}
end)
Mix.shell().info(Jason.encode!(data, pretty: true))
else
Enum.each(reports, fn r ->
basename = Path.basename(r.file)
status = if r.result.valid, do: "βœ…", else: "❌"
Mix.shell().info(" #{status} #{basename}")
if verbose do
Mix.shell().info(Firebird.Target.Verify.format_report(r.result))
else
Mix.shell().info(" Exports: #{r.result.export_count}")
end
Mix.shell().info("")
end)
valid = Enum.count(reports, & &1.result.valid)
total = length(reports)
Mix.shell().info("πŸ“Š #{valid}/#{total} modules verified successfully")
end
end
{:error, reason} ->
Mix.shell().error(" Error: #{inspect(reason)}")
end
end
end
end