簡體   English   中英

如何在Elixir中基於命令行args加載配置文件

[英]How to load config file based on command line args in Elixir

如何使用提供的命令行標志覆蓋Elixir中的配置? 例如,通過運行以下命令啟動應用程序:

./my_app --mode=mode1 or ./my_app --mode=mode2

根據提供的模式,我想用mode1.exsmode2.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"

在編譯時使用Env變量

根據不同的命令行參數使用不同的配置的問題是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

您現在可以通過兩種方式設置(和獲取)模式:

可以使用定制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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM