-
-
Save pertsevds/ab27499cad9c93a9742ce2df1d5ec258 to your computer and use it in GitHub Desktop.
Compare Phoenix Versions with extra custom steps like mix phx.gen.live Accounts User users name:string
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Usage: | |
# elixir <this_script_name.exs> 1.7.2 | |
# | |
# The script grabs a Phoenix version and places it | |
# under `phoenix/<version>` subfolder. It attempts to call | |
# a diff GUI, if there's another version found in `phoenix`. | |
# It picks the closest older version, if more than one found. | |
# | |
# Feel free to modify PhoenixCompareConfig | |
# to bring in your diff tool and add additional | |
# steps after blank project creation. | |
# | |
# | |
defmodule PhoenixCompareConfig do | |
@doc "project name to pass to mix phx.new <project_name>" | |
def project_name, do: "project" | |
@doc "Additional steps to execute on a phoenix new project. Caller expects :ok on success." | |
def run(into_path, project_name) do | |
{_, 0} = | |
cmd(["mix phx.gen.live Accounts User users name:string"], | |
cd: Path.join(into_path, project_name), | |
stderr_to_stdout: true | |
) | |
:ok | |
end | |
def maybe_diff(previous, current) do | |
case previous do | |
nil -> | |
IO.puts( | |
"Skipping diff: no version < #{current} is found processed. Request it with this script and try again." | |
) | |
_ -> | |
IO.puts("#{previous} <-> #{current}") | |
case :os.type() do | |
{:win32, _} -> | |
Task.async(fn -> | |
cmd([ | |
~S<C:\Program Files (x86)\WinMerge\WinMergeU.exe>, | |
"/r", | |
# Titles | |
"/dl", | |
"#{previous}", | |
"/dr", | |
"#{current}", | |
# Read only | |
"/wl", | |
"/wr", | |
Path.join("phoenix", [previous, "/", project_name()]), | |
Path.join("phoenix", [current, "/", project_name()]) | |
]) | |
end) | |
_ -> | |
IO.puts("Skipping diff: not implemented for #{:os.type()} yet. Please PR!") | |
end | |
end | |
end | |
def cmd([_ | _] = what, options \\ []) do | |
{cmd, args, options} = | |
case :os.type() do | |
{:win32, _} -> | |
{"cmd", ["/c"] ++ what, options} | |
# _os_name | |
# ------------ | |
# :darwin | |
# ... | |
{:unix, _os_name} -> | |
[head | tail] = what | |
{head, tail, options} | |
end | |
stream = IO.binstream(:standard_io, :line) | |
options = Keyword.put_new(options, :into, stream) | |
System.cmd(cmd, args, options) | |
end | |
end | |
defmodule Execute do | |
import PhoenixCompareConfig | |
def already_exists_fail(is_force) do | |
path = phoenix_version_path() | |
case File.stat(path) do | |
{:ok, _stat} -> | |
case is_force do | |
true -> | |
case File.rm_rf(path) do | |
{:ok, _} -> :ok | |
{:error, reason, file} -> {:error, "#{file} failed to delete due to #{reason}"} | |
end | |
false -> | |
{:error, "#{path} already exists. Add --force to force deletion"} | |
end | |
{:error, _reason} -> | |
:ok | |
end | |
end | |
def get_phx_new do | |
version = argv_as_version() | |
{_, 0} = | |
cmd(["mix", "archive.install", "--force", "hex", "phx_new", "#{Version.to_string(version)}"]) | |
:ok | |
end | |
def recreate_path do | |
path = phoenix_version_path() | |
File.rm_rf!(path) | |
:ok = File.mkdir_p(path) | |
{:ok, path} | |
end | |
def initiate_phx_new(into_path, project_name) do | |
# mix phx.new <project_name> | |
{_, 0} = | |
cmd(["mix phx.new #{project_name} --no-install"], | |
cd: into_path, | |
stderr_to_stdout: true | |
) | |
{_, 0} = | |
cmd(["mix deps.get"], | |
cd: Path.join(into_path, project_name), | |
stderr_to_stdout: true | |
) | |
run(into_path, project_name) | |
end | |
def argv_as_version do | |
if length(System.argv()) == 0 do | |
raise "Phoenix version number required" | |
end | |
[h | _] = System.argv() | |
{:ok, version} = Version.parse(h) | |
version | |
end | |
def argv_is_force do | |
Enum.find_index(System.argv(), fn v -> v == "--force" end) != nil | |
end | |
def phoenix_version_path do | |
version = argv_as_version() | |
Path.join("phoenix", "#{version}") | |
end | |
def build(src) do | |
{_, 0} = cmd(["npm run build"], cd: src) | |
:ok | |
end | |
def available_prev_version(%Version{} = version) do | |
{:ok, versions} = File.ls("phoenix") | |
sorted = Enum.sort(versions, fn a, b -> Version.compare(a, b) == :lt end) | |
idx = Enum.find_index(sorted, fn v -> v == Version.to_string(version) end) | |
cond do | |
idx > 0 -> Enum.at(sorted, idx - 1) | |
true -> nil | |
end | |
end | |
def maybe_diff(previous, current), do: PhoenixCompareConfig.maybe_diff(previous, current) | |
end | |
version = Execute.argv_as_version() | |
is_force = Execute.argv_is_force() | |
case Execute.already_exists_fail(is_force) do | |
:ok -> | |
:ok = Execute.get_phx_new() | |
{:ok, path} = Execute.recreate_path() | |
:ok = Execute.initiate_phx_new(path, PhoenixCompareConfig.project_name()) | |
{:error, reason} -> | |
IO.puts(reason) | |
end | |
previous = Execute.available_prev_version(version) | |
current = Version.to_string(version) | |
Execute.maybe_diff(previous, current) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment