diff --git a/CHANGELOG.md b/CHANGELOG.md index fd79ed8..668b797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ ### Fixed +- **`mix mob.deploy --slim` is no longer a silent no-op** (MOB-73). + `NativeBuild.build_all/1` stored `slim` in the process dict + (`Process.put(:mob_slim, slim)`) but the actual gate at + `maybe_slim_otp_bundle/2` reads `System.get_env("MOB_SLIM")` — so + `--slim` from the CLI never reached the strip pass. Only + `mix mob.release` produced a slim OTP bundle, because that path + explicitly sets the env var. Fixed by publishing `MOB_SLIM=1` / `=0` + in `__apply_slim_env__/1`, which the gate already knows how to read. + Two revert-verified tests lock the env-var contract. + - **Plugin signature verification now runs before `Code.eval_file`** on the manifest (MOB-74). The v1 signature covered the eval'd manifest map, so verifiers needed the eval to run first to rebuild the payload — letting diff --git a/lib/mob_dev/native_build.ex b/lib/mob_dev/native_build.ex index 4494a45..4eac5d0 100644 --- a/lib/mob_dev/native_build.ex +++ b/lib/mob_dev/native_build.ex @@ -40,7 +40,7 @@ defmodule MobDev.NativeBuild do do: narrow_platforms_for_device(platforms, device_id), else: platforms - Process.put(:mob_slim, slim) + __apply_slim_env__(slim) # Always regenerate the runtime plugin manifest from the CURRENT activated # plugins before bundling priv — like the driver_tab, it's derived state, not @@ -5857,6 +5857,18 @@ defmodule MobDev.NativeBuild do :ok end + @doc false + # Publish the --slim flag into MOB_SLIM so `maybe_slim_otp_bundle/2` (which + # mirrors `release.ex`'s env-var gate) actually sees it. Before MOB-73 this + # went into `Process.put(:mob_slim, ...)` and nothing consulted it — so + # `mix mob.deploy --slim` was a silent no-op. Public-for-testing so the + # env-var contract is regression-guarded. + @spec __apply_slim_env__(boolean()) :: :ok + def __apply_slim_env__(slim) when is_boolean(slim) do + System.put_env("MOB_SLIM", if(slim, do: "1", else: "0")) + :ok + end + defp maybe_slim_otp_bundle(app_path, cfg) do if System.get_env("MOB_SLIM") == "1" do otp_bundle = Path.join(app_path, "otp") diff --git a/test/mob_dev/native_build_test.exs b/test/mob_dev/native_build_test.exs index 7c22ac4..f2e6bd3 100644 --- a/test/mob_dev/native_build_test.exs +++ b/test/mob_dev/native_build_test.exs @@ -10,6 +10,39 @@ defmodule MobDev.NativeBuildTest do alias MobDev.NativeBuild + describe "__apply_slim_env__/1 (MOB-73 --slim gate)" do + setup do + # Save/restore MOB_SLIM across the test since it's process-global. + previous = System.get_env("MOB_SLIM") + + on_exit(fn -> + case previous do + nil -> System.delete_env("MOB_SLIM") + val -> System.put_env("MOB_SLIM", val) + end + end) + + :ok + end + + test "true publishes MOB_SLIM=1 so the slim gate actually fires" do + # Before MOB-73 this went through `Process.put(:mob_slim, true)` and + # `maybe_slim_otp_bundle/2` never consulted the dict — so `mix mob.deploy + # --slim` was a silent no-op. The env-var read at native_build.ex:5861 + # is what the strip pass gates on; the helper's job is to set it. Revert + # to Process.put and this fails. + System.put_env("MOB_SLIM", "0") + :ok = NativeBuild.__apply_slim_env__(true) + assert System.get_env("MOB_SLIM") == "1" + end + + test "false publishes MOB_SLIM=0 so --no-slim is explicit and observable" do + System.put_env("MOB_SLIM", "1") + :ok = NativeBuild.__apply_slim_env__(false) + assert System.get_env("MOB_SLIM") == "0" + end + end + describe "build_zig_supports_abi?/2" do test "true when the build.zig declares the ABI as a quoted string literal" do src = ~s|