[英]How to load config file based on command line args in Elixir
如何使用提供的命令行標志覆蓋Elixir中的配置? 例如,通過運行以下命令啟動應用程序:
./my_app --mode=mode1 or ./my_app --mode=mode2
根據提供的模式,我想用mode1.exs
或mode2.exs
覆蓋config.exs
,如下所示
use Mix.Config
# Configures the endpoint
config :my_app,
env: Mix.env
import_config "#{Mix.env}.exs"
import_config "mode1.exs" or import_config "mode2.exs"
根據不同的命令行參數使用不同的配置的問題是Elixir應用程序已編譯,因此打包該應用程序后,它將僅包含在編譯時指定的模式的配置。
如果這不是問題,並且您仍想使用單獨的配置,則最好使用環境變量而不是命令行標志。
use Mix.Config
# Get the Application Mode
default_mode = "1"
app_mode = System.get_env("APP_MODE") || default_mode
mode_config = "mode#{app_mode}.exs"
# Load external configs
import_config("#{Mix.env}.exs")
import_config(mode_config)
現在只需通過環境變量傳遞模式:
$ APP_MODE=1 mix run
就像我在其他答案中提到的那樣,Elixir應用程序已編譯,因此一旦打包了該應用程序,它將僅包含該模式的配置。 更好的解決方案是將所有模式的配置保持在一起,並在應用程序中動態加載適當的配置。
您的config.exs
文件如下所示:
use Mix.Config
config :my_app, :app_modes,
default: :mode_1
config :my_app, :mode_1,
x: 1, y: 2, z: 3
config :my_app, :mode_2,
x: 6, y: 7, z: 8
您可以使用自定義ModeConfig
模塊來加載模式配置:
defmodule MyApp.ModeConfig do
@default_mode Application.get_env(:my_app, :app_modes)[:default_mode]
# Get App Mode
def mode do
passed_mode = System.get_env("APP_MODE")
# or you can use OptionParser for command-line flags
String.to_atom(passed_mode) || @default_mode
end
def get, do: Application.get_env(:my_app, mode())
def get(key), do: get()[key]
end
您現在可以通過兩種方式設置(和獲取)模式:
OptionParser.parse/2
System.get_env/1
可以使用定制Config模塊加載適當的配置:
# App started in Mode 2
MyApp.ModeConfig.get(:x) # => 6
# App started in Mode 1
MyApp.ModeConfig.get(:y) # => 2
注意:如果您的應用程序變得更加復雜(OTP和流程),則您甚至可能具有與每種模式相對應的不同“適配器”,並在應用程序監視樹的啟動期間切換到適當的適配器。
要解析命令行參數,可以使用OptionParser
。
要覆蓋配置文件中的值,應使用Application.put_env/4
,因為配置文件是在編譯時加載和處理的 ,甚至更多, Mix.Config
在生產中不存在 Mix.Config
以及整個Mix
應用程序。 因此,無論您選擇這種方法,都是將mix
應用程序引入prod
(不推薦使用,強烈建議不modeN
),或者自己解析您的modeN
文件並手動更新應用程序環境。
該主題已經在Elixir社區中進行了廣泛討論 ,並且核心團隊非常了解使用編譯時配置的弊端。
目前最好的解決方案(直到有合適的解決方案為止)是使用系統環境而不是配置和/或引入自己的JSON / YAML配置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.