defmodule Mix.Tasks.Npm.Cache do @shortdoc "Manage the npm package cache" @moduledoc """ Manage the global npm package cache. mix npm.cache status # Show cache location and size mix npm.cache clean # Remove all cached packages """ use Mix.Task @impl true def run(["status"]) do Application.ensure_all_started(:req) cache_dir = NPM.Cache.dir() if File.exists?(cache_dir) do {size, count} = dir_stats(cache_dir) Mix.shell().info("Cache: #{cache_dir}") Mix.shell().info("Size: #{NPM.FormatUtil.format_size(size)}") Mix.shell().info("Packages: #{count}") else Mix.shell().info("Cache: #{cache_dir} (empty)") end end def run(["clean"]) do Application.ensure_all_started(:req) cache_dir = NPM.Cache.dir() if File.exists?(cache_dir) do {size, count} = dir_stats(cache_dir) File.rm_rf!(cache_dir) Mix.shell().info("Removed #{count} packages (#{NPM.FormatUtil.format_size(size)})") else Mix.shell().info("Cache is already empty.") end end def run(_) do Mix.shell().error("Usage: mix npm.cache [status|clean]") end defp dir_stats(path) do path |> Path.join("**/*") |> Path.wildcard() |> Enum.reduce({0, 0}, fn file, {size, count} -> case File.stat(file) do {:ok, %{type: :regular, size: s}} -> {size + s, count + 1} _ -> {size, count} end end) end end