/src/etcher_loader.erl

http://github.com/jinsky/etcher · Erlang · 111 lines · 62 code · 10 blank · 39 comment · 0 complexity · cfaa84beeda7b89513f20237ea3b0b94 MD5 · raw file

  1. %%%-------------------------------------------------------------------
  2. %%% File : etcher_loader.erl
  3. %%% Project : Etcher (http://github.com/jinsky/etcher)
  4. %%% Author : Rory Byrne <rory [at] jinsky [dot] com>
  5. %%% License : BSD
  6. %%%
  7. %%% Copyright (c) 2010 Rory Byrne
  8. %%%
  9. %%% Redistribution and use in source and binary forms, with or without
  10. %%% modification, are permitted provided that the following conditions
  11. %%% are met:
  12. %%%
  13. %%% * Redistributions of source code must retain the above copyright
  14. %%% notice, this list of conditions and the following disclaimer.
  15. %%%
  16. %%% * Redistributions in binary form must reproduce the above
  17. %%% copyright notice, this list of conditions and the following
  18. %%% disclaimer in the documentation and/or other materials provided
  19. %%% with the distribution.
  20. %%%
  21. %%% * Neither the names of the copyright holders, nor the names of its
  22. %%% contributors may be used to endorse or promote products derived
  23. %%% from this software without specific prior written permission.
  24. %%%
  25. %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. %%% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. %%% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. %%% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. %%% OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. %%% SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. %%% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. %%% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. %%% THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. %%% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. %%% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. %%%-------------------------------------------------------------------
  37. -module(etcher_loader).
  38. -export([get_template/2,
  39. file_loader/2
  40. ]).
  41. -include("internal.hrl").
  42. get_template(#ps{template_loaders=TemplateLoaders} = PS, Path) ->
  43. load_and_compile(TemplateLoaders, Path, PS);
  44. get_template(#rs{compiler_opts=CompilerOpts}, Path) ->
  45. TemplateLoaders = proplists:get_value(template_loaders, CompilerOpts, []),
  46. load_and_compile(TemplateLoaders, Path, CompilerOpts).
  47. load_and_compile(TemplateLoaders, Path, CompilerArg) ->
  48. case load_template(TemplateLoaders, Path) of
  49. #etcher_template{} = Tpl ->
  50. Tpl;
  51. undefined ->
  52. undefined;
  53. Bin when is_binary(Bin) ->
  54. try binary_to_term(Bin) of
  55. #etcher_template{} = Tpl ->
  56. Tpl;
  57. BadTerm ->
  58. {error, {non_template_term, BadTerm}}
  59. catch
  60. error:badarg ->
  61. compile_template(Bin, CompilerArg)
  62. end;
  63. CharData when is_list(CharData) ->
  64. compile_template(CharData, CompilerArg)
  65. end.
  66. compile_template(CharData, CompilerArg) ->
  67. {ok, Tpl} = etcher_compiler:compile(CharData, CompilerArg),
  68. Tpl.
  69. load_template([{file, Args} | Rest], Path) ->
  70. load_template([{?MODULE, file_loader, Args} | Rest], Path);
  71. load_template([{Mod, Fun, Args} | Rest], Path) when is_list(Args) ->
  72. case Mod:Fun(Path, Args) of
  73. undefined ->
  74. load_template(Rest, Path);
  75. T ->
  76. T
  77. end;
  78. load_template([], _Path) ->
  79. undefined.
  80. %%------------------------------------------------------------------------
  81. %% Template File Loader
  82. %%------------------------------------------------------------------------
  83. file_loader(Path, TemplateDirs) ->
  84. case etcher_util:normalize_relative_path(Path) of
  85. illegal ->
  86. undefined;
  87. Path1 ->
  88. find_file(TemplateDirs, Path1)
  89. end.
  90. find_file(["/" ++ _ = Dir | Rest], Path) ->
  91. FileName = filename:join(Dir, Path),
  92. case file:read_file(FileName) of
  93. {ok, Bin} ->
  94. Bin;
  95. {error, _} ->
  96. find_file(Rest, Path)
  97. end;
  98. find_file([_ | Rest], Path) ->
  99. find_file(Rest, Path); % Ignore non-absolute template dirs
  100. find_file([], _Path) ->
  101. undefined.