Skip to content

Commit 3ca5292

Browse files
committed
Update ex_dna 1.5, ex_slop 0.4; fix new credo warnings
1 parent 4ba28c8 commit 3ca5292

15 files changed

Lines changed: 104 additions & 93 deletions

.credo.exs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,28 +165,45 @@
165165

166166
# ExSlop — AI slop detection
167167
{ExSlop.Check.Warning.BlanketRescue, []},
168-
{ExSlop.Check.Warning.RescueWithoutReraise, []},
169-
{ExSlop.Check.Warning.RepoAllThenFilter, []},
170-
{ExSlop.Check.Warning.QueryInEnumMap, []},
168+
{ExSlop.Check.Warning.DualKeyAccess, []},
171169
{ExSlop.Check.Warning.GenserverAsKvStore, []},
170+
{ExSlop.Check.Warning.PathExpandPriv, []},
171+
{ExSlop.Check.Warning.QueryInEnumMap, []},
172+
{ExSlop.Check.Warning.RepoAllThenFilter, []},
173+
{ExSlop.Check.Warning.RescueWithoutReraise, []},
174+
{ExSlop.Check.Refactor.CaseTrueFalse, []},
175+
{ExSlop.Check.Refactor.ExplicitSumReduce, []},
172176
{ExSlop.Check.Refactor.FilterNil, []},
173-
{ExSlop.Check.Refactor.RejectNil, []},
174-
{ExSlop.Check.Refactor.ReduceAsMap, []},
175-
{ExSlop.Check.Refactor.MapIntoLiteral, []},
176-
{ExSlop.Check.Refactor.IdentityPassthrough, []},
177+
{ExSlop.Check.Refactor.FlatMapFilter, []},
178+
{ExSlop.Check.Refactor.GraphemesLength, []},
177179
{ExSlop.Check.Refactor.IdentityMap, []},
178-
{ExSlop.Check.Refactor.CaseTrueFalse, []},
179-
{ExSlop.Check.Refactor.TryRescueWithSafeAlternative, []},
180-
{ExSlop.Check.Refactor.WithIdentityElse, []},
181-
{ExSlop.Check.Refactor.WithIdentityDo, []},
180+
{ExSlop.Check.Refactor.IdentityPassthrough, []},
181+
{ExSlop.Check.Refactor.LengthInGuard, []},
182+
{ExSlop.Check.Refactor.ListFold, []},
183+
{ExSlop.Check.Refactor.ListLast, []},
184+
{ExSlop.Check.Refactor.ManualStringReverse, []},
185+
{ExSlop.Check.Refactor.MapIntoLiteral, []},
186+
{ExSlop.Check.Refactor.PreferEnumSlice, []},
187+
{ExSlop.Check.Refactor.ReduceAsMap, []},
188+
{ExSlop.Check.Refactor.ReduceMapPut, []},
189+
{ExSlop.Check.Refactor.RedundantBooleanIf, []},
190+
{ExSlop.Check.Refactor.RedundantEnumJoinSeparator, []},
191+
{ExSlop.Check.Refactor.RejectNil, []},
192+
{ExSlop.Check.Refactor.SortForTopK, []},
193+
{ExSlop.Check.Refactor.SortThenAt, []},
182194
{ExSlop.Check.Refactor.SortThenReverse, []},
183195
{ExSlop.Check.Refactor.StringConcatInReduce, []},
184-
{ExSlop.Check.Readability.NarratorDoc, []},
185-
{ExSlop.Check.Readability.DocFalseOnPublicFunction, []},
196+
{ExSlop.Check.Refactor.TryRescueWithSafeAlternative, []},
197+
{ExSlop.Check.Refactor.UseMapJoin, []},
198+
{ExSlop.Check.Refactor.WithIdentityDo, []},
199+
{ExSlop.Check.Refactor.WithIdentityElse, []},
186200
{ExSlop.Check.Readability.BoilerplateDocParams, []},
201+
{ExSlop.Check.Readability.DocFalseOnPublicFunction, []},
202+
{ExSlop.Check.Readability.NarratorComment, []},
203+
{ExSlop.Check.Readability.NarratorDoc, []},
187204
{ExSlop.Check.Readability.ObviousComment, []},
188205
{ExSlop.Check.Readability.StepComment, []},
189-
{ExSlop.Check.Readability.NarratorComment, []}
206+
{ExSlop.Check.Readability.UnaliasedModuleUse, []}
190207
],
191208
disabled: [
192209
#

lib/mix/tasks/npm.size.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,22 @@ defmodule Mix.Tasks.Npm.Size do
1616

1717
use Mix.Task
1818

19+
alias NPM.NodeModules
20+
1921
@impl true
2022
def run(args) do
2123
{opts, _, _} = OptionParser.parse(args, strict: [top: :integer])
2224
top_n = Keyword.get(opts, :top, 10)
2325
dir = "node_modules"
2426

25-
total_size = NPM.NodeModules.disk_size(dir)
26-
total_files = NPM.NodeModules.file_count(dir)
27+
total_size = NodeModules.disk_size(dir)
28+
total_files = NodeModules.file_count(dir)
2729

2830
Mix.shell().info("node_modules analysis:")
2931
Mix.shell().info(" Total size: #{NPM.FormatUtil.format_size(total_size)}")
3032
Mix.shell().info(" Total files: #{total_files}")
3133

32-
packages = NPM.NodeModules.installed(dir)
34+
packages = NodeModules.installed(dir)
3335
Mix.shell().info(" Packages: #{length(packages)}")
3436

3537
if packages != [] do
@@ -42,7 +44,7 @@ defmodule Mix.Tasks.Npm.Size do
4244
packages
4345
|> Enum.map(fn name ->
4446
pkg_dir = Path.join(dir, name)
45-
size = NPM.NodeModules.disk_size(pkg_dir)
47+
size = NodeModules.disk_size(pkg_dir)
4648
{name, size}
4749
end)
4850
|> Enum.sort_by(fn {_, size} -> -size end)

lib/mix/tasks/npm.stats.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,24 @@ defmodule Mix.Tasks.Npm.Stats do
1212

1313
use Mix.Task
1414

15+
alias NPM.DepGraph
16+
1517
@impl true
1618
def run([]) do
1719
Application.ensure_all_started(:req)
1820

1921
with {:ok, %{dependencies: deps, dev_dependencies: dev_deps}} <- NPM.PackageJSON.read_all(),
2022
{:ok, lockfile} when lockfile != %{} <- NPM.Lockfile.read() do
2123
all_deps = Map.merge(deps, dev_deps)
22-
adj = NPM.DepGraph.adjacency_list(lockfile)
23-
fin = NPM.DepGraph.fan_in(adj)
24-
fout = NPM.DepGraph.fan_out(adj)
24+
adj = DepGraph.adjacency_list(lockfile)
25+
fin = DepGraph.fan_in(adj)
26+
fout = DepGraph.fan_out(adj)
2527

2628
Mix.shell().info("NPM dependency statistics:")
2729
Mix.shell().info(" Total packages: #{map_size(lockfile)}")
2830
Mix.shell().info(" Direct deps: #{map_size(all_deps)}")
2931
Mix.shell().info(" Transitive deps: #{map_size(lockfile) - map_size(all_deps)}")
30-
Mix.shell().info(" Leaf packages: #{length(NPM.DepGraph.leaves(adj))}")
32+
Mix.shell().info(" Leaf packages: #{length(DepGraph.leaves(adj))}")
3133

3234
print_top("Most depended on", fin)
3335
print_top("Most dependencies", fout)

lib/npm/cache.ex

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ defmodule NPM.Cache do
4747
{:ok, dest}
4848

4949
{:error, reason} ->
50-
if Keyword.get(opts, :optional?, false) do
51-
File.rm_rf(dest)
52-
{:ok, :missing_optional}
53-
else
54-
{:error, reason}
55-
end
50+
handle_fetch_error(reason, dest, opts)
5651
end
5752
end
5853
end
54+
55+
defp handle_fetch_error(reason, dest, opts) do
56+
if Keyword.get(opts, :optional?, false) do
57+
File.rm_rf(dest)
58+
{:ok, :missing_optional}
59+
else
60+
{:error, reason}
61+
end
62+
end
5963
end

lib/npm/dep_conflict.ex

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,8 @@ defmodule NPM.DepConflict do
5050

5151
all_entries
5252
|> Enum.group_by(& &1.name)
53-
|> Enum.flat_map(fn {name, entries} ->
54-
if length(entries) > 1 do
55-
[%{name: name, groups: Enum.map(entries, & &1.group)}]
56-
else
57-
[]
58-
end
59-
end)
53+
|> Enum.filter(fn {_name, entries} -> match?([_, _ | _], entries) end)
54+
|> Enum.map(fn {name, entries} -> %{name: name, groups: Enum.map(entries, & &1.group)} end)
6055
|> Enum.sort_by(& &1.name)
6156
end
6257

lib/npm/import.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ defmodule NPM.Import do
1919
{:npm_ex, "npm.lock"}
2020
]
2121

