Create a gist now

Instantly share code, notes, and snippets.

@teamon /Elixir.App.erl Secret
Last active Sep 18, 2016

What would you like to do?
defmodule App do
use Thor
desc "List things"
def list do
IO.puts "listing"
end
desc "Install something"
def install(name) do
IO.puts "installing #{name}"
end
end
-compile(no_auto_import).
-file("thor.exs", 48).
-module('Elixir.App').
-export(['__info__'/1, help/0, install/1, list/0,
run/1]).
-spec({{'__info__', 1},
[{type, 48, 'fun',
[{type, 48, product,
[{type, 48, union,
[{atom, 48, attributes}, {atom, 48, compile},
{atom, 48, exports}, {atom, 48, functions},
{atom, 48, macros}, {atom, 48, md5}, {atom, 48, module},
{atom, 48, native_addresses}]}]},
{type, 48, union,
[{type, 48, atom, []},
{type, 48, list,
[{type, 48, union,
[{type, 48, tuple,
[{type, 48, atom, []}, {type, 48, any, []}]},
{type, 48, tuple,
[{type, 48, atom, []}, {type, 48, byte, []},
{type, 48, integer, []}]}]}]}]}]}]}).
'__info__'(functions) ->
[{help, 0}, {install, 1}, {list, 0}, {run, 1}];
'__info__'(macros) -> [];
'__info__'(info) ->
erlang:get_module_info('Elixir.App', info).
help() ->
lists:reverse('Elixir.Enum':reduce([{install,
<<"Install something">>},
{list, <<"List things">>}],
[],
fun ({_@3, _@4}, _@1) ->
['Elixir.IO':puts(<<case _@3 of
_@5
when
erlang:is_binary(_@5) ->
_@5;
_@6 ->
'Elixir.String.Chars':to_string(_@6)
end/binary,
" - ",
case _@4 of
_@7
when
erlang:is_binary(_@7) ->
_@7;
_@8 ->
'Elixir.String.Chars':to_string(_@8)
end/binary>>)
| _@1];
(_, _@1) -> _@1
end)).
install(name@1) ->
'Elixir.IO':puts(<<"installing ",
case name@1 of
_@1 when erlang:is_binary(_@1) -> _@1;
_@2 -> 'Elixir.String.Chars':to_string(_@2)
end/binary>>).
list() -> 'Elixir.IO':puts(<<"listing">>).
run([]) -> help();
run([_@1 | _@2]) ->
erlang:apply('Elixir.App',
erlang:binary_to_atom(_@1, utf8), _@2).
defmodule Thor do
defmacro __using__(_opts) do
quote do
import Thor.Builder, only: [desc: 1]
Module.register_attribute(__MODULE__, :desc, [])
Module.register_attribute(__MODULE__, :actions, accumulate: true)
@on_definition Thor.Builder
@before_compile Thor.Builder
end
end
defmodule Builder do
defmacro desc(text) do
quote do
@desc unquote(text)
end
end
def __on_definition__(env, :def, name, _args, _guards, _body) do
if desc = Module.get_attribute(env.module, :desc) do
Module.put_attribute(env.module, :actions, {name, desc})
Module.delete_attribute(env.module, :desc)
end
end
def __on_definition__(_, _, _, _, _, _) do
end
defmacro __before_compile__(_env) do
quote do
def run([]) do
help
end
def run([action | args]) do
apply(__MODULE__, String.to_atom(action), args)
end
def help do
for {action, desc} <- @actions do
IO.puts "#{action} - #{desc}"
end
end
end
end
end
end
class Thor
def self.inherited(base)
base.extend(ClassMethods)
end
def run(args)
if cmd = args.shift
send(cmd, *args)
else
help
end
end
def help
self.class.__actions.each do |action, desc|
puts "#{action} - #{desc}"
end
end
module ClassMethods
def desc(text)
@__desc = text
end
def method_added(method)
if @__desc
__actions << [method, @__desc]
@__desc = nil
end
end
def __actions
@__actions ||= []
end
def run(args)
new.run(args)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment