Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Elixir中基于命令行参数加载配置文件_Elixir - Fatal编程技术网

如何在Elixir中基于命令行参数加载配置文件

如何在Elixir中基于命令行参数加载配置文件,elixir,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" impor

如何使用提供的命令行标志覆盖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"
在编译时使用Env变量 基于不同的命令行参数进行不同配置的问题在于Elixir应用程序是编译的,因此,一旦打包应用程序,它将只包含编译时指定的模式的配置

如果这不是问题,并且您仍然希望使用单独的配置,那么最好使用环境变量而不是命令行标志

使用Mix.Config
#获取应用程序模式
默认模式=“1”
app_mode=System.get_env(“app_mode”)|默认_mode
mode_config=“mode#{app_mode}.exs”
#加载外部配置
导入配置(“#{Mix.env}.exs”)
导入配置(模式配置)
现在只需通过环境变量传递模式:

$APP_MODE=1混合运行
在编译时使用Env变量 基于不同的命令行参数进行不同配置的问题在于Elixir应用程序是编译的,因此,一旦打包应用程序,它将只包含编译时指定的模式的配置

如果这不是问题,并且您仍然希望使用单独的配置,那么最好使用环境变量而不是命令行标志

使用Mix.Config
#获取应用程序模式
默认模式=“1”
app_mode=System.get_env(“app_mode”)|默认_mode
mode_config=“mode#{app_mode}.exs”
#加载外部配置
导入配置(“#{Mix.env}.exs”)
导入配置(模式配置)
现在只需通过环境变量传递模式:

$APP_MODE=1混合运行
切换是动态配置的 正如我在另一个答案中提到的,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
现在,您可以通过两种方式设置(和获取)模式:

  • 命令行参数:使用
  • 环境变量:使用
可以使用自定义配置模块加载适当的配置:

# App started in Mode 2
MyApp.ModeConfig.get(:x)       # => 6

# App started in Mode 1
MyApp.ModeConfig.get(:y)       # => 2

注意:如果您的应用程序变得更复杂(OTP和流程),您甚至可以拥有对应于每个模式的不同“适配器”,并在启动应用程序监控树时切换到相应的适配器。

动态配置切换 正如我在另一个答案中提到的,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
现在,您可以通过两种方式设置(和获取)模式:

  • 命令行参数:使用
  • 环境变量:使用
可以使用自定义配置模块加载适当的配置:

# App started in Mode 2
MyApp.ModeConfig.get(:x)       # => 6

# App started in Mode 1
MyApp.ModeConfig.get(:y)       # => 2


注意:如果您的应用程序变得更复杂(OTP和进程),您甚至可以拥有对应于每个模式的不同“适配器”,并在启动应用程序监控树时切换到相应的适配器。

解析您使用的命令行参数

要覆盖配置文件中的值,应该使用,因为配置文件是在编译时加载和处理的,甚至更多,
Mix.config
以及整个
Mix
应用程序在生产中不存在。因此,无论您选择这种方法,您要么将
mix
应用程序带到
prod
(不推荐也不鼓励),要么自己解析
modeN
文件并手动更新应用程序环境

该主题已经出现在Elixir社区中,核心团队非常清楚使用编译时配置的缺点


目前最好的解决方案(在我们得到合适的解决方案之前)是使用系统环境而不是配置和/或引入您自己的JSON/YAML配置。

来解析您使用的命令行参数

要覆盖配置文件中的值,应该使用,因为配置文件是在编译时加载和处理的,甚至更多,
Mix.config
以及整个
Mix
应用程序在生产中不存在。因此,无论您选择这种方法,您要么将
mix
应用程序带到
prod
(不推荐也不鼓励),要么自己解析
modeN
文件并手动更新应用程序环境

该主题已经出现在Elixir社区中,核心团队非常清楚使用编译时配置的缺点


目前最好的解决方案(直到我们得到合适的解决方案)将使用系统环境而不是配置和/或引入您自己的JSON/YAML配置。

您可以使用MIX_ENV=foo MIX run吗?您可以,但最好为MIX环境和其他应用程序标志使用不同的环境变量。@Botonomous我同意Sheharyar的观点。如果我们保持应用程序标志和MIX.EnV的不同,这样的应用程序就可以在不同的环境中部署,比如在DEV、QA、测试、阶段和PRD中基于所需的应用标志。@ SheshankKodam考虑接受我的答案,如果它是HEL的话。