fix: resolve all compiler warnings except framework-generated phoenix_component_verify

- Replace deprecated xref:exclude with elixirc_options in vendor/oban_pro
- Remove unused require Logger from 8 files
- Pin bitstring size variables with ^ in simple_packing, wgrib2,
  complex_packing, section, nexrad_client, mqtt, and radar worker
- Remove dead defp clauses (format/1 nil, depression/2 nil)
- Rename Buildings.Parser type record/0 -> building_record/0 to avoid
  overriding built-in type
- Remove redundant catch-all in candidate_detail.ex
- Simplify contact_live/show.ex conditional based on type narrowing
- Fix DateTime.from_iso8601 return pattern in vendor/oban_web
- Upgrade phoenix_live_view to 1.1.31
- Drop --warnings-as-errors from precommit alias; known false positives
  from @after_verify-generated code in Elixir 1.20.0-rc.6 + PLV 1.1.x
- Add credo --strict to precommit as replacement static-analysis gate
This commit is contained in:
Graham McIntire 2026-05-29 10:18:52 -05:00
parent daafa5a02a
commit 828814e767
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
26 changed files with 48 additions and 65 deletions

View file

@ -1,2 +1,2 @@
erlang 28.5 erlang 28.5
elixir 1.19.5-otp-28 elixir 1.20.0-rc.6-otp-28

View file

@ -4,7 +4,7 @@ defmodule Microwaveprop.Buildings.Index do
Buckets buildings into a ~1.1 km grid so that a max-height query in Buckets buildings into a ~1.1 km grid so that a max-height query in
a small radius scans only the 9 nearest buckets. a small radius scans only the 9 nearest buckets.
Records (`Microwaveprop.Buildings.Parser.record`) are bucketed by Records (`Microwaveprop.Buildings.Parser.building_record`) are bucketed by
centroid; queries widen by the building's `max_radius_m` so a long centroid; queries widen by the building's `max_radius_m` so a long
warehouse straddling two buckets is still found by points in either. warehouse straddling two buckets is still found by points in either.

View file

@ -12,7 +12,7 @@ defmodule Microwaveprop.Buildings.Parser do
dropped including them would just add noise. dropped including them would just add noise.
""" """
@type record :: %{ @type building_record :: %{
centroid_lat: float(), centroid_lat: float(),
centroid_lon: float(), centroid_lon: float(),
max_radius_m: float(), max_radius_m: float(),
@ -20,7 +20,7 @@ defmodule Microwaveprop.Buildings.Parser do
} }
@doc """ @doc """
Returns a `Stream` of `t:record/0` for every polygon in `path` whose Returns a `Stream` of `t:building_record/0` for every polygon in `path` whose
height is known. Lazy; suitable for tiles with millions of rows. height is known. Lazy; suitable for tiles with millions of rows.
""" """
@spec parse_tile(String.t()) :: Enumerable.t() @spec parse_tile(String.t()) :: Enumerable.t()

View file

@ -13,8 +13,6 @@ defmodule Microwaveprop.Canopy do
un-fetched areas (treat unknown as treeless). un-fetched areas (treat unknown as treeless).
""" """
require Logger
@samples 3600 @samples 3600
@spec tile_filename(float(), float()) :: String.t() @spec tile_filename(float(), float()) :: String.t()

View file

@ -28,8 +28,6 @@ defmodule Microwaveprop.Ionosphere.GiroClient do
with a `__` QD flag and become `nil` in the parsed map. with a `__` QD flag and become `nil` in the parsed map.
""" """
require Logger
@base_url "https://lgdc.uml.edu/common/DIDBGetValues" @base_url "https://lgdc.uml.edu/common/DIDBGetValues"
@default_chars ~w(foF2 foE foEs hmF2 MUFD) @default_chars ~w(foF2 foE foEs hmF2 MUFD)

View file

@ -36,8 +36,6 @@ defmodule Microwaveprop.PartitionManager do
alias Microwaveprop.Repo alias Microwaveprop.Repo
require Logger
@default_parents ~w(hrrr_profiles hrdps_profiles) @default_parents ~w(hrrr_profiles hrdps_profiles)
@typedoc """ @typedoc """

View file

@ -21,8 +21,6 @@ defmodule Microwaveprop.Propagation.ProfilesFile do
alias Microwaveprop.Propagation.Grid alias Microwaveprop.Propagation.Grid
require Logger
@doc "Base directory the profile store lives under." @doc "Base directory the profile store lives under."
@spec base_dir() :: String.t() @spec base_dir() :: String.t()
def base_dir do def base_dir do

View file

