-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