1## This Source Code Form is subject to the terms of the Mozilla Public 2## License, v. 2.0. If a copy of the MPL was not distributed with this 3## file, You can obtain one at https://mozilla.org/MPL/2.0/. 4## 5## Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. 6 7defmodule RabbitMQ.CLI.Core.CodePath do 8 alias RabbitMQ.CLI.Core.{Config, Paths, Platform} 9 10 def add_plugins_to_load_path(opts) do 11 with {:ok, plugins_dir} <- Paths.plugins_dir(opts) do 12 String.split(to_string(plugins_dir), Platform.path_separator()) 13 |> Enum.map(&add_directory_plugins_to_load_path/1) 14 15 :ok 16 end 17 end 18 19 def add_directory_plugins_to_load_path(directory_with_plugins_inside_it) do 20 with {:ok, files} <- File.ls(directory_with_plugins_inside_it) do 21 Enum.map( 22 files, 23 fn filename -> 24 cond do 25 String.ends_with?(filename, [".ez"]) -> 26 Path.join([directory_with_plugins_inside_it, filename]) 27 |> String.to_charlist() 28 |> add_archive_code_path() 29 30 File.dir?(filename) -> 31 Path.join([directory_with_plugins_inside_it, filename]) 32 |> add_dir_code_path() 33 34 true -> 35 {:error, {:not_a_plugin, filename}} 36 end 37 end 38 ) 39 end 40 end 41 42 defp add_archive_code_path(ez_dir) do 43 case :erl_prim_loader.list_dir(ez_dir) do 44 {:ok, [app_dir]} -> 45 app_in_ez = :filename.join(ez_dir, app_dir) 46 add_dir_code_path(app_in_ez) 47 48 _ -> 49 {:error, :no_app_dir} 50 end 51 end 52 53 defp add_dir_code_path(app_dir_0) do 54 app_dir = to_charlist(app_dir_0) 55 56 case :erl_prim_loader.list_dir(app_dir) do 57 {:ok, list} -> 58 case Enum.member?(list, 'ebin') do 59 true -> 60 ebin_dir = :filename.join(app_dir, 'ebin') 61 Code.append_path(ebin_dir) 62 63 false -> 64 {:error, :no_ebin} 65 end 66 67 _ -> 68 {:error, :app_dir_empty} 69 end 70 end 71 72 def require_rabbit_and_plugins(_, opts) do 73 require_rabbit_and_plugins(opts) 74 end 75 76 def require_rabbit_and_plugins(opts) do 77 with :ok <- require_rabbit(opts), 78 :ok <- add_plugins_to_load_path(opts), 79 do: :ok 80 end 81 82 def require_rabbit(_, opts) do 83 require_rabbit(opts) 84 end 85 86 def require_rabbit(opts) do 87 home = Config.get_option(:rabbitmq_home, opts) 88 89 case home do 90 nil -> 91 {:error, {:unable_to_load_rabbit, :rabbitmq_home_is_undefined}} 92 93 _ -> 94 case Application.load(:rabbit) do 95 :ok -> 96 Code.ensure_loaded(:rabbit_plugins) 97 :ok 98 99 {:error, {:already_loaded, :rabbit}} -> 100 Code.ensure_loaded(:rabbit_plugins) 101 :ok 102 103 {:error, err} -> 104 {:error, {:unable_to_load_rabbit, err}} 105 end 106 end 107 end 108end 109