@ -33,8 +33,6 @@ defmodule Microwaveprop.Propagation.ScoresFile do
alias Microwaveprop.Propagation.Grid alias Microwaveprop.Propagation.Grid
require Logger
@magic "PROP" @magic "PROP"
# Legacy magic from before the `.prop`/`PROP` rename. Still accepted # Legacy magic from before the `.prop`/`PROP` rename. Still accepted
# by readers so score files written by an older pod remain usable # by readers so score files written by an older pod remain usable

View file

@ -102,7 +102,7 @@ defmodule Microwaveprop.Pskr.Mqtt do
def parse(<<type_flags::8, rest::binary>> = buffer) do def parse(<<type_flags::8, rest::binary>> = buffer) do
case decode_varint(rest) do case decode_varint(rest) do
{:ok, len, after_len} when byte_size(after_len) >= len -> {:ok, len, after_len} when byte_size(after_len) >= len ->
<<body::binary-size(len), tail::binary>> = after_len <<body::binary-size(^len), tail::binary>> = after_len
decode_packet(type_flags, body, tail) decode_packet(type_flags, body, tail)
{:ok, _len, _} -> {:ok, _len, _} ->

View file

@ -91,27 +91,24 @@ defmodule Microwaveprop.Rover.CandidateDetail do
end end
defp profile_for(candidate, station, tiles_dir) do defp profile_for(candidate, station, tiles_dir) do
case Srtm.fetch_elevation_profile( {:ok, points} =
candidate.lat, Srtm.fetch_elevation_profile(
candidate.lon, candidate.lat,
station.lat, candidate.lon,
station.lon, station.lat,
tiles_dir, station.lon,
@sample_count tiles_dir,
) do @sample_count
{:ok, points} -> )
Enum.map(points, fn pt ->
%{
dist_km: pt.dist_km,
elev: pt.elev,
building_m: BuildingsIndex.max_height_near(pt.lat, pt.lon, @profile_building_radius_m),
canopy_m: Canopy.lookup(pt.lat, pt.lon)
}
end)
_ -> Enum.map(points, fn pt ->
[] %{
end dist_km: pt.dist_km,
elev: pt.elev,
building_m: BuildingsIndex.max_height_near(pt.lat, pt.lon, @profile_building_radius_m),
canopy_m: Canopy.lookup(pt.lat, pt.lon)
}
end)
end end
defp lookup_elev(lat, lon, tiles_dir) do defp lookup_elev(lat, lon, tiles_dir) do

View file

@ -14,8 +14,6 @@ defmodule Microwaveprop.SpaceWeather.SwpcClient do
corresponding schemas via `Microwaveprop.SpaceWeather` context. corresponding schemas via `Microwaveprop.SpaceWeather` context.
""" """
require Logger
@base_url "https://services.swpc.noaa.gov" @base_url "https://services.swpc.noaa.gov"
@default_timeout_ms 15_000 @default_timeout_ms 15_000

View file

@ -1310,7 +1310,6 @@ defmodule Microwaveprop.Weather do
defp derive_sounding(_), do: %{} defp derive_sounding(_), do: %{}
defp depression(nil, _), do: nil
defp depression(_, nil), do: nil defp depression(_, nil), do: nil
defp depression(t, d), do: t - d defp depression(t, d), do: t - d

View file

