# `MobDev.OtpRequiredApps`
[🔗](https://github.com/genericjam/mob_dev/blob/master/lib/mob_dev/otp_required_apps.ex#L1)

The applications a Mob app needs at runtime, so no slim pass strips one.

Every slim pass (`MobDev.OtpAssetBundle` for the Android release, the iOS
release script in `MobDev.Release`, `MobDev.OtpAudit.Slim` for
`mix mob.deploy --slim`) drops whole OTP libs from the bundled runtime. If a
shipped app lists a dropped lib in its `.app` `applications` or
`included_applications`, starting that app fails on the device, e.g.
`{:inets, {~c"no such file or directory", ~c"inets.app"}}`. Debug deploys
ship the full OTP tree, so the failure only shows in release builds.

The closure starts from the project's runtime dependency set
(`MobDev.HotPush.runtime_lib_names/0`, which walks the `.app` files under
`_build`) and continues through the `.app` files of the OTP tree being
bundled, so an OTP lib needed only by another OTP lib is kept as well.

# `app_dependencies`

```elixir
@spec app_dependencies(Path.t()) :: [String.t()]
```

The apps the `.app` file at `path` needs started or loaded: its
`applications` and `included_applications`. `[]` when it can't be read.

# `closure`

```elixir
@spec closure(Path.t(), Enumerable.t()) :: MapSet.t(String.t())
```

`seeds` plus every app they need, transitively, through the
`lib/*/ebin/*.app` files of `otp_tree`. Names with no `.app` in the tree are
kept as they are.

# `for_project`

```elixir
@spec for_project(Path.t()) :: MapSet.t(String.t())
```

Every app the current Mix project needs at runtime, resolved against the
OTP tree at `otp_tree`. A slim pass must not strip any name in it.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
