فهرست منبع

Merge pull request #9 from JimMoen/feat/validate-avsc-and-i18n

feat: make avsc and i18n valid
JimMoen 1 سال پیش
والد
کامیت
de09131fe6
4فایلهای تغییر یافته به همراه50 افزوده شده و 8 حذف شده
  1. 1 1
      .github/workflows/erlang.yml
  2. 7 2
      rebar.config
  3. 3 1
      src/emqx_plugrel.app.src
  4. 39 4
      src/emqx_plugrel.erl

+ 1 - 1
.github/workflows/erlang.yml

@@ -13,7 +13,7 @@ jobs:
     runs-on: ubuntu-latest
 
     container:
-      image: erlang:23
+      image: erlang:26
 
     steps:
     - uses: actions/checkout@v2

+ 7 - 2
rebar.config

@@ -1,2 +1,7 @@
-{erl_opts, [debug_info]}.
-{deps, [jsx]}.
+%% -*- mode: erlang -*-
+
+{erl_opts, [debug_info, {feature, maybe_expr, enable}]}.
+
+{deps, [
+    {erlavro, {git, "https://github.com/emqx/erlavro.git", {tag, "2.10.0"}}}
+]}.

+ 3 - 1
src/emqx_plugrel.app.src

@@ -4,7 +4,9 @@
   {registered, []},
   {applications,
    [kernel,
-    stdlib
+    stdlib,
+    jsone,
+    erlavro
    ]},
   {env,[]},
   {modules, []},

+ 39 - 4
src/emqx_plugrel.erl

@@ -45,7 +45,7 @@ do(State) ->
     end,
     {ok, State}.
 
--spec format_error(any()) ->  iolist().
+-spec format_error(any()) -> iolist().
 format_error(Reason) ->
     io_lib:format("~p", [Reason]).
 
@@ -121,7 +121,7 @@ make_tar(#{name := Name, rel_vsn := Vsn, rel_apps := Apps} = Info, State) ->
     ok = filelib:ensure_dir(InfoFile),
     ok = maybe_copy_files(LibDir),
     %% write info file
-    ok = file:write_file(InfoFile, jsx:encode(Info, [space, {indent, 4}])),
+    ok = file:write_file(InfoFile, jsone:encode(Info, [native_forward_slash, {space, 1}, {indent, 4}])),
     %% copy apps to lib dir
     Sources = lists:map(fun(App) -> filename:join([BaseDir, "rel", Name, "lib", App]) end, Apps),
     ok = rebar_file_utils:cp_r(Sources, LibDir),
@@ -146,8 +146,11 @@ do_make_tar(Cwd, NameWithVsn) ->
 maybe_copy_files(LibDir) ->
     lists:foreach(
         fun(F) ->
-            case file:read_file_info(F) of
-                {ok, _} -> rebar_file_utils:cp_r([F], LibDir);
+            maybe
+                true ?= filelib:is_regular(F),
+                true ?= validate_file(F), %% validate only when file existed
+                rebar_file_utils:cp_r([F], LibDir)
+            else
                 _ -> ok
             end
         end,
@@ -158,6 +161,38 @@ maybe_copy_files(LibDir) ->
     ),
     ok.
 
+validate_file(?plugin_avsc_file = F) ->
+    validate_avsc(F);
+validate_file(?plugin_i18n_file = F) ->
+    validate_i18n(F);
+validate_file(F) ->
+    ?LOG(debug, "Skipping validate file ~ts", [F]),
+    true.
+
+validate_avsc(F) ->
+    {ok, Bin} = file:read_file(F),
+    try avro:decode_schema(Bin) of
+        _ ->
+            ?LOG(debug, "Valid AVRO schema file: ~ts", [F]),
+            true
+    catch
+        E : R : S ->
+            ?LOG(error, "Invalid AVRO schema file. Error = ~p, Reason = ~p, Stacktrace=~p", [E, R, S]),
+            error({failed_to_validate_avsc_file, F})
+    end.
+
+validate_i18n(F) ->
+    {ok, Bin} = file:read_file(F),
+    try jsone:decode(Bin, [{object_format, map}]) of
+        _ ->
+            ?LOG(debug, "Valid i18n file: ~ts", [F]),
+            true
+    catch
+        E : R : S ->
+            ?LOG(error, "Invalid i18n json file. Error = ~p, Reason = ~p, Stacktrace=~p", [E, R, S]),
+            error({failed_to_validate_i18n_file, F})
+    end.
+
 bin(X) -> iolist_to_binary(X).
 
 str_list(L) -> lists:map(fun bin/1, L).