Validates plugin manifests, in two stages (see MOB_PLUGINS.md).
Single-plugin (validate_plugin/3, behind mix mob.validate_plugin): a
plugin author's pre-publish check — required fields, referenced files exist,
mob_version satisfied by the installed mob, plus advisory warnings.
Cross-plugin (cross_validate/1, run by mob_dev when activating): the
collision checks that only make sense across the set of activated plugins —
no two may claim the same component atom, screen route, or migration namespace.
Every result is %{errors: [...], warnings: [...]}. Errors fail loud;
warnings are advisory. Both stages are pure given their inputs (the only I/O
is File.exists?/1 for path checks, isolated in validate_plugin/3).
Summary
Functions
Activation-time capability check across every activated plugin.
Cross-plugin collision validation across the activated set.
Runs activated_capability_errors/1 and raises a Mix.raise/1 (with a
user-readable bullet list) when any plugin's source references a
capability not in its manifest. No-op when every plugin is clean.
Collects the file paths a manifest references, relative to the plugin root.
Verifies every <uses-permission android:name="X"/> declared in
AndroidManifest.xml fragments under the plugin's tree appears in
manifest.android.permissions.
Single-plugin validation, run from the plugin's own project directory.
Verifies every import X in the plugin's Swift sources resolves to either
a base iOS framework or one declared in manifest.ios.frameworks.
Types
Functions
Activation-time capability check across every activated plugin.
plugins is the MobDev.Plugin.activated/0 shape — a list of
{plugin_dir, manifest} pairs. For each plugin, runs
validate_swift_imports/2 and validate_android_permissions/2 and
returns the flattened error list, each entry prefixed with the
plugin's :name so the user can tell which plugin tripped.
Empty list means every activated plugin's source matches its manifest's
declared capability surface. The build hooks this into iOS + Android
builds via raise_on_capability_drift!/1, which raises a Mix.raise/1
with the full list when any drift is found.
Cross-plugin collision validation across the activated set.
plugins is a list of {name, manifest} for the activated plugins (tier-0
no-manifest plugins, i.e. manifest == nil, contribute nothing and are
ignored).
Runs activated_capability_errors/1 and raises a Mix.raise/1 (with a
user-readable bullet list) when any plugin's source references a
capability not in its manifest. No-op when every plugin is clean.
Lives in the validator (not NativeBuild) so the iOS-sim and iOS-device build paths can both call it as a one-liner, and so it stays unit-testable.
Also runs the Phase 2 signature gate
(MobDev.Plugin.SignatureGate.raise_on_signature_drift!/1) at the top
— fails fast on a tampered or untrusted plugin before any capability
analysis runs. The unsigned-plugin banner is printed afterwards so it
surfaces on every successful invocation.
Collects the file paths a manifest references, relative to the plugin root.
Pure. Covers the concrete file declarations (nifs.native_dir,
android.bridge_kt, android.jni_source, ios.swift_files). Component
view_module/composable are type/function names, not paths, so they are
not included here.
Verifies every <uses-permission android:name="X"/> declared in
AndroidManifest.xml fragments under the plugin's tree appears in
manifest.android.permissions.
Scope (deliberate): scans priv/native/android/**/*.xml for
<uses-permission/> entries — declarations the plugin author explicitly
wrote. Does not attempt to infer permissions from Kotlin/Java API usage
(the static-analysis rabbit hole MOB_PLUGIN_SECURITY.md warns against).
Returns [] when the plugin ships no AndroidManifest fragment.
Single-plugin validation, run from the plugin's own project directory.
installed_mob_version is the version of :mob resolved in the plugin's
deps (a string), or nil to skip the compatibility check.
Verifies every import X in the plugin's Swift sources resolves to either
a base iOS framework or one declared in manifest.ios.frameworks.
See MOB_PLUGIN_SECURITY.md (Layer 2 — capability enforcement at compile
time): the manifest is the contract; the plugin's source cannot reach for a
framework that isn't manifest-declared. Catches drift at validate time
rather than at link time, where the error points at the linker invocation
and not at the manifest that produced it.
Returns a list of error strings (empty when the manifest passes). Skips
plugins with no ios.swift_files. Files referenced by the manifest but
missing on disk are flagged by add_path_errors/3, not here — this check
only opens files that exist.