1defmodule Application do
2  @moduledoc """
3  A module for working with applications and defining application callbacks.
4
5  Applications are the idiomatic way to package software in Erlang/OTP. To get
6  the idea, they are similar to the "library" concept common in other
7  programming languages, but with some additional characteristics.
8
9  An application is a component implementing some specific functionality, with a
10  standardized directory structure, configuration, and life cycle. Applications
11  are *loaded*, *started*, and *stopped*. Each application also has its own
12  environment, which provides a unified API for configuring each application.
13
14  Developers typically interact with the application environment and its
15  callback module. Therefore those will be the topics we will cover first
16  before jumping into details about the application resource file and life-cycle.
17
18  ## The application environment
19
20  Each application has its own environment. The environment is a keyword list
21  that maps atoms to terms. Note that this environment is unrelated to the
22  operating system environment.
23
24  By default, the environment of an application is an empty list. In a Mix
25  project's `mix.exs` file, you can set the `:env` key in `application/0`:
26
27      def application do
28        [env: [db_host: "localhost"]]
29      end
30
31  Now, in your application, you can read this environment by using functions
32  such as `fetch_env!/2` and friends:
33
34      defmodule MyApp.DBClient do
35        def start_link() do
36          SomeLib.DBClient.start_link(host: db_host())
37        end
38
39        defp db_host do
40          Application.fetch_env!(:my_app, :db_host)
41        end
42      end
43
44  In Mix projects, the environment of the application and its dependencies can
45  be overridden via the `config/config.exs` file. For example, someone using
46  your application can override its `:db_host` environment variable as follows:
47
48      import Config
49      config :my_app, :db_host, "db.local"
50
51  You can also change the application environment dynamically by using functions
52  such as `put_env/3` and `delete_env/2`. However, as a rule of thumb, each application
53  is responsible for its own environment. Please do not use the functions in this
54  module for directly accessing or modifying the environment of other applications.
55
56  ### Compile-time environment
57
58  In the previous example, we read the application environment at runtime:
59
60      defmodule MyApp.DBClient do
61        def start_link() do
62          SomeLib.DBClient.start_link(host: db_host())
63        end
64
65        defp db_host do
66          Application.fetch_env!(:my_app, :db_host)
67        end
68      end
69
70  In other words, the environment key `:db_host` for application `:my_app`
71  will only be read when `MyApp.DBClient` effectively starts. While reading
72  the application environment at runtime is the preferred approach, in some
73  rare occasions you may want to use the application environment to configure
74  the compilation of a certain project. This is often done by calling `get_env/3`
75  outside of a function:
76
77      defmodule MyApp.DBClient do
78        @db_host Application.get_env(:my_app, :db_host, "db.local")
79
80        def start_link() do
81          SomeLib.DBClient.start_link(host: @db_host)
82        end
83      end
84
85  This approach has one big limitation: if you change the value of the
86  application environment after the code is compiled, the value used at
87  runtime is not going to change! For example, if your `config/runtime.exs`
88  has:
89
90      config :my_app, :db_host, "db.production"
91
92  This value will have no effect as the code was compiled to connect to "db.local",
93  which is mostly likely unavailable in the production environment.
94
95  For those reasons, reading the application environment at runtime should be the
96  first choice. However, if you really have to read the application environment
97  during compilation, we recommend you to use `compile_env/3` instead:
98
99      @db_host Application.compile_env(:my_app, :db_host, "db.local")
100
101  By using `compile_env/3`, tools like Mix will store the values used during
102  compilation and compare the compilation values with the runtime values whenever
103  your system starts, raising an error in case they differ.
104
105  ## The application callback module
106
107  Applications can be loaded, started, and stopped. Generally, build tools
108  like Mix take care of starting an application and all of its dependencies
109  for you, but you can also do it manually by calling:
110
111      {:ok, _} = Application.ensure_all_started(:some_app)
112
113  When an application starts, developers may configure a callback module
114  that executes custom code. Developers use this callback to start the
115  application supervision tree.
116
117  The first step to do so is to add a `:mod` key to the `application/0`
118  definition in your `mix.exs` file. It expects a tuple, with the application
119  callback module and start argument (commonly an empty list):
120
121      def application do
122        [mod: {MyApp, []}]
123      end
124
125  The `MyApp` module given to `:mod` needs to implement the `Application` behaviour.
126  This can be done by putting `use Application` in that module and implementing the
127  `c:start/2` callback, for example:
128
129      defmodule MyApp do
130        use Application
131
132        def start(_type, _args) do
133          children = []
134          Supervisor.start_link(children, strategy: :one_for_one)
135        end
136      end
137
138  The `c:start/2` callback has to spawn and link a supervisor and return `{:ok,
139  pid}` or `{:ok, pid, state}`, where `pid` is the PID of the supervisor, and
140  `state` is an optional application state. `args` is the second element of the
141  tuple given to the `:mod` option.
142
143  The `type` argument passed to `c:start/2` is usually `:normal` unless in a
144  distributed setup where application takeovers and failovers are configured.
145  Distributed applications are beyond the scope of this documentation.
146
147  When an application is shutting down, its `c:stop/1` callback is called after
148  the supervision tree has been stopped by the runtime. This callback allows the
149  application to do any final cleanup. The argument is the state returned by
150  `c:start/2`, if it did, or `[]` otherwise. The return value of `c:stop/1` is
151  ignored.
152
153  By using `Application`, modules get a default implementation of `c:stop/1`
154  that ignores its argument and returns `:ok`, but it can be overridden.
155
156  Application callback modules may also implement the optional callback
157  `c:prep_stop/1`. If present, `c:prep_stop/1` is invoked before the supervision
158  tree is terminated. Its argument is the state returned by `c:start/2`, if it did,
159  or `[]` otherwise, and its return value is passed to `c:stop/1`.
160
161  ## The application resource file
162
163  In the sections above, we have configured an application in the
164  `application/0` section of the `mix.exs` file. Ultimately, Mix will use
165  this configuration to create an [*application resource
166  file*](https://erlang.org/doc/man/application.html), which is a file called
167  `APP_NAME.app`. For example, the application resource file of the OTP
168  application `ex_unit` is called `ex_unit.app`.
169
170  You can learn more about the generation of application resource files in
171  the documentation of `Mix.Tasks.Compile.App`, available as well by running
172  `mix help compile.app`.
173
174  ## The application life cycle
175
176  ### Loading applications
177
178  Applications are *loaded*, which means that the runtime finds and processes
179  their resource files:
180
181      Application.load(:ex_unit)
182      #=> :ok
183
184  When an application is loaded, the environment specified in its resource file
185  is merged with any overrides from config files.
186
187  Loading an application *does not* load its modules.
188
189  In practice, you rarely load applications by hand because that is part of the
190  start process, explained next.
191
192  ### Starting applications
193
194  Applications are also *started*:
195
196      Application.start(:ex_unit)
197      #=> :ok
198
199  Once your application is compiled, running your system is a matter of starting
200  your current application and its dependencies. Differently from other languages,
201  Elixir does not have a `main` procedure that is responsible for starting your
202  system. Instead, you start one or more applications, each with their own
203  initialization and termination logic.
204
205  When an application is started, the `Application.load/1` is automatically
206  invoked if it hasn't been done yet. Then, it checks if the dependencies listed
207  in the `applications` key of the resource file are already started. Having at
208  least one dependency not started is an error condition. Functions like
209  `ensure_all_started/1` takes care of starting an application and all of its
210  dependencies for you.
211
212  If the application does not have a callback module configured, starting is
213  done at this point. Otherwise, its `c:start/2` callback is invoked. The PID of
214  the top-level supervisor returned by this function is stored by the runtime
215  for later use, and the returned application state is saved too, if any.
216
217  ### Stopping applications
218
219  Started applications are, finally, *stopped*:
220
221      Application.stop(:ex_unit)
222      #=> :ok
223
224  Stopping an application without a callback module is defined, but except for
225  some system tracing, it is in practice a no-op.
226
227  Stopping an application with a callback module has three steps:
228
229    1. If present, invoke the optional callback `c:prep_stop/1`.
230    2. Terminate the top-level supervisor.
231    3. Invoke the required callback `c:stop/1`.
232
233  The arguments passed to the callbacks are related to the state optionally
234  returned by `c:start/2`, and are documented in the section about the callback
235  module above.
236
237  It is important to highlight that step 2 is a blocking one. Termination of a
238  supervisor triggers a recursive chain of children terminations, therefore
239  orderly shutting down all descendant processes. The `c:stop/1` callback is
240  invoked only after termination of the whole supervision tree.
241
242  Shutting down a live system cleanly can be done by calling `System.stop/1`. It
243  will shut down every application in the opposite order they had been started.
244
245  By default, a SIGTERM from the operating system will automatically translate to
246  `System.stop/0`. You can also have more explicit control over operating system
247  signals via the `:os.set_signal/2` function.
248
249  ## Tooling
250
251  The Mix build tool automates most of the application management tasks. For example,
252  `mix test` automatically starts your application dependencies and your application
253  itself before your test runs. `mix run --no-halt` boots your current project and
254  can be used to start a long running system. See `mix help run`.
255
256  Developers can also use `mix release` to build **releases**. Releases are able to
257  package all of your source code as well as the Erlang VM into a single directory.
258  Releases also give you explicit control over how each application is started and in
259  which order. They also provide a more streamlined mechanism for starting and
260  stopping systems, debugging, logging, as well as system monitoring.
261
262  Finally, Elixir provides tools such as escripts and archives, which are
263  different mechanisms for packaging your application. Those are typically used
264  when tools must be shared between developers and not as deployment options.
265  See `mix help archive.build` and `mix help escript.build` for more detail.
266
267  ## Further information
268
269  For further details on applications please check the documentation of the
270  [`:application` Erlang module](`:application`), and the
271  [Applications](https://erlang.org/doc/design_principles/applications.html)
272  section of the [OTP Design Principles User's
273  Guide](https://erlang.org/doc/design_principles/users_guide.html).
274  """
275
276  @doc """
277  Called when an application is started.
278
279  This function is called when an application is started using
280  `Application.start/2` (and functions on top of that, such as
281  `Application.ensure_started/2`). This function should start the top-level
282  process of the application (which should be the top supervisor of the
283  application's supervision tree if the application follows the OTP design
284  principles around supervision).
285
286  `start_type` defines how the application is started:
287
288    * `:normal` - used if the startup is a normal startup or if the application
289      is distributed and is started on the current node because of a failover
290      from another node and the application specification key `:start_phases`
291      is `:undefined`.
292    * `{:takeover, node}` - used if the application is distributed and is
293      started on the current node because of a failover on the node `node`.
294    * `{:failover, node}` - used if the application is distributed and is
295      started on the current node because of a failover on node `node`, and the
296      application specification key `:start_phases` is not `:undefined`.
297
298  `start_args` are the arguments passed to the application in the `:mod`
299  specification key (for example, `mod: {MyApp, [:my_args]}`).
300
301  This function should either return `{:ok, pid}` or `{:ok, pid, state}` if
302  startup is successful. `pid` should be the PID of the top supervisor. `state`
303  can be an arbitrary term, and if omitted will default to `[]`; if the
304  application is later stopped, `state` is passed to the `stop/1` callback (see
305  the documentation for the `c:stop/1` callback for more information).
306
307  `use Application` provides no default implementation for the `start/2`
308  callback.
309  """
310  @callback start(start_type, start_args :: term) ::
311              {:ok, pid}
312              | {:ok, pid, state}
313              | {:error, reason :: term}
314
315  @doc """
316  Called before stopping the application.
317
318  This function is called before the top-level supervisor is terminated. It
319  receives the state returned by `c:start/2`, if it did, or `[]` otherwise.
320  The return value is later passed to `c:stop/1`.
321  """
322  @callback prep_stop(state) :: state
323
324  @doc """
325  Called after an application has been stopped.
326
327  This function is called after an application has been stopped, i.e., after its
328  supervision tree has been stopped. It should do the opposite of what the
329  `c:start/2` callback did, and should perform any necessary cleanup. The return
330  value of this callback is ignored.
331
332  `state` is the state returned by `c:start/2`, if it did, or `[]` otherwise.
333  If the optional callback `c:prep_stop/1` is present, `state` is its return
334  value instead.
335
336  `use Application` defines a default implementation of this function which does
337  nothing and just returns `:ok`.
338  """
339  @callback stop(state) :: term
340
341  @doc """
342  Starts an application in synchronous phases.
343
344  This function is called after `start/2` finishes but before
345  `Application.start/2` returns. It will be called once for every start phase
346  defined in the application's (and any included applications') specification,
347  in the order they are listed in.
348  """
349  @callback start_phase(phase :: term, start_type, phase_args :: term) ::
350              :ok | {:error, reason :: term}
351
352  @doc """
353  Callback invoked after code upgrade, if the application environment
354  has changed.
355
356  `changed` is a keyword list of keys and their changed values in the
357  application environment. `new` is a keyword list with all new keys
358  and their values. `removed` is a list with all removed keys.
359  """
360  @callback config_change(changed, new, removed) :: :ok
361            when changed: keyword, new: keyword, removed: [atom]
362
363  @optional_callbacks start_phase: 3, prep_stop: 1, config_change: 3
364
365  @doc false
366  defmacro __using__(_) do
367    quote location: :keep do
368      @behaviour Application
369
370      @doc false
371      def stop(_state) do
372        :ok
373      end
374
375      defoverridable Application
376    end
377  end
378
379  @application_keys [
380    :description,
381    :id,
382    :vsn,
383    :modules,
384    :maxP,
385    :maxT,
386    :registered,
387    :included_applications,
388    :applications,
389    :mod,
390    :start_phases
391  ]
392
393  application_key_specs = Enum.reduce(@application_keys, &{:|, [], [&1, &2]})
394
395  @type app :: atom
396  @type key :: atom
397  @type application_key :: unquote(application_key_specs)
398  @type value :: term
399  @type state :: term
400  @type start_type :: :normal | {:takeover, node} | {:failover, node}
401  @type restart_type :: :permanent | :transient | :temporary
402
403  @doc """
404  Returns the spec for `app`.
405
406  The following keys are returned:
407
408    * #{Enum.map_join(@application_keys, "\n  * ", &"`#{inspect(&1)}`")}
409
410  Note the environment is not returned as it can be accessed via
411  `fetch_env/2`. Returns `nil` if the application is not loaded.
412  """
413  @spec spec(app) :: [{application_key, value}] | nil
414  def spec(app) when is_atom(app) do
415    case :application.get_all_key(app) do
416      {:ok, info} -> :lists.keydelete(:env, 1, info)
417      :undefined -> nil
418    end
419  end
420
421  @doc """
422  Returns the value for `key` in `app`'s specification.
423
424  See `spec/1` for the supported keys. If the given
425  specification parameter does not exist, this function
426  will raise. Returns `nil` if the application is not loaded.
427  """
428  @spec spec(app, application_key) :: value | nil
429  def spec(app, key) when is_atom(app) and key in @application_keys do
430    case :application.get_key(app, key) do
431      {:ok, value} -> value
432      :undefined -> nil
433    end
434  end
435
436  @doc """
437  Gets the application for the given module.
438
439  The application is located by analyzing the spec
440  of all loaded applications. Returns `nil` if
441  the module is not listed in any application spec.
442  """
443  @spec get_application(atom) :: atom | nil
444  def get_application(module) when is_atom(module) do
445    case :application.get_application(module) do
446      {:ok, app} -> app
447      :undefined -> nil
448    end
449  end
450
451  @doc """
452  Returns all key-value pairs for `app`.
453  """
454  @spec get_all_env(app) :: [{key, value}]
455  def get_all_env(app) when is_atom(app) do
456    :application.get_all_env(app)
457  end
458
459  @doc """
460  Reads the application environment at compilation time.
461
462  Similar to `get_env/3`, except it must be used to read values
463  at compile time. This allows Elixir to track when configuration
464  values change between compile time and runtime.
465
466  The first argument is the application name. The second argument
467  `key_or_path` is either an atom key or a path to traverse in
468  search of the configuration, starting with an atom key.
469
470  For example, imagine the following configuration:
471
472      config :my_app, :key, [foo: [bar: :baz]]
473
474  We can access it during compile time as:
475
476      Application.compile_env(:my_app, :key)
477      #=> [foo: [bar: :baz]]
478
479      Application.compile_env(:my_app, [:key, :foo])
480      #=> [bar: :baz]
481
482      Application.compile_env(:my_app, [:key, :foo, :bar])
483      #=> :baz
484
485  A default value can also be given as third argument. If
486  any of the keys in the path along the way is missing, the
487  default value is used:
488
489      Application.compile_env(:my_app, [:unknown, :foo, :bar], :default)
490      #=> :default
491
492      Application.compile_env(:my_app, [:key, :unknown, :bar], :default)
493      #=> :default
494
495      Application.compile_env(:my_app, [:key, :foo, :unknown], :default)
496      #=> :default
497
498  Giving a path is useful to let Elixir know that only certain paths
499  in a large configuration are compile time dependent.
500  """
501  # TODO: Warn on v1.14 if get_env/fetch_env/fetch_env! is used at
502  # compile time instead of compile_env
503  @doc since: "1.10.0"
504  @spec compile_env(app, key | list, value) :: value
505  defmacro compile_env(app, key_or_path, default \\ nil) when is_atom(app) do
506    if __CALLER__.function do
507      raise "Application.compile_env/3 cannot be called inside functions, only in the module body"
508    end
509
510    key_or_path = expand_key_or_path(key_or_path, __CALLER__)
511
512    quote do
513      Application.__compile_env__(unquote(app), unquote(key_or_path), unquote(default), __ENV__)
514    end
515  end
516
517  defp expand_key_or_path({:__aliases__, _, _} = alias, env),
518    do: Macro.expand(alias, %{env | function: {:__info__, 1}})
519
520  defp expand_key_or_path(list, env) when is_list(list),
521    do: Enum.map(list, &expand_key_or_path(&1, env))
522
523  defp expand_key_or_path(other, _env),
524    do: other
525
526  @doc false
527  def __compile_env__(app, key_or_path, default, env) do
528    case fetch_compile_env(app, key_or_path, env) do
529      {:ok, value} -> value
530      :error -> default
531    end
532  end
533
534  @doc """
535  Reads the application environment at compilation time or raises.
536
537  This is the same as `compile_env/3` but it raises an
538  `ArgumentError` if the configuration is not available.
539  """
540  @doc since: "1.10.0"
541  @spec compile_env!(app, key | list) :: value
542  defmacro compile_env!(app, key_or_path) when is_atom(app) do
543    if __CALLER__.function do
544      raise "Application.compile_env!/2 cannot be called inside functions, only in the module body"
545    end
546
547    key_or_path = expand_key_or_path(key_or_path, __CALLER__)
548
549    quote do
550      Application.__compile_env__!(unquote(app), unquote(key_or_path), __ENV__)
551    end
552  end
553
554  @doc false
555  def __compile_env__!(app, key_or_path, env) do
556    case fetch_compile_env(app, key_or_path, env) do
557      {:ok, value} ->
558        value
559
560      :error ->
561        raise ArgumentError,
562              "could not fetch application environment #{inspect(key_or_path)} for application " <>
563                "#{inspect(app)} #{fetch_env_failed_reason(app, key_or_path)}"
564    end
565  end
566
567  defp fetch_compile_env(app, key, env) when is_atom(key),
568    do: fetch_compile_env(app, key, [], env)
569
570  defp fetch_compile_env(app, [key | paths], env) when is_atom(key),
571    do: fetch_compile_env(app, key, paths, env)
572
573  defp fetch_compile_env(app, key, path, env) do
574    return = traverse_env(fetch_env(app, key), path)
575
576    for tracer <- env.tracers do
577      tracer.trace({:compile_env, app, [key | path], return}, env)
578    end
579
580    return
581  end
582
583  defp traverse_env(return, []), do: return
584  defp traverse_env(:error, _paths), do: :error
585  defp traverse_env({:ok, value}, [key | keys]), do: traverse_env(Access.fetch(value, key), keys)
586
587  @doc """
588  Returns the value for `key` in `app`'s environment.
589
590  If the configuration parameter does not exist, the function returns the
591  `default` value.
592
593  **Important:** if you are reading the application environment at compilation
594  time, for example, inside the module definition instead of inside of a
595  function, see `compile_env/3` instead.
596
597  **Important:** if you are writing a library to be used by other developers,
598  it is generally recommended to avoid the application environment, as the
599  application environment is effectively a global storage. For more information,
600  read our [library guidelines](library-guidelines.md).
601
602  ## Examples
603
604  `get_env/3` is commonly used to read the configuration of your OTP applications.
605  Since Mix configurations are commonly used to configure applications, we will use
606  this as a point of illustration.
607
608  Consider a new application `:my_app`. `:my_app` contains a database engine which
609  supports a pool of databases. The database engine needs to know the configuration for
610  each of those databases, and that configuration is supplied by key-value pairs in
611  environment of `:my_app`.
612
613      config :my_app, Databases.RepoOne,
614        # A database configuration
615        ip: "localhost",
616        port: 5433
617
618      config :my_app, Databases.RepoTwo,
619        # Another database configuration (for the same OTP app)
620        ip: "localhost",
621        port: 20717
622
623      config :my_app, my_app_databases: [Databases.RepoOne, Databases.RepoTwo]
624
625  Our database engine used by `:my_app` needs to know what databases exist, and
626  what the database configurations are. The database engine can make a call to
627  `get_env(:my_app, :my_app_databases)` to retrieve the list of databases (specified
628  by module names). Our database engine can then traverse each repository in the
629  list and then call `get_env(:my_app, Databases.RepoOne)` and so forth to retrieve
630  the configuration of each one.
631  """
632  @spec get_env(app, key, value) :: value
633  def get_env(app, key, default \\ nil) when is_atom(app) do
634    maybe_warn_on_app_env_key(app, key)
635    :application.get_env(app, key, default)
636  end
637
638  @doc """
639  Returns the value for `key` in `app`'s environment in a tuple.
640
641  If the configuration parameter does not exist, the function returns `:error`.
642  """
643  @spec fetch_env(app, key) :: {:ok, value} | :error
644  def fetch_env(app, key) when is_atom(app) do
645    maybe_warn_on_app_env_key(app, key)
646
647    case :application.get_env(app, key) do
648      {:ok, value} -> {:ok, value}
649      :undefined -> :error
650    end
651  end
652
653  @doc """
654  Returns the value for `key` in `app`'s environment.
655
656  If the configuration parameter does not exist, raises `ArgumentError`.
657
658  **Important:** if you are reading the application environment at compilation
659  time, for example, inside the module definition instead of inside of a
660  function, see `compile_env!/2` instead.
661  """
662  @spec fetch_env!(app, key) :: value
663  def fetch_env!(app, key) when is_atom(app) do
664    case fetch_env(app, key) do
665      {:ok, value} ->
666        value
667
668      :error ->
669        raise ArgumentError,
670              "could not fetch application environment #{inspect(key)} for application " <>
671                "#{inspect(app)} #{fetch_env_failed_reason(app, key)}"
672    end
673  end
674
675  defp fetch_env_failed_reason(app, key) do
676    vsn = :application.get_key(app, :vsn)
677
678    case vsn do
679      {:ok, _} ->
680        "because configuration at #{inspect(key)} was not set"
681
682      :undefined ->
683        "because the application was not loaded nor configured"
684    end
685  end
686
687  @doc """
688  Puts the `value` in `key` for the given `app`.
689
690  ## Options
691
692    * `:timeout` - the timeout for the change (defaults to `5_000` milliseconds)
693    * `:persistent` - persists the given value on application load and reloads
694
695  If `put_env/4` is called before the application is loaded, the application
696  environment values specified in the `.app` file will override the ones
697  previously set.
698
699  The `:persistent` option can be set to `true` when there is a need to guarantee
700  parameters set with this function will not be overridden by the ones defined
701  in the application resource file on load. This means persistent values will
702  stick after the application is loaded and also on application reload.
703  """
704  @spec put_env(app, key, value, timeout: timeout, persistent: boolean) :: :ok
705  def put_env(app, key, value, opts \\ []) when is_atom(app) do
706    maybe_warn_on_app_env_key(app, key)
707    :application.set_env(app, key, value, opts)
708  end
709
710  @doc """
711  Puts the environment for multiple apps at the same time.
712
713  The given config should not:
714
715    * have the same application listed more than once
716    * have the same key inside the same application listed more than once
717
718  If those conditions are not met, it will raise.
719
720  It receives the same options as `put_env/4`. Returns `:ok`.
721  """
722  @doc since: "1.9.0"
723  @spec put_all_env([{app, [{key, value}]}], timeout: timeout, persistent: boolean) :: :ok
724  def put_all_env(config, opts \\ []) when is_list(config) and is_list(opts) do
725    :application.set_env(config, opts)
726  end
727
728  @doc """
729  Deletes the `key` from the given `app` environment.
730
731  It receives the same options as `put_env/4`. Returns `:ok`.
732  """
733  @spec delete_env(app, key, timeout: timeout, persistent: boolean) :: :ok
734  def delete_env(app, key, opts \\ []) when is_atom(app) do
735    maybe_warn_on_app_env_key(app, key)
736    :application.unset_env(app, key, opts)
737  end
738
739  defp maybe_warn_on_app_env_key(_app, key) when is_atom(key),
740    do: :ok
741
742  # TODO: Remove this deprecation warning on 2.0+ and allow list lookups as in compile_env.
743  defp maybe_warn_on_app_env_key(app, key) do
744    message = "passing non-atom as application env key is deprecated, got: #{inspect(key)}"
745    IO.warn_once({Application, :key, app, key}, message, _stacktrace_drop_levels = 2)
746  end
747
748  @doc """
749  Ensures the given `app` is started.
750
751  Same as `start/2` but returns `:ok` if the application was already
752  started. This is useful in scripts and in test setup, where test
753  applications need to be explicitly started:
754
755      :ok = Application.ensure_started(:my_test_dep)
756
757  """
758  @spec ensure_started(app, restart_type) :: :ok | {:error, term}
759  def ensure_started(app, type \\ :temporary) when is_atom(app) do
760    :application.ensure_started(app, type)
761  end
762
763  @doc """
764  Ensures the given `app` is loaded.
765
766  Same as `load/2` but returns `:ok` if the application was already
767  loaded.
768  """
769  @doc since: "1.10.0"
770  @spec ensure_loaded(app) :: :ok | {:error, term}
771  def ensure_loaded(app) when is_atom(app) do
772    case :application.load(app) do
773      :ok -> :ok
774      {:error, {:already_loaded, ^app}} -> :ok
775      {:error, _} = error -> error
776    end
777  end
778
779  @doc """
780  Ensures the given `app` and its applications are started.
781
782  Same as `start/2` but also starts the applications listed under
783  `:applications` in the `.app` file in case they were not previously
784  started.
785  """
786  @spec ensure_all_started(app, restart_type) :: {:ok, [app]} | {:error, {app, term}}
787  def ensure_all_started(app, type \\ :temporary) when is_atom(app) do
788    :application.ensure_all_started(app, type)
789  end
790
791  @doc """
792  Starts the given `app`.
793
794  If the `app` is not loaded, the application will first be loaded using `load/1`.
795  Any included application, defined in the `:included_applications` key of the
796  `.app` file will also be loaded, but they won't be started.
797
798  Furthermore, all applications listed in the `:applications` key must be explicitly
799  started before this application is. If not, `{:error, {:not_started, app}}` is
800  returned, where `app` is the name of the missing application.
801
802  In case you want to automatically load **and start** all of `app`'s dependencies,
803  see `ensure_all_started/2`.
804
805  The `type` argument specifies the type of the application:
806
807    * `:permanent` - if `app` terminates, all other applications and the entire
808      node are also terminated.
809
810    * `:transient` - if `app` terminates with `:normal` reason, it is reported
811      but no other applications are terminated. If a transient application
812      terminates abnormally, all other applications and the entire node are
813      also terminated.
814
815    * `:temporary` - if `app` terminates, it is reported but no other
816      applications are terminated (the default).
817
818  Note that it is always possible to stop an application explicitly by calling
819  `stop/1`. Regardless of the type of the application, no other applications will
820  be affected.
821
822  Note also that the `:transient` type is of little practical use, since when a
823  supervision tree terminates, the reason is set to `:shutdown`, not `:normal`.
824  """
825  @spec start(app, restart_type) :: :ok | {:error, term}
826  def start(app, type \\ :temporary) when is_atom(app) do
827    :application.start(app, type)
828  end
829
830  @doc """
831  Stops the given `app`.
832
833  When stopped, the application is still loaded.
834  """
835  @spec stop(app) :: :ok | {:error, term}
836  def stop(app) when is_atom(app) do
837    :application.stop(app)
838  end
839
840  @doc """
841  Loads the given `app`.
842
843  In order to be loaded, an `.app` file must be in the load paths.
844  All `:included_applications` will also be loaded.
845
846  Loading the application does not start it nor load its modules, but
847  it does load its environment.
848  """
849  @spec load(app) :: :ok | {:error, term}
850  def load(app) when is_atom(app) do
851    :application.load(app)
852  end
853
854  @doc """
855  Unloads the given `app`.
856
857  It will also unload all `:included_applications`.
858  Note that the function does not purge the application modules.
859  """
860  @spec unload(app) :: :ok | {:error, term}
861  def unload(app) when is_atom(app) do
862    :application.unload(app)
863  end
864
865  @doc """
866  Gets the directory for app.
867
868  This information is returned based on the code path. Here is an
869  example:
870
871      File.mkdir_p!("foo/ebin")
872      Code.prepend_path("foo/ebin")
873      Application.app_dir(:foo)
874      #=> "foo"
875
876  Even though the directory is empty and there is no `.app` file
877  it is considered the application directory based on the name
878  "foo/ebin". The name may contain a dash `-` which is considered
879  to be the app version and it is removed for the lookup purposes:
880
881      File.mkdir_p!("bar-123/ebin")
882      Code.prepend_path("bar-123/ebin")
883      Application.app_dir(:bar)
884      #=> "bar-123"
885
886  For more information on code paths, check the `Code` module in
887  Elixir and also Erlang's [`:code` module](`:code`).
888  """
889  @spec app_dir(app) :: String.t()
890  def app_dir(app) when is_atom(app) do
891    case :code.lib_dir(app) do
892      lib when is_list(lib) -> IO.chardata_to_string(lib)
893      {:error, :bad_name} -> raise ArgumentError, "unknown application: #{inspect(app)}"
894    end
895  end
896
897  @doc """
898  Returns the given path inside `app_dir/1`.
899
900  If `path` is a string, then it will be used as the path inside `app_dir/1`. If
901  `path` is a list of strings, it will be joined (see `Path.join/1`) and the result
902  will be used as the path inside `app_dir/1`.
903
904  ## Examples
905
906      File.mkdir_p!("foo/ebin")
907      Code.prepend_path("foo/ebin")
908
909      Application.app_dir(:foo, "my_path")
910      #=> "foo/my_path"
911
912      Application.app_dir(:foo, ["my", "nested", "path"])
913      #=> "foo/my/nested/path"
914
915  """
916  @spec app_dir(app, String.t() | [String.t()]) :: String.t()
917  def app_dir(app, path)
918
919  def app_dir(app, path) when is_atom(app) and is_binary(path) do
920    Path.join(app_dir(app), path)
921  end
922
923  def app_dir(app, path) when is_atom(app) and is_list(path) do
924    Path.join([app_dir(app) | path])
925  end
926
927  @doc """
928  Returns a list with information about the applications which are currently running.
929  """
930  @spec started_applications(timeout) :: [{app, description :: charlist(), vsn :: charlist()}]
931  def started_applications(timeout \\ 5000) do
932    :application.which_applications(timeout)
933  end
934
935  @doc """
936  Returns a list with information about the applications which have been loaded.
937  """
938  @spec loaded_applications :: [{app, description :: charlist(), vsn :: charlist()}]
939  def loaded_applications do
940    :application.loaded_applications()
941  end
942
943  @doc """
944  Formats the error reason returned by `start/2`,
945  `ensure_started/2`, `stop/1`, `load/1` and `unload/1`,
946  returns a string.
947  """
948  @spec format_error(any) :: String.t()
949  def format_error(reason) do
950    try do
951      do_format_error(reason)
952    catch
953      # A user could create an error that looks like a built-in one
954      # causing an error.
955      :error, _ ->
956        inspect(reason)
957    end
958  end
959
960  # exit(:normal) call is special cased, undo the special case.
961  defp do_format_error({{:EXIT, :normal}, {mod, :start, args}}) do
962    Exception.format_exit({:normal, {mod, :start, args}})
963  end
964
965  # {:error, reason} return value
966  defp do_format_error({reason, {mod, :start, args}}) do
967    Exception.format_mfa(mod, :start, args) <>
968      " returned an error: " <> Exception.format_exit(reason)
969  end
970
971  # error or exit(reason) call, use exit reason as reason.
972  defp do_format_error({:bad_return, {{mod, :start, args}, {:EXIT, reason}}}) do
973    Exception.format_exit({reason, {mod, :start, args}})
974  end
975
976  # bad return value
977  defp do_format_error({:bad_return, {{mod, :start, args}, return}}) do
978    Exception.format_mfa(mod, :start, args) <> " returned a bad value: " <> inspect(return)
979  end
980
981  defp do_format_error({:already_started, app}) when is_atom(app) do
982    "already started application #{app}"
983  end
984
985  defp do_format_error({:not_started, app}) when is_atom(app) do
986    "not started application #{app}"
987  end
988
989  defp do_format_error({:bad_application, app}) do
990    "bad application: #{inspect(app)}"
991  end
992
993  defp do_format_error({:already_loaded, app}) when is_atom(app) do
994    "already loaded application #{app}"
995  end
996
997  defp do_format_error({:not_loaded, app}) when is_atom(app) do
998    "not loaded application #{app}"
999  end
1000
1001  defp do_format_error({:invalid_restart_type, restart}) do
1002    "invalid application restart type: #{inspect(restart)}"
1003  end
1004
1005  defp do_format_error({:invalid_name, name}) do
1006    "invalid application name: #{inspect(name)}"
1007  end
1008
1009  defp do_format_error({:invalid_options, opts}) do
1010    "invalid application options: #{inspect(opts)}"
1011  end
1012
1013  defp do_format_error({:badstartspec, spec}) do
1014    "bad application start specs: #{inspect(spec)}"
1015  end
1016
1017  defp do_format_error({'no such file or directory', file}) do
1018    "could not find application file: #{file}"
1019  end
1020
1021  defp do_format_error(reason) do
1022    Exception.format_exit(reason)
1023  end
1024end
1025