diff --git a/src/forge/hb_packager.erl b/src/forge/hb_packager.erl index eee6cb9a7..c6c690114 100644 --- a/src/forge/hb_packager.erl +++ b/src/forge/hb_packager.erl @@ -31,6 +31,7 @@ -export([scan/2, scan/1]). -export([package/2, package_all/2, group_device_name/1]). -export([spec_message/2, impl_message/3]). +-export([require_spec_bodies/1]). -export([format_error/1]). -include("include/hb.hrl"). @@ -333,6 +334,17 @@ package(#{ root := Root, root_file := RootFile, helpers := Helpers, Pkg end. +%% @doc Require packaged devices to have a non-empty specification body before +%% publishing through paths that upload the spec as signed item data. +require_spec_bodies(Pkgs) -> + lists:foreach(fun require_spec_body/1, Pkgs), + Pkgs. + +require_spec_body(#{ device_name := Name, spec_body := <<>> }) -> + erlang:error({empty_device_specification, Name}); +require_spec_body(_Pkg) -> + ok. + %% @doc The device name (`name@version') a scanned group implements, %% without packaging it. Build tooling uses this to correlate a source %% group with its package. @@ -618,6 +630,11 @@ format_error({device_compile_failed, Device, Path, Errors, Warnings}) -> compile_messages("", Errors), compile_messages("Warning: ", Warnings) ]; +format_error({empty_device_specification, Name}) -> + io_lib:format( + "Device specification body is empty for ~ts. Add a leading %%% @doc block or -specification(\"path\") before publishing.", + [hb_util:list(Name)] + ); format_error(Reason) -> io_lib:format("~p", [Reason]). diff --git a/src/forge/plugin/src/hb_forge_args.erl b/src/forge/plugin/src/hb_forge_args.erl index 65abc6277..3c6be7321 100644 --- a/src/forge/plugin/src/hb_forge_args.erl +++ b/src/forge/plugin/src/hb_forge_args.erl @@ -142,6 +142,8 @@ run_provider(State, Module, Fun) when is_function(Fun, 1) -> try Fun(State) catch error:{device_compile_failed, _, _, _, _} = Reason -> + {error, hb_packager:format_error(Reason)}; + error:{empty_device_specification, _} = Reason -> {error, hb_packager:format_error(Reason)} end end. diff --git a/src/forge/plugin/src/hb_forge_publish.erl b/src/forge/plugin/src/hb_forge_publish.erl index f63dbabe6..958f5eaae 100644 --- a/src/forge/plugin/src/hb_forge_publish.erl +++ b/src/forge/plugin/src/hb_forge_publish.erl @@ -78,9 +78,11 @@ publish(State) -> [Action, maps:get(device_name, Pkg), SpecID, ImplID, Signer] ) end, - hb_packager:package_all( - hb_forge_args:scan_devices(Args), - NodeOpts + hb_packager:require_spec_bodies( + hb_packager:package_all( + hb_forge_args:scan_devices(Args), + NodeOpts + ) ) ), {ok, State}.