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