22-
Enum.flat_map(checks, fn {manager, file} ->
23-
if File.exists?(Path.join(project_dir, file)), do: [manager], else: []
22+
Enum.filter(checks, fn {_manager, file} ->
23+
File.exists?(Path.join(project_dir, file))
2424
end)
25+
|> Enum.map(fn {manager, _file} -> manager end)
2526
end
2627

2728
@doc """

lib/npm/linker.ex

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -282,24 +282,20 @@ defmodule NPM.Linker do
282282

283283
lockfile
284284
|> Enum.filter(fn {name, _} -> MapSet.member?(optional_names, name) end)
285-
|> Enum.reject(fn {name, entry} ->
286-
case NPM.Registry.get_packument(name) do
287-
{:ok, packument} ->
288-
case Map.get(packument.versions, entry.version) do
289-
nil ->
290-
false
291-
292-
info ->
293-
NPM.Platform.os_compatible?(info.os) and NPM.Platform.cpu_compatible?(info.cpu)
294-
end
295-
296-
_ ->
297-
true
298-
end
299-
end)
285+
|> Enum.reject(fn {name, entry} -> platform_compatible?(name, entry.version) end)
300286
|> MapSet.new(fn {name, _} -> name end)
301287
end
302288

289+
defp platform_compatible?(name, version) do
290+
with {:ok, packument} <- NPM.Registry.get_packument(name),
291+
%{} = info <- Map.get(packument.versions, version) do
292+
NPM.Platform.os_compatible?(info.os) and NPM.Platform.cpu_compatible?(info.cpu)
293+
else
294+
nil -> false
295+
_ -> true
296+
end
297+
end
298+
303299
defp optional_dependency?(name, lockfile) do
304300
Enum.any?(lockfile, fn {_pkg, entry} ->
305301
Map.has_key?(Map.get(entry, :optional_dependencies, %{}), name)

lib/npm/platform_optional.ex

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ defmodule NPM.PlatformOptional do
3333
exact_matches = Enum.filter(deps, fn {name, _range} -> current_match(name) end)
3434

3535
case exact_matches do
36-
[first | _] ->
37-
[first]
38-
39-
[] ->
40-
case Enum.filter(deps, fn {name, _range} -> package_matches_platform?(name) end) do
41-
[] -> []
42-
matches -> [Enum.max_by(matches, fn {name, _range} -> platform_score(name) end)]
43-
end
36+
[first | _] -> [first]
37+
[] -> best_platform_match(deps)
38+
end
39+
end
40+
41+
defp best_platform_match(deps) do
42+
case Enum.filter(deps, fn {name, _range} -> package_matches_platform?(name) end) do
43+
[] -> []
44+
matches -> [Enum.max_by(matches, fn {name, _range} -> platform_score(name) end)]
4445
end
4546
end
4647

@@ -51,36 +52,29 @@ defmodule NPM.PlatformOptional do
5152
defp platform_score(name) do
5253
case NPM.Registry.get_packument(name) do
5354
{:ok, packument} ->
54-
packument.versions
55-
|> Map.values()
56-
|> Enum.map(fn info ->
57-
os_match = if NPM.Platform.os_compatible?(info.os), do: 1, else: 0
58-
cpu_match = if NPM.Platform.cpu_compatible?(info.cpu), do: 1, else: 0
59-
os_match + cpu_match
60-
end)
61-
|> Enum.max(fn -> 0 end)
55+
packument.versions |> Map.values() |> Enum.map(&version_score/1) |> Enum.max(fn -> 0 end)
6256

6357
_ ->
6458
0
6559
end
6660
end
6761

62+
defp version_score(info) do
63+
os_match = if NPM.Platform.os_compatible?(info.os), do: 1, else: 0
64+
cpu_match = if NPM.Platform.cpu_compatible?(info.cpu), do: 1, else: 0
65+
os_match + cpu_match
66+
end
67+
6868
@platform_tokens ~w(darwin linux win32 freebsd android openharmony arm64 x64 ia32 arm x86 ppc64 s390x riscv64 musl gnu msvc gnueabihf musleabihf)
6969

7070
defp package_family(name) do
71-
if platform_binding?(name) do
72-
case Regex.run(~r/^(@[^\/]+\/)/, name) do
73-
[scope | _] ->
74-
scope
75-
76-
nil ->
77-
case String.split(name, "-", parts: 2) do
78-
[prefix, _] -> prefix
79-
_ -> name
80-
end
81-
end
82-
else
83-
name
71+
if platform_binding?(name), do: binding_family(name), else: name
72+
end
73+
74+
defp binding_family(name) do
75+
case Regex.run(~r/^(@[^\/]+\/)/, name) do
76+
[scope | _] -> scope
77+
nil -> name |> String.split("-", parts: 2) |> hd()
8478
end
8579
end
8680

lib/npm/publish.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ defmodule NPM.Publish do
4343
"""
4444
@spec check_recommended(map()) :: [String.t()]
4545
def check_recommended(pkg_data) do
46-
Enum.flat_map(@recommended_fields, fn field ->
47-
if pkg_data[field], do: [], else: ["Missing recommended field: #{field}"]
48-
end)
46+
Enum.reject(@recommended_fields, &pkg_data[&1])
47+
|> Enum.map(&"Missing recommended field: #{&1}")
4948
end
5049

5150
@doc """

lib/npm/resolver.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ defmodule NPM.Resolver do
155155
defp extract_conflict_package(message) do
156156
# Look for patterns like: "ms 2.0.0" and "ms 2.1.3" in the error
157157
case Regex.scan(~r/"(\S+) (\d+\.\d+\.\d+)"/, message) do
158-
matches when length(matches) >= 2 ->
158+
[_, _ | _] = matches ->
159159
names = Enum.map(matches, fn [_, name, _] -> name end)
160160

161161
names

0 commit comments

Comments
 (0)