Bump mix version

Mix task to quickly bump the application version

Bump mix version
Photo by Armin Babakhani / Unsplash
defmodule Mix.Tasks.BumpVersion do
  @shortdoc "Bumps the version number in mix.exs"

  @moduledoc """
  Bumps the version number in mix.exs.
  """
  use Mix.Task

  @spec run(OptionParser.argv()) :: :ok
  def run(args) do
    {opts, _, _} = OptionParser.parse(args, switches: [major: :boolean, minor: :boolean, patch: :boolean])
    current_version = :ex_svelte |> Application.spec(:vsn) |> to_string()
    new_version = bump_version(String.split(current_version, "."), opts)
    update_mix_file(current_version, new_version)
  end

  defp bump_version([major, _, _], major: true) do
    {major, _} = Integer.parse(major)
    Enum.join([major + 1, 0, 0], ".")
  end

  defp bump_version([major, minor, _], minor: true) do
    {major, _} = Integer.parse(major)
    {minor, _} = Integer.parse(minor)
    Enum.join([major, minor + 1, 0], ".")
  end

  defp bump_version([major, minor, patch], patch: true) do
    {major, _} = Integer.parse(major)
    {minor, _} = Integer.parse(minor)
    {patch, _} = Integer.parse(patch)
    Enum.join([major, minor, patch + 1], ".")
  end

  defp bump_version(current_version, _), do: Enum.join(current_version, ".")

  defp update_mix_file(current_version, current_version) do
    Mix.shell().info("No change needed. Pass a flag for either `major`, `minor` or `patch` to bump the version.")
  end

  defp update_mix_file(current_version, new_version) do
    Mix.shell().info("Updating version from #{current_version} to #{new_version}")

    File.write!(
      "mix.exs",
      String.replace(File.read!("mix.exs"), ~r/version: "#{current_version}"/, ~s(version: "#{new_version}"))
    )
  end
end