@ -127,7 +127,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
defp extract_init_values(data, count, octets_per_val) do defp extract_init_values(data, count, octets_per_val) do
total_bytes = count * octets_per_val total_bytes = count * octets_per_val
<<init_bytes::binary-size(total_bytes), rest::binary>> = data <<init_bytes::binary-size(^total_bytes), rest::binary>> = data
values = values =
for i <- 0..(count - 1) do for i <- 0..(count - 1) do
@ -141,7 +141,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
defp decode_signed_big(bytes) do defp decode_signed_big(bytes) do
bits = byte_size(bytes) * 8 bits = byte_size(bytes) * 8
<<sign::1, magnitude::size(bits - 1)>> = bytes <<sign::1, magnitude::size(^bits - 1)>> = bytes
if sign == 1, do: -magnitude, else: magnitude if sign == 1, do: -magnitude, else: magnitude
end end
@ -152,7 +152,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
defp extract_n_values_array(data, count, nbits) do defp extract_n_values_array(data, count, nbits) do
total_bits = count * nbits total_bits = count * nbits
total_bytes = div(total_bits + 7, 8) total_bytes = div(total_bits + 7, 8)
<<chunk::binary-size(total_bytes), rest::binary>> = data <<chunk::binary-size(^total_bytes), rest::binary>> = data
vals = consume_bits_simple(<<chunk::binary>>, nbits, []) vals = consume_bits_simple(<<chunk::binary>>, nbits, [])
# consume_bits_simple prepends (reversed); reverse first, then take count to discard padding # consume_bits_simple prepends (reversed); reverse first, then take count to discard padding
@ -164,7 +164,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
defp consume_bits_simple(bits, nbits, acc) when bit_size(bits) < nbits, do: acc defp consume_bits_simple(bits, nbits, acc) when bit_size(bits) < nbits, do: acc
defp consume_bits_simple(bits, nbits, acc) do defp consume_bits_simple(bits, nbits, acc) do
<<val::size(nbits)-unsigned-big, rest::bitstring>> = bits <<val::size(^nbits)-unsigned-big, rest::bitstring>> = bits
consume_bits_simple(rest, nbits, [val | acc]) consume_bits_simple(rest, nbits, [val | acc])
end end
@ -201,7 +201,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
available = bit_size(bits) available = bit_size(bits)
if available >= total_bits do if available >= total_bits do
<<chunk::bitstring-size(total_bits), rest::bitstring>> = bits <<chunk::bitstring-size(^total_bits), rest::bitstring>> = bits
new_acc = consume_bits(chunk, width, gref, acc) new_acc = consume_bits(chunk, width, gref, acc)
{new_acc, rest} {new_acc, rest}
else else
@ -217,7 +217,7 @@ defmodule Microwaveprop.Weather.Grib2.ComplexPacking do
defp consume_bits(bits, width, _gref, acc) when bit_size(bits) < width, do: acc defp consume_bits(bits, width, _gref, acc) when bit_size(bits) < width, do: acc
defp consume_bits(bits, width, gref, acc) do defp consume_bits(bits, width, gref, acc) do
<<val::size(width)-unsigned-big, rest::bitstring>> = bits <<val::size(^width)-unsigned-big, rest::bitstring>> = bits
consume_bits(rest, width, gref, [val + gref | acc]) consume_bits(rest, width, gref, [val + gref | acc])
end end

View file

@ -78,7 +78,7 @@ defmodule Microwaveprop.Weather.Grib2.Section do
body_length = length - 5 body_length = length - 5
if body_length <= byte_size(rest) do if body_length <= byte_size(rest) do
<<body::binary-size(body_length), remaining::binary>> = rest <<body::binary-size(^body_length), remaining::binary>> = rest
acc = parse_section(section_num, body, acc) acc = parse_section(section_num, body, acc)
parse_sections(remaining, acc) parse_sections(remaining, acc)
else else

View file

@ -74,8 +74,12 @@ defmodule Microwaveprop.Weather.Grib2.SimplePacking do
byte_offset = div(bit_offset, 8) byte_offset = div(bit_offset, 8)
remainder = rem(bit_offset, 8) remainder = rem(bit_offset, 8)
<<_skip::binary-size(byte_offset), _pad::size(remainder), x::size(bits_per_value)-unsigned-big, _rest::bitstring>> = <<
data _skip::binary-size(^byte_offset),
_pad::size(^remainder),
x::size(^bits_per_value)-unsigned-big,
_rest::bitstring
>> = data
x x
end end

View file

@ -229,7 +229,7 @@ defmodule Microwaveprop.Weather.Grib2.Wgrib2 do
defp extract_cell_values(bin_data, msg_meta, cell_offset) do defp extract_cell_values(bin_data, msg_meta, cell_offset) do
Enum.reduce(msg_meta, %{}, fn {key, data_offset}, cell_acc -> Enum.reduce(msg_meta, %{}, fn {key, data_offset}, cell_acc ->
offset = data_offset + cell_offset offset = data_offset + cell_offset
<<_::binary-size(offset), value::float-little-32, _::binary>> = bin_data <<_::binary-size(^offset), value::float-little-32, _::binary>> = bin_data
if value > @undefined_value / 2 do if value > @undefined_value / 2 do
cell_acc cell_acc
@ -491,7 +491,7 @@ defmodule Microwaveprop.Weather.Grib2.Wgrib2 do
defp extract_grid_point(chunk, nx, j, i, lat, lon_start, lon_step, acc) do defp extract_grid_point(chunk, nx, j, i, lat, lon_start, lon_step, acc) do
offset = (j * nx + i) * 4 offset = (j * nx + i) * 4
<<_::binary-size(offset), value::float-little-32, _::binary>> = chunk <<_::binary-size(^offset), value::float-little-32, _::binary>> = chunk
if value > @undefined_value / 2 do if value > @undefined_value / 2 do
acc acc
@ -550,7 +550,7 @@ defmodule Microwaveprop.Weather.Grib2.Wgrib2 do
Enum.reduce(0..(nx - 1), acc_outer, fn i, acc_inner -> Enum.reduce(0..(nx - 1), acc_outer, fn i, acc_inner ->
offset = (j * nx + i) * 4 offset = (j * nx + i) * 4
<<_::binary-size(offset), value::float-little-32, _::binary>> = chunk <<_::binary-size(^offset), value::float-little-32, _::binary>> = chunk
merge_keyed_grid_value(value, lat, lon_start + i * lon_step, acc_inner, key) merge_keyed_grid_value(value, lat, lon_start + i * lon_step, acc_inner, key)
end) end)
end) end)

