Current section

Files

Jump to
mob_dev lib mix tasks mob.icon.ex
Raw

lib/mix/tasks/mob.icon.ex

defmodule Mix.Tasks.Mob.Icon do
use Mix.Task
@shortdoc "Generate or regenerate app icons"
@moduledoc """
Generates platform icons for the current Mob project.
Must be run from the project root (the directory containing `mix.exs`).
mix mob.icon # random robot avatar
mix mob.icon --source PATH # resize an existing image
## Output
Writes icons into the current project directory:
- `android/app/src/main/res/mipmap-*/ic_launcher.png`
- `ios/Assets.xcassets/AppIcon.appiconset/icon_*.png`
- `ios/Assets.xcassets/AppIcon.appiconset/Contents.json`
- `icon_source.png` (1024×1024 master, only when generating)
## Under the hood
`mix mob.icon` uses the `image` Elixir library (backed by `libvips`) to resize a
1024×1024 source PNG into every required platform size:
# Android (mipmap-mdpi through mipmap-xxxhdpi: 48px → 192px)
Image.thumbnail(source, size) |> Image.write(dest)
# iOS (20px → 1024px, all required AppIcon sizes)
Image.thumbnail(source, size) |> Image.write(dest)
# also writes Contents.json for Xcode
No external tools (ImageMagick, Xcode, etc.) are required — `libvips` is
bundled as a precompiled NIF via the `image` dependency.
"""
@switches [source: :string]
@impl Mix.Task
def run(argv) do
{opts, _args, _} = OptionParser.parse(argv, strict: @switches)
project_dir = File.cwd!()
unless File.exists?(Path.join(project_dir, "mix.exs")) do
Mix.raise("No mix.exs found. Run mix mob.icon from your project root.")
end
case opts[:source] do
nil ->
Mix.shell().info("Generating random robot icon...")
MobDev.IconGenerator.generate_random(project_dir)
source ->
unless File.exists?(source) do
Mix.raise("Source file not found: #{source}")
end
Mix.shell().info("Resizing icon from #{source}...")
MobDev.IconGenerator.generate_from_source(source, project_dir)
end
Mix.shell().info("Icons written to #{project_dir}")
Mix.shell().info(" Android: android/app/src/main/res/mipmap-*/ic_launcher.png")
Mix.shell().info(" iOS: ios/Assets.xcassets/AppIcon.appiconset/")
end
end