Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merging

  • Loading branch information...
commit cd6ee083588d9609ebbafa7e8f0643ab8ccfa6e1 2 parents 1abbb14 + b3fa15d
Jacob Vorreuter authored
View
10 Emakefile
@@ -0,0 +1,10 @@
+% -*- mode: erlang -*-
+
+{[
+ 'src/*'
+ ], [
+ {i, "include"},
+ {outdir, "ebin"},
+ debug_info
+ ]
+}.
View
37 Makefile
@@ -1,36 +1,23 @@
VERSION=0.3
PKGNAME=excavator
-LIBDIR=`erl -eval 'io:format("~s~n", [code:lib_dir()])' -s init stop -noshell`
-ROOTDIR=`erl -eval 'io:format("~s~n", [code:root_dir()])' -s init stop -noshell`
-all: rel
-
-compile: app
- mkdir -p ebin/
- (cd src;$(MAKE))
- (cd t;$(MAKE))
+all: emake
+emake: rel
+ mkdir -p ebin/
+ erl -make
+
+rel: release/$(PKGNAME).tar.gz
+
app:
sh ebin/$(PKGNAME).app.in $(VERSION)
+
+release/$(PKGNAME).rel release/$(PKGNAME).script release/$(PKGNAME).tar.gz: app
+ mkdir -p release
+ escript build_rel.escript $(PKGNAME)
test: compile
prove t/*.t
clean:
- (cd src;$(MAKE) clean)
- rm -rf erl_crash.dump *.boot *.rel *.script ebin/*.beam ebin/*.app
-
-rel: compile
- erl -pa ebin -noshell -run excavator build_rel -s init stop
-
-package: clean
- @mkdir $(PKGNAME)-$(VERSION)/ && cp -rf ebin include Makefile public README.markdown src support t templates $(PKGNAME)-$(VERSION)
- @COPYFILE_DISABLE=true tar zcf $(PKGNAME)-$(VERSION).tgz $(PKGNAME)-$(VERSION)
- @rm -rf $(PKGNAME)-$(VERSION)/
-
-install:
- @mkdir -p $(prefix)/$(LIBDIR)/$(PKGNAME)-$(VERSION)/{ebin,include}
- @mkdir -p $(prefix)/$(ROOTDIR)/bin
- for i in ebin/*.beam include/*.hrl ebin/*.app; do install $$i $(prefix)/$(LIBDIR)/$(PKGNAME)-$(VERSION)/$$i ; done
- cp *.boot $(prefix)/$(ROOTDIR)/bin/
- @mkdir -p $(prefix)/etc/init.d
+ rm -rf $(wildcard ebin/*.beam) erl_crash.dump *.boot *.rel *.script ebin/*.app release
View
48 build_rel.escript
@@ -0,0 +1,48 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+main([AppName]) ->
+ {ok, [{application,_,AppProps}]} = file:consult("ebin/" ++ AppName ++ ".app"),
+ AppDeps = proplists:get_value(applications, AppProps, []),
+ AppVsn = proplists:get_value(vsn, AppProps),
+ {ok, FD} = file:open("release/" ++ AppName ++ ".rel", [write]),
+ RelInfo = {release,
+ {AppName, AppVsn},
+ {erts, erts_vsn()},
+ [{Pkg, lib_vsn(Pkg)} || Pkg <- AppDeps]
+ },
+ io:format(FD, "~p.", [RelInfo]),
+ file:close(FD),
+ systools:make_script("release/" ++ AppName, [{exref, AppDeps}, {outdir, "release"}]),
+ systools:make_tar("release/" ++ AppName, [{dirs, tar_dirs()}, {outdir, "release"}]),
+ ok.
+
+erts_vsn() ->
+ erlang:system_info(version).
+
+lib_vsn(App) ->
+ load(App),
+ {ok, Vsn} = application:get_key(App, vsn),
+ Vsn.
+
+load(App) ->
+ case application:load(App) of
+ ok ->
+ ok;
+ {error, {already_loaded, _}} ->
+ ok;
+ E ->
+ io:format(standard_error, "Warning - can't load ~p (~p)~n", [App, E]),
+ erlang:exit(E)
+ end.
+
+tar_dirs() ->
+ {ok, Files} = file:list_dir("."),
+ [list_to_atom(Dir) || Dir <- lists:filter(
+ fun ("." ++ _) -> false;
+ (File) ->
+ filelib:is_dir(File) andalso not lists:member(File, ["ebin", "include", "t"])
+ end, Files)].
+
+
+
View
2  ebin/excavator.app.in
@@ -12,6 +12,6 @@ ${MODULES}
]},
{registered, []},
{mod, {excavator, []}},
- {applications, [kernel, stdlib, inets]}
+ {applications, [kernel, stdlib, inets, dynamic_compile, mochixpath]}
]}.
EOF
View
4 excavator.epm
@@ -1,5 +1,7 @@
[{deps, [
{"clones/mochiweb", []},
{"mochixpath", []},
- {"dynamic_compile", []}
+ {"dynamic_compile", []},
+ {"etap", []},
+ {"JacobVorreuter/mochiweb_server_behavior", []}
]}].
View
2  include/excavator.hrl
@@ -8,8 +8,8 @@
last_value
}).
--record(http_resp, {status, headers, body, cookies}).
-record(http_req, {method=get, url=[], headers=[], body=[], options=[]}).
+-record(http_resp, {status, headers, body, cookies}).
-define(DBG_REPORT(Args), ex_logger:debug_report(Args)).
-define(DBG_MSG(Format, Args), ex_logger:debug_msg(Format, Args)).
View
9 src/Makefile
@@ -1,9 +0,0 @@
-include ../support/include.mk
-
-all: $(EBIN_FILES)
-
-debug:
- $(MAKE) DEBUG=-DDEBUG
-
-clean:
- rm -rf $(EBIN_FILES) erl_crash.dump
View
3  src/ex_eval.erl
@@ -58,7 +58,7 @@ expand(State, {cookie, CookieName, HttpRespKey}) ->
case expand(State, HttpRespKey) of
#http_resp{cookies=Cookies} ->
case proplists:get_value(CookieName, Cookies) of
- {cookie, _, Fields} ->
+ {resp_cookie, _, Fields} ->
proplists:get_value(CookieName, Fields);
_ ->
undefined
@@ -133,6 +133,7 @@ flatten_url(State, {Url, Props}) ->
flatten_url(State, Url) ->
case ex_util:typeof(Url) of
+ atom -> expand(State, Url);
string -> Url;
list -> lists:concat([expand(State, I) || I <- Url])
end.
View
96 src/ex_pp.erl
@@ -21,7 +21,7 @@
%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
%% OTHER DEALINGS IN THE SOFTWARE.
-module(ex_pp).
--export([parse/1, parse/2]).
+-export([parse/1, parse/2, forms/2]).
-export([purge/1, delete/1]).
-define(L, 4).
@@ -33,46 +33,52 @@ parse(Filename, MainArgs) when is_list(Filename) ->
ModuleName = compile(Filename),
erlang:apply(ModuleName, main, MainArgs).
+forms(Filename, ModuleName) ->
+ case (catch epp:parse_file(Filename,[],[])) of
+ {ok, Forms} ->
+ {_,Indices} = lists:foldl(
+ fun ({attribute,_,file,{_,_}}, {I, Acc}) ->
+ {I+1, [{attribute, I}|Acc]};
+ ({function,_,main,_,_}, {I, Acc}) ->
+ {I+1, [{main, [I | proplists:get_value(main, Acc, [])]}|Acc]};
+ (_, {I, Acc}) ->
+ {I+1, Acc}
+ end, {1, []}, Forms),
+
+ case proplists:get_value(attribute, Indices) of
+ 1 -> ok;
+ _ -> exit({error, bad_file_attribute})
+ end,
+
+ case proplists:get_value(main, Indices) of
+ undefined -> exit({error, missing_main_function});
+ _ -> ok
+ end,
+
+ [{attribute,1,file,{Filename,1}},
+ {attribute,1,module, ModuleName},
+ {attribute,1,compile,[export_all]}] ++
+ parse_include() ++
+ [process_root_level_form(Form) || Form <- lists:nthtail(1, Forms)];
+
+ {'EXIT', Err} ->
+ exit(Err);
+ Other ->
+ exit({parse_error, Other})
+ end.
+
compile(Filename) ->
ModuleName = module_name(Filename, application:get_env(excavator, randomize_module_names)),
case code:is_loaded(ModuleName) of
{file, _} -> ok;
false ->
- case catch epp:parse_file(Filename,[],[]) of
- {ok, Forms} ->
- {_,Indices} = lists:foldl(
- fun ({attribute,_,file,{_,_}}, {I, Acc}) ->
- {I+1, [{attribute, I}|Acc]};
- ({function,_,main,_,_}, {I, Acc}) ->
- {I+1, [{main, [I | proplists:get_value(main, Acc, [])]}|Acc]};
- (_, {I, Acc}) ->
- {I+1, Acc}
- end, {1, []}, Forms),
-
- case proplists:get_value(attribute, Indices) of
- 1 -> ok;
- _ -> exit({error, bad_file_attribute})
- end,
-
- case proplists:get_value(main, Indices) of
- undefined -> exit({error, missing_main_function});
- _ -> ok
- end,
-
- Forms1 =
- [{attribute,1,file,{Filename,1}},
- {attribute,1,module, ModuleName},
- {attribute,1,compile,[export_all]}] ++
- parse_include() ++
- [process_root_level_form(Form) || Form <- lists:nthtail(1, Forms)],
-
- {ok, Mod, Bins} = compile:forms(Forms1, [verbose,report_errors]),
- code:load_binary(Mod, atom_to_list(Mod), Bins);
- {'EXIT', Err} ->
- exit(Err);
- Other ->
- exit({parse_error, Other})
- end
+ Forms = forms(Filename, ModuleName),
+ case compile:forms(Forms, [verbose,report_errors]) of
+ {ok, Mod, Bins} ->
+ code:load_binary(Mod, atom_to_list(Mod), Bins);
+ error ->
+ exit(normal)
+ end
end,
ModuleName.
@@ -127,8 +133,10 @@ module_name(_, {ok, true}) ->
random:seed(A,B,C),
list_to_atom([random:uniform(26) + 96 || _ <- lists:seq(1,32)]);
-module_name(Filename, _) ->
- list_to_atom(binary_to_list(erlang:md5(Filename))).
+module_name(FilePath, _) ->
+ [Filename|_] = lists:reverse(string:tokens(FilePath, "/")),
+ [ModuleName|_] = string:tokens(Filename, "."),
+ list_to_atom(ModuleName).
build_instrs(Tokens) ->
[build_instr(Token) || Token <- Tokens].
@@ -250,9 +258,21 @@ expand_arg({call, _, {atom, _, read_file}, [Filename]}) ->
expand_arg({call, _, {atom, _, open_file}, [Filename, Modes]}) ->
{tuple, ?L, [{atom,?L,open}, expand_arg(Filename), expand_arg(Modes)]};
+expand_arg({call, _, {atom, _, cookie}, [CookieName, Key]}) ->
+ {tuple, ?L, [{atom,?L,cookie}, expand_arg(CookieName), expand_arg(Key)]};
+
expand_arg({call, _, {atom, _, call}, [Module, Function, Args]}) ->
{tuple, ?L, [{atom,?L,call}, expand_arg(Module), expand_arg(Function), expand_arg(Args)]};
+expand_arg({tuple, _, Args}) ->
+ {tuple, ?L, expand_args(Args)};
+
+expand_arg({cons, _, Arg, {nil, _}}) ->
+ {cons, ?L, expand_arg(Arg), {nil, ?L}};
+
+expand_arg({cons, _, Arg, Cons}) ->
+ {cons, ?L, expand_arg(Arg), expand_arg(Cons)};
+
expand_arg(Other) -> Other.
preprocess_arg({tuple, _, [{atom,_,regexp},{atom,_,Key},{string,_,Regexp}]}) ->
View
2  src/ex_util.erl
@@ -87,6 +87,8 @@ typeof([H|_]=List) when is_integer(H) ->
fun (I, string) when is_integer(I) -> string;
(_, _) -> list
end, string, List);
+typeof(List) when is_binary(List) -> binary;
typeof(List) when is_list(List) -> list;
typeof(Fun) when is_function(Fun) -> function;
+typeof(Atom) when is_atom(Atom) -> atom;
typeof(_) -> term.
View
16 src/ex_web.erl
@@ -21,7 +21,7 @@
%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
%% OTHER DEALINGS IN THE SOFTWARE.
-module(ex_web).
--export([request/5]).
+-export([request/1, request/2, request/3, request/4, request/5]).
-include("excavator.hrl").
@@ -33,6 +33,18 @@
{"User-Agent","Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.5) Gecko/2008120121 Firefox/3.0.5"}
]).
+request(Url) ->
+ request(get, Url, [], [], []).
+
+request(Method, Url) ->
+ request(Method, Url, [], [], []).
+
+request(Method, Url, Headers) ->
+ request(Method, Url, Headers, [], []).
+
+request(Method, Url, Headers, Body) ->
+ request(Method, Url, Headers, Body, []).
+
request(Method, Url, [], Body, Options) -> request(Method, Url, ?HEADERS, Body, Options);
request(Method, Url, Headers, [], Options)
@@ -77,6 +89,6 @@ get_cookies(Headers) ->
end
end || Field <- string:tokens(CookieString, ";")],
[{Name,_}|_] = Fields,
- dict:store(Name, {cookie, CookieString, Fields}, Dict)
+ dict:store(Name, {resp_cookie, CookieString, Fields}, Dict)
end, dict:new(), Values))
end.
View
4 src/ex_xpath.erl
@@ -31,9 +31,9 @@ run(XPath, #http_resp{body=Body}) ->
run(XPath, {A,B,C}) when is_binary(A), is_list(B), is_list(C) ->
run_internal(XPath, {A,B,C});
-run(XPath, Subject0) when is_list(XPath), is_list(Subject0) ->
+run(XPath, Subject0) when is_list(XPath) ->
case ex_util:typeof(Subject0) of
- string ->
+ String when String == string; String == binary ->
case (catch mochiweb_html:parse(Subject0)) of
{'EXIT', {{badmatch,[]},_}} ->
[];
View
2  src/excavator.erl
@@ -55,7 +55,7 @@ build_rel() ->
{"excavator", "0.3"},
get_app_version(erts),
[get_app_version(AppName) || AppName <- Apps] ++ [
- {mochiweb, "0.2"},
+ {mochiweb, "0.01"},
{mochixpath, "0.1"},
{dynamic_compile, "0.1"},
{excavator, "0.3"}
View
38 support/include.mk
@@ -1,38 +0,0 @@
-## -*- makefile -*-
-
-ERL := erl
-ERLC := $(ERL)c
-
-INCLUDE_DIRS := ../include
-EBIN_DIRS := $(wildcard ../ebin)
-ERLC_FLAGS := -W $(INCLUDE_DIRS:../%=-I ../%) $(EBIN_DIRS:%=-pa %)
-
-ifndef no_debug_info
- ERLC_FLAGS += +debug_info
-endif
-
-ifdef debug
- ERLC_FLAGS += -Ddebug
-endif
-
-EBIN_DIR := ../ebin
-DOC_DIR := ../doc
-EMULATOR := beam
-
-ERL_SOURCES := $(wildcard *.erl)
-ERL_HEADERS := $(wildcard *.hrl) $(wildcard ../include/*.hrl)
-ERL_OBJECTS := $(ERL_SOURCES:%.erl=$(EBIN_DIR)/%.beam)
-ERL_TEMPLATES := $(ERL_TEMPLATE:%.et=$(EBIN_DIR)/%.beam)
-ERL_OBJECTS_LOCAL := $(ERL_SOURCES:%.erl=./%.$(EMULATOR))
-APP_FILES := $(wildcard *.app)
-EBIN_FILES = $(ERL_OBJECTS) $(APP_FILES:%.app=../ebin/%.app) $(ERL_TEMPLATES)
-MODULES = $(ERL_SOURCES:%.erl=%)
-
-../ebin/%.app: %.app
- cp $< $@
-
-$(EBIN_DIR)/%.$(EMULATOR): %.erl
- $(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $<
-
-./%.$(EMULATOR): %.erl
- $(ERLC) $(ERLC_FLAGS) -o . $<
View
9 t/Makefile
@@ -1,9 +0,0 @@
-include ../support/include.mk
-
-all: $(EBIN_FILES)
-
-debug:
- $(MAKE) DEBUG=-DDEBUG
-
-clean:
- rm -rf $(EBIN_FILES) erl_crash.dump
View
25 t/excavator_t_007.t
@@ -0,0 +1,25 @@
+#!/usr/local/bin/escript
+%% -*- erlang -*-
+%%! -pa ../excavator -pa ebin -sasl errlog_type error -boot start_sasl -noshell
+
+main(_) ->
+ etap:plan(unknown),
+ case (catch start()) of
+ {'EXIT', Err} ->
+ io:format("# ~p~n", [Err]),
+ etap:bail();
+ _ ->
+ etap:end_tests()
+ end,
+ ok.
+
+start() ->
+ error_logger:tty(false),
+ application:start(inets),
+ application:start(excavator),
+ test_server:start_link(),
+
+ Instrs = ex_pp:parse("templates/function_tests.ex", []),
+ etap:is(ex_engine:run(Instrs), "abc", "function test passes"),
+
+ ok.
View
10 templates/function_tests.ex
@@ -0,0 +1,10 @@
+main() ->
+ assign(x, myfunc()),
+
+ x.
+
+myfunc() ->
+ assign(y, "abc"),
+
+ y.
+
View
2  templates/github.ex
@@ -1,7 +1,7 @@
main(Users) ->
each(user, Users, [
%% fetch user's public activity
- assign(public_activity, #http_req{url=["http://127.0.0.1:8888/github-", user, ".xml"]}),
+ assign(public_activity, http(["http://127.0.0.1:8888/github-", user, ".xml"])),
assert(public_activity, {status, 200}),
%% pull entry nodes

0 comments on commit cd6ee08

Please sign in to comment.
Something went wrong with that request. Please try again.