`with` construct usage question - variables in `else`

The else clause was there from the beginnings of with. Looking through Elixir’s codebase, I haven’t really found instances of using more than one patterns in else. So it’s either falling through without the else clause:

def touch(path, time) when is_tuple(time) do
  path = IO.chardata_to_string(path)

  with {:error, :enoent} <- :elixir_utils.change_universal_time(path, time),
       :ok <- write(path, "", [:append]),
       do: :elixir_utils.change_universal_time(path, time)
end

or returning a default regardless of an error:

def parse_version(string, approximate? \\ false) when is_binary(string) do
  destructure [version_with_pre, build], String.split(string, "+", parts: 2)
  destructure [version, pre], String.split(version_with_pre, "-", parts: 2)
  destructure [major, minor, patch, next], String.split(version, ".")

  with nil <- next,
        {:ok, major} <- require_digits(major),
        {:ok, minor} <- require_digits(minor),
        {:ok, patch} <- maybe_patch(patch, approximate?),
        {:ok, pre_parts} <- optional_dot_separated(pre),
        {:ok, pre_parts} <- convert_parts_to_integer(pre_parts, []),
        {:ok, build_parts} <- optional_dot_separated(build) do
    {:ok, {major, minor, patch, pre_parts, build_parts}}
  else
    _other -> :error
  end
end

or using the approach suggested by the author, but without a dedicated error struct:

with :ok <- make_boot_scripts(release, version_path, consolidation_path),
     :ok <- make_vm_args(release, vm_args_path),
     :ok <- make_vm_args(release, remote_vm_args_path),
     :ok <- Mix.Release.make_sys_config(release, sys_config, config_provider_path),
     :ok <- Mix.Release.make_cookie(release, cookie_path),
     :ok <- Mix.Release.make_start_erl(release, start_erl_path) do
  consolidation_path
else
  {:error, message} ->
    File.rm_rf!(version_path)
    Mix.raise(message)
end

I’m not familiar with the codebase, but the last one looks like a use of with to build some flow (something that you’d use in application code) rather than just mechanics of avoiding nested case (something you’d use more in library code)