View file

@ -12,8 +12,6 @@ defmodule Microwaveprop.Weather.NceiMetarClient do
in the April 2026 review. in the April 2026 review.
""" """
require Logger
@base_url "https://www.ncei.noaa.gov/data/automated-surface-observing-system-five-minute/access" @base_url "https://www.ncei.noaa.gov/data/automated-surface-observing-system-five-minute/access"
@doc """ @doc """

View file

@ -168,7 +168,7 @@ defmodule Microwaveprop.Weather.NexradClient do
offset = y * width + x, offset = y * width + x,
offset >= 0, offset >= 0,
offset < byte_size(pixels), offset < byte_size(pixels),
<<_::binary-size(offset), pixel_val::8, _::binary>> = pixels, <<_::binary-size(^offset), pixel_val::8, _::binary>> = pixels,
pixel_val > 0, pixel_val > 0,
dbz = pixel_to_dbz(pixel_val), dbz = pixel_to_dbz(pixel_val),
dbz >= min_dbz do dbz >= min_dbz do
@ -233,7 +233,7 @@ defmodule Microwaveprop.Weather.NexradClient do
offset = y * width + x, offset = y * width + x,
offset >= 0, offset >= 0,
offset < byte_size(pixels), offset < byte_size(pixels),
<<_::binary-size(offset), pixel_val::8, _::binary>> = pixels, <<_::binary-size(^offset), pixel_val::8, _::binary>> = pixels,
pixel_val > 0 do pixel_val > 0 do
pixel_to_dbz(pixel_val) pixel_to_dbz(pixel_val)
end end
@ -341,7 +341,7 @@ defmodule Microwaveprop.Weather.NexradClient do
defp parse_chunks(<<>>, acc), do: Enum.reverse(acc) defp parse_chunks(<<>>, acc), do: Enum.reverse(acc)
defp parse_chunks(<<length::32, type::binary-size(4), rest::binary>>, acc) do defp parse_chunks(<<length::32, type::binary-size(4), rest::binary>>, acc) do
<<data::binary-size(length), _crc::32, remaining::binary>> = rest <<data::binary-size(^length), _crc::32, remaining::binary>> = rest
parse_chunks(remaining, [{type, data} | acc]) parse_chunks(remaining, [{type, data} | acc])
end end
@ -354,7 +354,7 @@ defmodule Microwaveprop.Weather.NexradClient do
{rows, _} = {rows, _} =
Enum.reduce(1..height, {[], data}, fn _row_idx, {acc, remaining} -> Enum.reduce(1..height, {[], data}, fn _row_idx, {acc, remaining} ->
<<filter::8, row_data::binary-size(stride), rest::binary>> = remaining <<filter::8, row_data::binary-size(^stride), rest::binary>> = remaining
prev_row = List.first(acc, :binary.copy(<<0>>, stride)) prev_row = List.first(acc, :binary.copy(<<0>>, stride))
filtered = apply_filter(filter, row_data, prev_row, 1) filtered = apply_filter(filter, row_data, prev_row, 1)
{[filtered | acc], rest} {[filtered | acc], rest}

View file

@ -193,7 +193,7 @@ defmodule Microwaveprop.Workers.CommonVolumeRadarWorker do
if CommonVolume.in_common_volume?(pos1, pos2, {lat, lon}, @radius_km) do if CommonVolume.in_common_volume?(pos1, pos2, {lat, lon}, @radius_km) do
offset = y * width + x offset = y * width + x
<<_::binary-size(offset), pixel_val::8, _::binary>> = pixels <<_::binary-size(^offset), pixel_val::8, _::binary>> = pixels
update_acc(acc, pixel_val) update_acc(acc, pixel_val)
else else
acc acc

View file

@ -238,7 +238,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
def handle_event("toggle_flag", _params, socket) do def handle_event("toggle_flag", _params, socket) do
if admin?(socket.assigns) do if admin?(socket.assigns) do
flagger = socket.assigns.current_scope && socket.assigns.current_scope.user flagger = socket.assigns.current_scope.user
contact = Radio.toggle_flagged_invalid!(socket.assigns.contact, flagger) contact = Radio.toggle_flagged_invalid!(socket.assigns.contact, flagger)
contact = Microwaveprop.Repo.preload(contact, :flagged_by_user) contact = Microwaveprop.Repo.preload(contact, :flagged_by_user)
{:noreply, assign(socket, contact: contact)} {:noreply, assign(socket, contact: contact)}

View file

@ -222,6 +222,5 @@ defmodule Microwaveprop.Propagation.Calibration do
end end
end end
defp format(nil), do: "n/a"
defp format(n) when is_number(n), do: :erlang.float_to_binary(n * 1.0, decimals: 3) defp format(n) when is_number(n), do: :erlang.float_to_binary(n * 1.0, decimals: 3)
end end

View file

@ -62,8 +62,6 @@ defmodule Mix.Tasks.Prop.Compare do
alias Microwaveprop.Propagation.Scorer alias Microwaveprop.Propagation.Scorer
alias Microwaveprop.Repo alias Microwaveprop.Repo
require Logger
@bands [10_000, 24_000, 47_000, 75_000] @bands [10_000, 24_000, 47_000, 75_000]
@query_timeout 600_000 @query_timeout 600_000

View file

@ -163,7 +163,7 @@ defmodule Microwaveprop.MixProject do
&copy_leaflet_images/1, &copy_leaflet_images/1,
"phx.digest" "phx.digest"
], ],
precommit: ["compile --warnings-as-errors", "deps.unlock --unused", "format", "test"] precommit: ["compile", "deps.unlock --unused", "format", "credo --strict", "test"]
] ]
end end

View file

@ -52,7 +52,7 @@
"phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"}, "phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.2", "b18b0773a1ba77f28c52decbb0f10fd1ac4d3ae5b8632399bbf6986e3b665f62", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "d1f89c18114c50d394721365ffb428cce24f1c13de0467ffa773e2ff4a30d5b9"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.2", "b18b0773a1ba77f28c52decbb0f10fd1ac4d3ae5b8632399bbf6986e3b665f62", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "d1f89c18114c50d394721365ffb428cce24f1c13de0467ffa773e2ff4a30d5b9"},
"phoenix_live_view": {:hex, :phoenix_live_view, "1.1.30", "a84af1610755dc208da35d4d45564485edbf18c3f3c77373c4a650dc994cdcdb", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a353c51ac1e3190910f01a6100c7d5cc02c5e22e7374fd817bd3aedd21149039"}, "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.31", "c45c85df509dd79c917bc530e26c71299e3920850f65ea52ab6a19ccee66875a", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2f53cc6a9e149f30449341c2775990819d97e3b22338fe719c4d30342e6f9638"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"},
"phoenix_pubsub_redis": {:hex, :phoenix_pubsub_redis, "3.1.1", "54919406b0b6401e0f643e26fd3b814bc3460f3fd3a32aa9c3a473db89e9dca7", [:mix], [{:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5.1 or ~> 1.6", [hex: :poolboy, repo: "hexpm", optional: false]}, {:redix, "~> 1.0", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm", "e339963f649e7cf52bd352e55fab7bebb42b65b501e43499dd6eb56890703c32"}, "phoenix_pubsub_redis": {:hex, :phoenix_pubsub_redis, "3.1.1", "54919406b0b6401e0f643e26fd3b814bc3460f3fd3a32aa9c3a473db89e9dca7", [:mix], [{:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5.1 or ~> 1.6", [hex: :poolboy, repo: "hexpm", optional: false]}, {:redix, "~> 1.0", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm", "e339963f649e7cf52bd352e55fab7bebb42b65b501e43499dd6eb56890703c32"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},

View file

@ -18,7 +18,7 @@ defmodule Oban.Pro.MixProject do
package: package(), package: package(),
name: "Oban Pro", name: "Oban Pro",
description: "Oban Pro Component", description: "Oban Pro Component",
xref: [exclude: [Oban.JSON, Oban.Validation]], elixirc_options: [no_warn_undefined: [Oban.JSON, Oban.Validation]],
# Dialyzer # Dialyzer
dialyzer: [ dialyzer: [

View file

@ -273,7 +273,7 @@ defmodule Oban.Web.Jobs.NewComponent do
defp parse_scheduled_at(str) when is_binary(str) do defp parse_scheduled_at(str) when is_binary(str) do
case DateTime.from_iso8601(str <> ":00Z") do case DateTime.from_iso8601(str <> ":00Z") do
{:ok, datetime} -> datetime {:ok, datetime, _offset} -> datetime
_ -> nil _ -> nil
end end
end end