Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

reformatting and todo: learning the code

  • Loading branch information...
commit d61a5d126daf8e6c554ddc1bef819828ee3f2d0b 1 parent 36e9f97
Dmytro Lytovchenko authored
View
41 README.markdown
@@ -1,3 +1,9 @@
+# How did this project get here?
+
+http://hyperthunk.wordpress.com/2012/05/28/does-erlangotp-need-a-new-package-management-solution/
+
+--------------------
+
### epm _IS_
* an Erlang package manager meant to have _minimal_ impact on projects
* a simple and easy dependency tracker
@@ -11,13 +17,13 @@
curl "https://github.com/JacobVorreuter/epm/raw/master/epm" > epm
chmod +x epm
sudo mv epm /usr/local/bin/
-
+
epm config --set build_dir "/tmp"
epm config --set install_dir "/Users/jvorreuter/erl_libs"
epm config --set proxy_host http://my.corporate.proxy
epm config --set proxy_port 80
epm config --set net_timeout 60000 # for a slow network...
-
+
### Read the blog post
<http://www.jkvor.com/erlang-package-manager>
@@ -77,7 +83,7 @@
--get (default)
--set <key> <value>
--remove <key>
-
+
### Do it
tell epm where to install packages
@@ -86,8 +92,8 @@ tell epm where to install packages
epm v0.1.1, 2010
+ updated .epm config
-
-search for an Erlang app
+
+search for an Erlang app
jvorreuter$ ./epm search excavator
epm v0.1.1, 2010
@@ -98,7 +104,7 @@ search for an Erlang app
name: excavator
owner: JacobVorreuter
followers: 7
- homepage:
+ homepage:
description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
tags:
"0.3"
@@ -106,7 +112,7 @@ search for an Erlang app
master
scheduler
-install that app that you wanted (its dependencies will be installed too)
+install that app that you wanted (its dependencies will be installed too)
jvorreuter$ ./epm install excavator
epm v0.1.1, 2010
@@ -142,7 +148,7 @@ install that app that you wanted (its dependencies will be installed too)
+ running excavator build command
+ running excavator install command
-get some info about that app you just installed
+get some info about that app you just installed
jvorreuter$ ./epm info excavator
epm v0.1.1, 2010
@@ -154,16 +160,16 @@ get some info about that app you just installed
owner: JacobVorreuter
vsn: master
install dir: /Users/jvorreuter/dev/excavator-0.3
- homepage:
+ homepage:
description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
- dependencies:
+ dependencies:
clones/mochiweb/master
mochixpath/master
dynamic_compile/master
epm/etap/master
mochiweb_server_behavior/master
-how 'bout a list of all apps I've installed?
+how 'bout a list of all apps I've installed?
jvorreuter$ ./epm list
epm v0.1.1, 2010
@@ -175,9 +181,9 @@ how 'bout a list of all apps I've installed?
owner: JacobVorreuter
vsn: master
install dir: /Users/jvorreuter/dev/excavator-0.3
- homepage:
+ homepage:
description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
- dependencies:
+ dependencies:
clones/mochiweb/master
mochixpath/master
dynamic_compile/master
@@ -195,23 +201,23 @@ how 'bout a list of all apps I've installed?
owner: JacobVorreuter
vsn: master
install dir: /Users/jvorreuter/dev/dynamic_compile-0.1
- homepage:
+ homepage:
description: compile and load erlang modules from string input
name: mochiweb_server_behavior
owner: JacobVorreuter
vsn: master
install dir: /Users/jvorreuter/dev/mochiweb_server_behavior-0.1
- homepage:
+ homepage:
description: Erlang behavior for a simple mochiweb web server
- dependencies:
+ dependencies:
clones/mochiweb/master
name: etap
owner: epm
vsn: master
install dir: /Users/jvorreuter/dev/etap-0.3.4
- homepage:
+ homepage:
description: etap is a simple erlang testing library that provides TAP compliant output.
name: mochiweb
@@ -234,4 +240,3 @@ what have I done? I must remove that terrible app. Its dependencies can stay tho
([y]/n) y
+ removing package JacobVorreuter-excavator-master from /Users/jvorreuter/dev/excavator-0.3
-
View
3  include/epm.hrl
@@ -1,3 +1,6 @@
+-define(epm_version, "0.1.1").
+-define(epm_year, 2014).
+
-define(EXIT(Format, Args), exit(lists:flatten(io_lib:format(Format, Args)))).
-record(repository, {name, owner, description, homepage, followers, pushed, api_module}).
View
184 src/bitbucket_api.erl
@@ -1,23 +1,23 @@
-%% OMFG, this API sucks.
+%% OMFG, this API sucks.
%%
%% explain to me how this is even remotely useful:
%% jacobvorreuter$ curl "http://api.bitbucket.org/1.0/repositories/?name=rebar"
%% {
-%% "count": 12,
-%% "query": "rebar",
+%% "count": 12,
+%% "query": "rebar",
%% "repositories": [
%% {
-%% "website": "",
-%% "slug": "rebar",
-%% "name": "rebar",
-%% "followers_count": 0,
+%% "website": "",
+%% "slug": "rebar",
+%% "name": "rebar",
+%% "followers_count": 0,
%% "description": ""
-%% },
+%% },
%% {
-%% "website": null,
-%% "slug": "rebar",
-%% "name": "rebar",
-%% "followers_count": 0,
+%% "website": null,
+%% "slug": "rebar",
+%% "name": "rebar",
+%% "followers_count": 0,
%% "description": ""
%% },
%% ...
@@ -35,52 +35,55 @@
-include("epm.hrl").
package_deps(User, ProjectName, Vsn) ->
- if
- User == undefined -> ?EXIT("get_package_deps/3 user cannot be undefined",[]);
- true -> ok
- end,
- if
- ProjectName == undefined -> ?EXIT("get_package_deps/3 name cannot be undefined",[]);
- true -> ok
- end,
- if
- Vsn == undefined -> ?EXIT("get_package_deps/3 vsn cannot be undefined",[]);
- true -> ok
- end,
- Url = lists:flatten(io_lib:format("http://bitbucket.org/~s/~s/raw/~s/~s.epm", [User, ProjectName, Vsn, ProjectName])),
- case epm_util:request_as_str(Url, "bitbucket.org") of
- Body when is_list(Body) -> proplists:get_value(deps, epm_util:eval(Body), []);
- _ -> []
- end.
-
+ if
+ User == undefined ->
+ ?EXIT("get_package_deps/3 user cannot be undefined", []);
+ true -> ok
+ end,
+ if
+ ProjectName == undefined ->
+ ?EXIT("get_package_deps/3 name cannot be undefined", []);
+ true -> ok
+ end,
+ if
+ Vsn == undefined -> ?EXIT("get_package_deps/3 vsn cannot be undefined", []);
+ true -> ok
+ end,
+ Url = lists:flatten(io_lib:format("http://bitbucket.org/~s/~s/raw/~s/~s.epm", [User, ProjectName, Vsn, ProjectName])),
+ case epm_util:request_as_str(Url, "bitbucket.org") of
+ Body when is_list(Body) ->
+ proplists:get_value(deps, epm_util:eval(Body), []);
+ _ -> []
+ end.
+
search(ProjectName) ->
- case request_as_xml("http://bitbucket.org/repo/all/?name=" ++ ProjectName) of
- {html,_,_}=Html ->
- case search_xml_for_repos(Html) of
- undefined -> [];
- Repos -> extract_repo_info_from_html(Repos)
- end;
- Err ->
- Err
- end.
-
-info(User, ProjectName) ->
- case search(ProjectName) of
- [#repository{}|_]=Repos ->
- case lists:filter(
- fun(Repo) ->
- Repo#repository.owner==User andalso
- Repo#repository.name==ProjectName
- end, Repos) of
- [R|_] -> R;
- _ -> undefined
- end;
- [] ->
- undefined;
- Err ->
- Err
- end.
-
+ case request_as_xml("http://bitbucket.org/repo/all/?name=" ++ ProjectName) of
+ {html, _, _} = Html ->
+ case search_xml_for_repos(Html) of
+ undefined -> [];
+ Repos -> extract_repo_info_from_html(Repos)
+ end;
+ Err ->
+ Err
+ end.
+
+info(User, ProjectName) ->
+ case search(ProjectName) of
+ [#repository{}|_] = Repos ->
+ case lists:filter(
+ fun(Repo) ->
+ Repo#repository.owner == User andalso
+ Repo#repository.name == ProjectName
+ end , Repos) of
+ [R|_] -> R;
+ _ -> undefined
+ end;
+ [] ->
+ undefined;
+ Err ->
+ Err
+ end.
+
tags(User, ProjectName) ->
Xml = request_as_xml(lists:flatten(io_lib:format("http://api.bitbucket.org/1.0/repositories/~s/~s/tags/?format=xml", [User, ProjectName]))),
case Xml of
@@ -102,26 +105,26 @@ branches(User, ProjectName) ->
download_package(Repo, Vsn) ->
Url = lists:flatten(io_lib:format("http://bitbucket.org/~s/~s/get/~s.tar.gz", [Repo#repository.owner, Repo#repository.name, Vsn])),
epm_package:download_tarball(Repo, Url).
-
+
default_vsn() -> "tip".
request_as_xml(Url) ->
- case epm_util:request_as_str(Url, "bitbucket.org") of
- Body when is_list(Body) ->
- case yaws_html:h2e(Body) of
- {ehtml,[],[_,Xml]} -> Xml;
- _ -> poorly_formatted_xml
- end;
- Err ->
- Err
- end.
-
+ case epm_util:request_as_str(Url, "bitbucket.org") of
+ Body when is_list(Body) ->
+ case yaws_html:h2e(Body) of
+ {ehtml, [], [_, Xml]} -> Xml;
+ _ -> poorly_formatted_xml
+ end;
+ Err ->
+ Err
+ end.
+
%% fake xpaths
-search_xml_for_repos({'div',[{class,"repos-all"}|_],Repos}) ->
+search_xml_for_repos({'div',[{class,"repos-all"}|_],Repos}) ->
Repos;
search_xml_for_repos({_,_,Children}) ->
- search_xml_for_repos(Children);
+ search_xml_for_repos(Children);
search_xml_for_repos([Child|Tail]) when not is_integer(Child) ->
case search_xml_for_repos(Child) of
undefined ->
@@ -132,24 +135,23 @@ search_xml_for_repos([Child|Tail]) when not is_integer(Child) ->
search_xml_for_repos(_) -> undefined.
extract_repo_info_from_html(Repos) ->
- lists:foldl(
- fun({'div',_,Props}, Acc) ->
- case Props of
- [{'div',_,_},{span,[],[{a,_,User},_,{a,_,RepoName}]},{br,_},Desc|_] ->
- Desc1 = string:strip(re:replace(Desc, "[\\t\\n]", "", [global, {return, list}])),
- Desc2 =
- case Desc1 of
- "Clone URL" ++ _ -> undefined;
- _ -> Desc1
- end,
- [#repository{
- owner = User,
- name = RepoName,
- description = Desc2,
- api_module = ?MODULE
- }|Acc];
- _ ->
- Acc
- end
- end, [], lists:reverse(Repos)).
-
+ lists:foldl(
+ fun({'div', _, Props}, Acc) ->
+ case Props of
+ [{'div', _, _}, {span, [], [{a, _, User}, _, {a, _, RepoName}]}, {br, _}, Desc|_] ->
+ Desc1 = string:strip(re:replace(Desc, "[\\t\\n]", "", [global, {return, list}])),
+ Desc2 =
+ case Desc1 of
+ "Clone URL" ++ _ -> undefined;
+ _ -> Desc1
+ end,
+ [#repository{
+ owner = User ,
+ name = RepoName ,
+ description = Desc2,
+ api_module = ?MODULE
+ }|Acc];
+ _ ->
+ Acc
+ end
+ end, [], lists:reverse(Repos)).
View
127 src/epm.erl
@@ -3,70 +3,71 @@
-include("epm.hrl").
main(Args) ->
- put(vsn, "0.1.1"),
-
- io:format("epm v~s, 2010~n~n", [get(vsn)]),
-
- application:load(sasl),
- application:set_env(sasl, sasl_error_logger, false),
- lists:map(fun application:start/1, [sasl, crypto, public_key, ssl, ibrowse, epm]),
+ %% TODO: Remove put/get
+ put(vsn, ?epm_version),
+ io:format("epm v~s, ~p~n~n", [?epm_version, ?epm_year]),
- case (catch main1(Args)) of
- {'EXIT', ErrorMsg} when is_list(ErrorMsg) ->
- io:format("- ~s~n", [ErrorMsg]);
- {'EXIT', Other} ->
- io:format("~p~n", [Other]);
- _ ->
- ok
- end,
-
- dets:close(epm_index),
+ application:load(sasl),
+ application:set_env(sasl, sasl_error_logger, false),
+ lists:map(fun application:start/1, [sasl, crypto, public_key, ssl, ibrowse, epm]),
+
+ case (catch main1(Args)) of
+ {'EXIT', ErrorMsg} when is_list(ErrorMsg) ->
+ io:format("- ~s~n", [ErrorMsg]);
+ {'EXIT', Other} ->
+ io:format("~p~n", [Other]);
+ _ ->
+ ok
+ end,
+
+ dets:close(epm_index),
io:format("~n").
-
-main1(Args) ->
- Home = epm_util:home_dir(),
- EpmHome = epm_util:epm_home_dir(Home),
- epm_util:open_dets_table(Home, EpmHome),
-
- %% consult global .epm config file in home directory
- case file:path_consult(["."] ++ Home ++ [code:root_dir()], ".epm") of
- {ok, [GlobalConfig], FileLoc} ->
-
- put(global_config, FileLoc),
-
- case proplists:get_value(install_dir, GlobalConfig) of
- undefined ->
- io:format("################ Warning ################~n"),
- io:format("You have not specified a value for ~n"),
- io:format("install_dir in your .epm config file. The~n"),
- io:format("current working directory will be used.~n~n"),
- io:format("run `epm config --set install_dir <path>`~n"),
- io:format("#########################################~n~n"),
- ok;
- InstallDir -> epm_util:add_to_path(InstallDir)
- end,
-
- setup_connectivity(GlobalConfig),
-
- epm_core:execute(GlobalConfig, Args);
- {ok, [], FileLoc} ->
- put(global_config, FileLoc),
- epm_core:execute([], Args);
- {error, enoent} ->
- file:write_file(filename:join([Home, ".epm"]), <<>>),
- put(global_config, filename:join([Home, ".epm"])),
- epm_core:execute([], Args);
- {error, Reason} ->
- ?EXIT("failed to read epm global config: ~p", [Reason])
- end.
+
+main1(Args) ->
+ Home = epm_util:home_dir(),
+ EpmHome = epm_util:epm_home_dir(Home),
+ epm_util:open_dets_table(Home, EpmHome),
+
+ %% consult global .epm config file in home directory
+ case file:path_consult(["."] ++ Home ++ [code:root_dir()], ".epm") of
+ {ok, [GlobalConfig], FileLoc} ->
+
+ %% TODO: Remove put/get
+ put(global_config, FileLoc),
+
+ case proplists:get_value(install_dir, GlobalConfig) of
+ undefined ->
+ io:format("################ Warning ################~n"),
+ io:format("You have not specified a value for ~n"),
+ io:format("install_dir in your .epm config file. The~n"),
+ io:format("current working directory will be used.~n~n"),
+ io:format("run `epm config --set install_dir <path>`~n"),
+ io:format("#########################################~n~n"),
+ ok;
+ InstallDir -> epm_util:add_to_path(InstallDir)
+ end,
+
+ setup_connectivity(GlobalConfig),
+
+ epm_core:execute(GlobalConfig, Args);
+ {ok, [], FileLoc} ->
+ put(global_config, FileLoc),
+ epm_core:execute([], Args);
+ {error, enoent} ->
+ file:write_file(filename:join([Home, ".epm"]), <<>>),
+ put(global_config, filename:join([Home, ".epm"])),
+ epm_core:execute([], Args);
+ {error, Reason} ->
+ ?EXIT("failed to read epm global config: ~p", [Reason])
+ end.
setup_connectivity(GlobalConfig) ->
- case proplists:get_value(proxy_host, GlobalConfig) of
- undefined ->
- epm_util:set_http_proxy(none, none);
- Host ->
- Port = proplists:get_value(proxy_port, GlobalConfig, "8080"),
- epm_util:set_http_proxy(Host, Port)
- end,
- Timeout = proplists:get_value(net_timeout, GlobalConfig, 6000),
- epm_util:set_net_timeout(Timeout).
+ case proplists:get_value(proxy_host, GlobalConfig) of
+ undefined ->
+ epm_util:set_http_proxy(none, none);
+ Host ->
+ Port = proplists:get_value(proxy_port, GlobalConfig, "8080"),
+ epm_util:set_http_proxy(Host, Port)
+ end,
+ Timeout = proplists:get_value(net_timeout, GlobalConfig, 6000),
+ epm_util:set_net_timeout(Timeout).
View
1,207 src/epm_core.erl
@@ -6,209 +6,209 @@
-define(DEFAULT_API_MODULES, [github_api]).
execute(GlobalConfig0, ["install" | Args]) ->
- {GlobalConfig, Packages, Flags} = collect_args(install, Args, GlobalConfig0),
- put(verbose, lists:member(verbose, Flags)),
- Deps = package_dependencies(GlobalConfig, Packages),
- {Installed, NotInstalled} = filter_installed_packages(Deps),
- case NotInstalled of
- [] ->
- io:format("+ nothing to do: packages and dependencies already installed~n");
- _ ->
- case Installed of
- [] -> ok;
- _ ->
- io:format("===============================~n"),
- io:format("Packages already installed:~n"),
- io:format("===============================~n"),
- [begin
- io:format(" + ~s-~s-~s (~s)~n", [U,N,V,AppVsn])
- end || #package{user=U, name=N, vsn=V, app_vsn=AppVsn} <- Installed]
- end,
- io:format("===============================~n"),
- io:format("Install the following packages?~n"),
- io:format("===============================~n"),
- [io:format(" + ~s-~s-~s~n", [U,N,V]) || #package{user=U, name=N, vsn=V} <- NotInstalled],
- io:format("~n([y]/n) "),
- case io:get_chars("", 1) of
- C when C == "y"; C == "\n" ->
- io:format("~n"),
- [install_package(GlobalConfig, Package) || Package <- NotInstalled];
- _ -> ok
- end
- end;
+ {GlobalConfig, Packages, Flags} = collect_args(install, Args, GlobalConfig0),
+ put(verbose, lists:member(verbose, Flags)),
+ Deps = package_dependencies(GlobalConfig, Packages),
+ {Installed, NotInstalled} = filter_installed_packages(Deps),
+ case NotInstalled of
+ [] ->
+ io:format("+ nothing to do: packages and dependencies already installed~n");
+ _ ->
+ case Installed of
+ [] -> ok;
+ _ ->
+ io:format("===============================~n"),
+ io:format("Packages already installed:~n"),
+ io:format("===============================~n"),
+ [begin
+ io:format(" + ~s-~s-~s (~s)~n", [U, N, V, AppVsn])
+ end || #package{user = U, name = N, vsn = V, app_vsn = AppVsn} <- Installed]
+ end,
+ io:format("===============================~n"),
+ io:format("Install the following packages?~n"),
+ io:format("===============================~n"),
+ [io:format(" + ~s-~s-~s~n", [U, N, V]) || #package{user = U, name = N, vsn = V} <- NotInstalled],
+ io:format("~n([y]/n) "),
+ case io:get_chars("", 1) of
+ C when C == "y"; C == "\n" ->
+ io:format("~n"),
+ [install_package(GlobalConfig, Package) || Package <- NotInstalled];
+ _ -> ok
+ end
+ end;
execute(GlobalConfig0, ["remove" | Args]) ->
- {GlobalConfig, Packages, Flags} = collect_args(remove, Args, GlobalConfig0),
- put(verbose, lists:member(verbose, Flags)),
- Installed = installed_packages(Packages),
- case Installed of
- [] ->
- io:format("+ nothing to remove: no matching packages installed~n");
- _ ->
- io:format("===============================~n"),
- io:format("Remove the following packages?~n"),
- io:format("===============================~n"),
- [io:format(" + ~s-~s-~s~n", [U,N,V]) || #package{user=U, name=N, vsn=V} <- Installed],
- io:format("~n([y]/n) "),
- case io:get_chars("", 1) of
- C when C == "y"; C == "\n" ->
- io:format("~n"),
- [remove_package(GlobalConfig, Package) || Package <- Installed];
- _ -> ok
- end
- end;
+ {GlobalConfig, Packages, Flags} = collect_args(remove, Args, GlobalConfig0),
+ put(verbose, lists:member(verbose, Flags)),
+ Installed = installed_packages(Packages),
+ case Installed of
+ [] ->
+ io:format("+ nothing to remove: no matching packages installed~n");
+ _ ->
+ io:format("===============================~n"),
+ io:format("Remove the following packages?~n"),
+ io:format("===============================~n"),
+ [io:format(" + ~s-~s-~s~n", [U, N, V]) || #package{user = U, name = N, vsn = V} <- Installed],
+ io:format("~n([y]/n) "),
+ case io:get_chars("", 1) of
+ C when C == "y"; C == "\n" ->
+ io:format("~n"),
+ [remove_package(GlobalConfig, Package) || Package <- Installed];
+ _ -> ok
+ end
+ end;
execute(GlobalConfig0, ["update" | Args]) ->
- {GlobalConfig, Packages, Flags} = collect_args(update, Args, GlobalConfig0),
- put(verbose, lists:member(verbose, Flags)),
- Installed = installed_packages(Packages),
- case Installed of
- [] ->
- io:format("- nothing to update~n");
- _ ->
- io:format("===============================~n"),
- io:format("Update the following packages?~n"),
- io:format("===============================~n"),
- [io:format(" + ~s-~s-~s~n", [U,N,V]) || #package{user=U, name=N, vsn=V} <- Installed],
- io:format("~n([y]/n) "),
- case io:get_chars("", 1) of
- C when C == "y"; C == "\n" ->
- io:format("~n"),
- [update_package(GlobalConfig, Package) || Package <- Installed];
- _ -> ok
- end
- end;
-
+ {GlobalConfig, Packages, Flags} = collect_args(update, Args, GlobalConfig0),
+ put(verbose, lists:member(verbose, Flags)),
+ Installed = installed_packages(Packages),
+ case Installed of
+ [] ->
+ io:format("- nothing to update~n");
+ _ ->
+ io:format("===============================~n"),
+ io:format("Update the following packages?~n"),
+ io:format("===============================~n"),
+ [io:format(" + ~s-~s-~s~n", [U, N, V]) || #package{user = U, name = N, vsn = V} <- Installed],
+ io:format("~n([y]/n) "),
+ case io:get_chars("", 1) of
+ C when C == "y"; C == "\n" ->
+ io:format("~n"),
+ [update_package(GlobalConfig, Package) || Package <- Installed];
+ _ -> ok
+ end
+ end;
+
execute(GlobalConfig0, ["info" | Args]) ->
- {GlobalConfig, Packages, _Flags} = collect_args(info, Args, GlobalConfig0),
- {Installed, NotInstalled} = filter_installed_packages(Packages),
- case Installed of
- [] -> ok;
- _ ->
- io:format("===============================~n"),
- io:format("INSTALLED~n"),
- io:format("===============================~n"),
-
- lists:foldl(
- fun(Package, Count) ->
- case Count of
- 0 -> ok;
- _ -> io:format("~n")
- end,
- write_installed_package_info(Package),
- Count+1
- end, 0, lists:reverse(Installed))
- end,
-
- case NotInstalled of
- [] -> ok;
- _ ->
- case Installed of
- [] -> ok;
- _ -> io:format("~n")
- end,
- write_not_installed_package_info(GlobalConfig, NotInstalled, true)
- end;
-
+ {GlobalConfig, Packages, _Flags} = collect_args(info, Args, GlobalConfig0),
+ {Installed, NotInstalled} = filter_installed_packages(Packages),
+ case Installed of
+ [] -> ok;
+ _ ->
+ io:format("===============================~n"),
+ io:format("INSTALLED~n"),
+ io:format("===============================~n"),
+
+ lists:foldl(
+ fun(Package, Count) ->
+ case Count of
+ 0 -> ok;
+ _ -> io:format("~n")
+ end,
+ write_installed_package_info(Package),
+ Count + 1
+ end , 0, lists:reverse(Installed))
+ end,
+
+ case NotInstalled of
+ [] -> ok;
+ _ ->
+ case Installed of
+ [] -> ok;
+ _ -> io:format("~n")
+ end,
+ write_not_installed_package_info(GlobalConfig, NotInstalled, true)
+ end;
+
execute(GlobalConfig0, ["search" | Args]) ->
{GlobalConfig, Packages, _Flags} = collect_args(search, Args, GlobalConfig0),
write_not_installed_package_info(GlobalConfig, lists:reverse(Packages));
-
+
execute(_GlobalConfig, ["list" | _Args]) ->
- Installed = installed_packages(),
- case Installed of
- [] ->
- io:format("- no packages installed~n");
- _ ->
- io:format("===============================~n"),
- io:format("INSTALLED~n"),
- io:format("===============================~n"),
-
- lists:foldl(
- fun(Package, Count) ->
- case Count of
- 0 -> ok;
- _ -> io:format("~n")
- end,
- write_installed_package_info(Package),
- Count+1
- end, 0, lists:reverse(Installed))
- end;
+ Installed = installed_packages(),
+ case Installed of
+ [] ->
+ io:format("- no packages installed~n");
+ _ ->
+ io:format("===============================~n"),
+ io:format("INSTALLED~n"),
+ io:format("===============================~n"),
+
+ lists:foldl(
+ fun(Package, Count) ->
+ case Count of
+ 0 -> ok;
+ _ -> io:format("~n")
+ end,
+ write_installed_package_info(Package),
+ Count + 1
+ end , 0, lists:reverse(Installed))
+ end;
execute(_GlobalConfig, ["latest" | _Args]) ->
update_epm();
-
+
execute(GlobalConfig0, ["config" | Args]) ->
- {GlobalConfig, _Packages, Flags} = collect_args(config, Args, GlobalConfig0),
- case Flags of
- [] ->
- print_config_values(GlobalConfig);
- [get] ->
- print_config_values(GlobalConfig);
- _ ->
- Config2 = lists:foldl(
- fun(Flag, Config) ->
- case Flag of
- {set, [K,V]} ->
- K1 = list_to_atom(K),
- [{K1, V}|proplists:delete(K1, Config)];
- {remove, K} ->
- K1 = list_to_atom(K),
- proplists:delete(K1, Config);
- _ ->
- Config
- end
- end, GlobalConfig, Flags),
- write_config_file(Config2)
- end;
-
+ {GlobalConfig, _Packages, Flags} = collect_args(config, Args, GlobalConfig0),
+ case Flags of
+ [] ->
+ print_config_values(GlobalConfig);
+ [get] ->
+ print_config_values(GlobalConfig);
+ _ ->
+ Config2 = lists:foldl(
+ fun(Flag, Config) ->
+ case Flag of
+ {set, [K, V]} ->
+ K1 = list_to_atom(K),
+ [{K1, V}|proplists:delete(K1, Config)];
+ {remove, K} ->
+ K1 = list_to_atom(K),
+ proplists:delete(K1, Config);
+ _ ->
+ Config
+ end
+ end , GlobalConfig, Flags),
+ write_config_file(Config2)
+ end;
+
execute(_, _) ->
- io:format("Usage: epm commands~n~n"),
- io:format(" install [<user>/]<project> {project options}, ... {global options}~n"),
- io:format(" project options:~n"),
- io:format(" --tag <tag>~n"),
- io:format(" --branch <branch>~n"),
- io:format(" --sha <sha>~n"),
- io:format(" --with-deps (default)~n"),
- io:format(" --without-deps~n"),
- io:format(" --prebuild-command <cmd>~n"),
- io:format(" --build-command <cmd>~n"),
- io:format(" --test-command <cmd>~n"),
- io:format(" global options:~n"),
- io:format(" --verbose~n"),
- io:format(" --config-set <key> <value>~n~n"),
- io:format(" remove [<user>/]<project> {project options}, ... {global options}~n"),
- io:format(" project options:~n"),
- io:format(" --tag <tag>~n"),
- io:format(" --branch <branch>~n"),
- io:format(" --sha <sha>~n"),
- io:format(" global options:~n"),
- io:format(" --verbose~n~n"),
- io:format(" --config-set <key> <value>~n~n"),
- io:format(" update [<user>/]<project> {project options}, ... {global options}~n"),
- io:format(" project options:~n"),
- io:format(" --tag <tag>~n"),
- io:format(" --branch <branch>~n"),
- io:format(" --sha <sha>~n"),
- io:format(" --with-deps~n"),
- io:format(" --without-deps (default)~n"),
- io:format(" global options:~n"),
- io:format(" --verbose~n~n"),
- io:format(" --config-set <key> <value>~n~n"),
- io:format(" info [<user>/]<project>, ... {global options}~n"),
- io:format(" global options:~n"),
- io:format(" --config-set <key> <value>~n~n"),
- io:format(" search <project>, ... {global options}~n"),
- io:format(" global options:~n"),
- io:format(" --config-set <key> <value>~n~n"),
- io:format(" list~n~n"),
- io:format(" latest~n~n"),
- io:format(" config {options}~n"),
- io:format(" options:~n"),
- io:format(" --get (default)~n"),
- io:format(" --set <key> <value>~n"),
- io:format(" --remove <key>~n"),
- ok.
+ io:format("Usage: epm commands~n~n"),
+ io:format(" install [<user>/]<project> {project options}, ... {global options}~n"),
+ io:format(" project options:~n"),
+ io:format(" --tag <tag>~n"),
+ io:format(" --branch <branch>~n"),
+ io:format(" --sha <sha>~n"),
+ io:format(" --with-deps (default)~n"),
+ io:format(" --without-deps~n"),
+ io:format(" --prebuild-command <cmd>~n"),
+ io:format(" --build-command <cmd>~n"),
+ io:format(" --test-command <cmd>~n"),
+ io:format(" global options:~n"),
+ io:format(" --verbose~n"),
+ io:format(" --config-set <key> <value>~n~n"),
+ io:format(" remove [<user>/]<project> {project options}, ... {global options}~n"),
+ io:format(" project options:~n"),
+ io:format(" --tag <tag>~n"),
+ io:format(" --branch <branch>~n"),
+ io:format(" --sha <sha>~n"),
+ io:format(" global options:~n"),
+ io:format(" --verbose~n~n"),
+ io:format(" --config-set <key> <value>~n~n"),
+ io:format(" update [<user>/]<project> {project options}, ... {global options}~n"),
+ io:format(" project options:~n"),
+ io:format(" --tag <tag>~n"),
+ io:format(" --branch <branch>~n"),
+ io:format(" --sha <sha>~n"),
+ io:format(" --with-deps~n"),
+ io:format(" --without-deps (default)~n"),
+ io:format(" global options:~n"),
+ io:format(" --verbose~n~n"),
+ io:format(" --config-set <key> <value>~n~n"),
+ io:format(" info [<user>/]<project>, ... {global options}~n"),
+ io:format(" global options:~n"),
+ io:format(" --config-set <key> <value>~n~n"),
+ io:format(" search <project>, ... {global options}~n"),
+ io:format(" global options:~n"),
+ io:format(" --config-set <key> <value>~n~n"),
+ io:format(" list~n~n"),
+ io:format(" latest~n~n"),
+ io:format(" config {options}~n"),
+ io:format(" options:~n"),
+ io:format(" --get (default)~n"),
+ io:format(" --set <key> <value>~n"),
+ io:format(" --remove <key>~n"),
+ ok.
%% -----------------------------------------------------------------------------
%% parse input args
@@ -220,59 +220,59 @@ execute(_, _) ->
%%` GlobalConfig = list()
%% Results = {[package(), Flags]}
%% Flags = [atom()]
-collect_args(Target, Args, GlobalConfig) ->
- collect_args(Target, Args, GlobalConfig, [], []).
-collect_args(_, [], GlobalConfig, Packages, Flags) ->
- {GlobalConfig, lists:reverse(Packages), lists:reverse(Flags)};
+collect_args(Target, Args, GlobalConfig) ->
+ collect_args(Target, Args, GlobalConfig, [], []).
+collect_args(_, [], GlobalConfig, Packages, Flags) ->
+ {GlobalConfig, lists:reverse(Packages), lists:reverse(Flags)};
collect_args(Target, [Arg | Rest], GlobalConfig, Packages, Flags) ->
- case parse_tag(Target, Arg) of
- undefined -> %% if not a tag then must be a project name
- {ProjectName, User} = split_package(Arg), %% split into user and project
- collect_args(Target, Rest, GlobalConfig, [#package{user=User, name=ProjectName}|Packages], Flags);
- {Type, Tag, 0} -> %% tag with no trailing value
- case Type of
- project ->
- [#package{args=Args}=Package|OtherPackages] = Packages,
- collect_args(Target, Rest, GlobalConfig, [Package#package{args=Args ++ [Tag]}|OtherPackages], Flags);
- global ->
- collect_args(Target, Rest, GlobalConfig, Packages, [Tag|Flags])
- end;
- {Type, Tag, NumVals} when is_integer(NumVals) -> %% tag with trailing value(s)
- if
- length(Rest) < NumVals ->
- exit("poorly formatted command");
- true -> ok
- end,
- {Vals, Rest1} = lists:split(NumVals, Rest),
- Vals1 =
- case Vals of
- [V] -> V;
- _ -> Vals
- end,
- case Type of
- project ->
- [#package{args=Args}=Package|OtherPackages] = Packages, %% this tag applies to the last project on the stack
- Vsn = if
- Tag==tag; Tag==branch; Tag==sha -> Vals1;
- true -> Package#package.vsn
- end,
- collect_args(Target, Rest1, GlobalConfig, [Package#package{vsn=Vsn, args=Args ++ [{Tag, Vals1}]}|OtherPackages], Flags);
- global ->
- GlobalConfig1 =
- if
- Tag == config_set ->
- [K,V1] = Vals1,
- K1 = list_to_atom(K),
- [case K1 of
- repo_plugins -> {K1, epm_util:eval(V1++".")};
- _ -> {K1, V1}
- end |proplists:delete(K1, GlobalConfig)];
- true ->
- GlobalConfig
- end,
- collect_args(Target, Rest1, GlobalConfig1, Packages, [{Tag, Vals1}|Flags])
- end
- end.
+ case parse_tag(Target, Arg) of
+ undefined -> %% if not a tag then must be a project name
+ {ProjectName, User} = split_package(Arg), %% split into user and project
+ collect_args(Target, Rest, GlobalConfig, [#package{user = User, name = ProjectName}|Packages], Flags);
+ {Type, Tag, 0} -> %% tag with no trailing value
+ case Type of
+ project ->
+ [#package{args = Args} = Package|OtherPackages] = Packages,
+ collect_args(Target, Rest, GlobalConfig, [Package#package{args = Args ++ [Tag]}|OtherPackages], Flags);
+ global ->
+ collect_args(Target, Rest, GlobalConfig, Packages, [Tag|Flags])
+ end;
+ {Type, Tag, NumVals} when is_integer(NumVals) -> %% tag with trailing value(s)
+ if
+ length(Rest) < NumVals ->
+ exit("poorly formatted command");
+ true -> ok
+ end,
+ {Vals, Rest1} = lists:split(NumVals, Rest),
+ Vals1 =
+ case Vals of
+ [V] -> V;
+ _ -> Vals
+ end,
+ case Type of
+ project ->
+ [#package{args = Args} = Package|OtherPackages] = Packages, %% this tag applies to the last project on the stack
+ Vsn = if
+ Tag == tag; Tag == branch; Tag == sha -> Vals1;
+ true -> Package#package.vsn
+ end,
+ collect_args(Target, Rest1, GlobalConfig, [Package#package{vsn = Vsn, args = Args ++ [{Tag, Vals1}]}|OtherPackages], Flags);
+ global ->
+ GlobalConfig1 =
+ if
+ Tag == config_set ->
+ [K, V1] = Vals1,
+ K1 = list_to_atom(K),
+ [case K1 of
+ repo_plugins -> {K1, epm_util:eval(V1 ++ ".")};
+ _ -> {K1, V1}
+ end |proplists:delete(K1, GlobalConfig)];
+ true ->
+ GlobalConfig
+ end,
+ collect_args(Target, Rest1, GlobalConfig1, Packages, [{Tag, Vals1}|Flags])
+ end
+ end.
%% @spec parse_tag(Target, Arg) -> {Tag, HasValue} | undefined
%% Target = atom()
@@ -308,74 +308,76 @@ split_package([A | Tail], User) -> split_package(Tail, User ++ [A]).
%% -----------------------------------------------------------------------------
%% package info
-%% -----------------------------------------------------------------------------
-local_package_info(#package{user=none, name=ProjectName, vsn=undefined}) ->
- case dets:match(epm_index, {{'_',ProjectName,'_'},'$1'}) of
- [] -> [];
- List -> [Package || [Package] <- List]
- end;
-local_package_info(#package{user=none, name=ProjectName, vsn=Vsn}) ->
- case dets:match(epm_index, {{'_',ProjectName,Vsn},'$1'}) of
- [] -> [];
- List -> [Package || [Package] <- List]
- end;
-local_package_info(#package{user=User, name=ProjectName, vsn=undefined}) ->
- case dets:match(epm_index, {{User,ProjectName,'_'},'$1'}) of
- [] -> [];
- List -> [Package || [Package] <- List]
- end;
-local_package_info(#package{user=User, name=ProjectName, vsn=Vsn}) ->
- case dets:match(epm_index, {{User,ProjectName,Vsn},'$1'}) of
- [] -> [];
- List -> [Package || [Package] <- List]
- end.
-
+%% -----------------------------------------------------------------------------
+local_package_info(#package{user = none, name = ProjectName, vsn = undefined}) ->
+ case dets:match(epm_index, {{'_', ProjectName, '_'}, '$1'}) of
+ [] -> [];
+ List -> [Package || [Package] <- List]
+ end;
+local_package_info(#package{user = none, name = ProjectName, vsn = Vsn}) ->
+ case dets:match(epm_index, {{'_', ProjectName, Vsn}, '$1'}) of
+ [] -> [];
+ List -> [Package || [Package] <- List]
+ end;
+local_package_info(#package{user = User, name = ProjectName, vsn = undefined}) ->
+ case dets:match(epm_index, {{User, ProjectName, '_'}, '$1'}) of
+ [] -> [];
+ List -> [Package || [Package] <- List]
+ end;
+local_package_info(#package{user = User, name = ProjectName, vsn = Vsn}) ->
+ case dets:match(epm_index, {{User, ProjectName, Vsn}, '$1'}) of
+ [] -> [];
+ List -> [Package || [Package] <- List]
+ end.
+
installed_packages() ->
[Package || [{_,Package}] <- dets:match(epm_index, '$1')].
installed_packages(Packages) ->
[V || {_K,V} <- dict:to_list(installed_packages1(Packages, dict:new()))].
-
+
installed_packages1([], Dict) ->
Dict;
-
+
installed_packages1([Package|Tail], Dict) ->
- Dict1 =
- case local_package_info(Package) of
- [] ->
- Dict;
- List ->
- lists:foldl(
- fun(InstalledPackage, TempDict) ->
- TempDict1 = dict:store({
- InstalledPackage#package.user,
- InstalledPackage#package.name,
- InstalledPackage#package.vsn }, InstalledPackage, TempDict),
- DependantPackages = dependant_installed_packages(InstalledPackage),
- installed_packages1(DependantPackages, TempDict1)
- end, Dict, List)
- end,
- installed_packages1(Tail, Dict1).
-
+ Dict1 =
+ case local_package_info(Package) of
+ [] ->
+ Dict;
+ List ->
+ lists:foldl(
+ fun(InstalledPackage, TempDict) ->
+ TempDict1 = dict:store( {
+ InstalledPackage#package.user,
+ InstalledPackage#package.name,
+ InstalledPackage#package.vsn }, InstalledPackage, TempDict),
+ DependantPackages = dependant_installed_packages(InstalledPackage),
+ installed_packages1(DependantPackages, TempDict1)
+ end , Dict, List)
+ end,
+ installed_packages1(Tail, Dict1).
+
dependant_installed_packages(Package) ->
dependant_installed_packages(Package, [], dets:match(epm_index, '$1')).
dependant_installed_packages(_Package, Acc, []) -> Acc;
-dependant_installed_packages(#package{user=User,name=Name,vsn=Vsn}=Package, Acc, [[{_,#package{deps=Deps}=InstalledPackage}]|Tail]) ->
- Acc1 = case lists:filter(
- fun({U,N,V}) ->
- (U==User orelse U==none) andalso
- (N==Name) andalso
- (V==Vsn)
- end, Deps) of
- [] -> Acc;
- [_] -> [InstalledPackage|Acc]
- end,
- dependant_installed_packages(Package, Acc1, Tail).
-
+dependant_installed_packages(#package{user = User, name = Name, vsn = Vsn} = Package
+ , Acc
+ , [[{_, #package{deps = Deps} = InstalledPackage}]|Tail]) ->
+ F = fun({U, N, V}) ->
+ (U == User orelse U == none) andalso
+ (N == Name) andalso
+ (V == Vsn)
+ end,
+ Acc1 = case lists:filter(F, Deps) of
+ [] -> Acc;
+ [_] -> [InstalledPackage|Acc]
+ end,
+ dependant_installed_packages(Package, Acc1, Tail).
+
%% -----------------------------------------------------------------------------
%% Print package info
-%% -----------------------------------------------------------------------------
+%% -----------------------------------------------------------------------------
write_installed_package_info(Package) ->
Repo = Package#package.repo,
[io:format(" ~s: ~s~n", [Field, if Value==undefined -> ""; true -> Value end]) || {Field, Value} <- [
@@ -399,202 +401,203 @@ write_installed_package_info(Package) ->
write_not_installed_package_info(GlobalConfig, Packages) ->
write_not_installed_package_info(GlobalConfig, Packages, false).
-
+
write_not_installed_package_info(GlobalConfig, Packages, IsExact) ->
RepoPlugins = proplists:get_value(repo_plugins, GlobalConfig, ?DEFAULT_API_MODULES),
write_not_installed_package_info1(Packages, RepoPlugins, IsExact).
-
+
write_not_installed_package_info1(Packages, RepoPlugins, IsExact) ->
- case fetch_not_installed_package_info(Packages, RepoPlugins, [], IsExact) of
- [] ->
- io:format("- not found~n");
- Repos ->
- io:format("===============================~n"),
- io:format("AVAILABLE~n"),
- io:format("===============================~n"),
- lists:foldl(
- fun(Repo, Count) ->
- Tags = apply(Repo#repository.api_module, tags, [Repo#repository.owner, Repo#repository.name]),
- Branches = apply(Repo#repository.api_module, branches, [Repo#repository.owner, Repo#repository.name]),
- case Count of
- 0 -> ok;
- _ -> io:format("~n")
- end,
- [io:format(" ~s: ~s~n", [Field, if Value==undefined -> ""; true -> Value end]) || {Field, Value} <- [
- {"name", Repo#repository.name},
- {"owner", Repo#repository.owner},
- {"followers", Repo#repository.followers},
- {"pushed", Repo#repository.pushed},
- {"homepage", Repo#repository.homepage},
- {"description", Repo#repository.description},
- {"repo plugin", atom_to_list(Repo#repository.api_module)}
- ]],
- if
- Tags =/= [] ->
- io:format(" tags:~n"),
- [io:format(" ~s~n", [Tag]) || Tag <- Tags];
- true -> ok
- end,
- if
- Branches =/= [] ->
- io:format(" branches:~n"),
- [io:format(" ~s~n", [Branch]) || Branch <- Branches];
- true -> ok
- end,
- Count+1
- end, 0, Repos)
- end.
+ case fetch_not_installed_package_info(Packages, RepoPlugins, [], IsExact) of
+ [] ->
+ io:format("- not found~n");
+ Repos ->
+ io:format("===============================~n"),
+ io:format("AVAILABLE~n"),
+ io:format("===============================~n"),
+ lists:foldl(
+ fun(Repo, Count) ->
+ Tags = apply(Repo#repository.api_module, tags, [Repo#repository.owner, Repo#repository.name]),
+ Branches = apply(Repo#repository.api_module, branches, [Repo#repository.owner, Repo#repository.name]),
+ case Count of
+ 0 -> ok;
+ _ -> io:format("~n")
+ end,
+ [io:format(" ~s: ~s~n", [Field, if Value == undefined -> ""; true ->
+ Value end ]) || {Field, Value} <- [
+ {"name", Repo#repository.name} ,
+ {"owner", Repo#repository.owner} ,
+ {"followers", Repo#repository.followers} ,
+ {"pushed", Repo#repository.pushed} ,
+ {"homepage", Repo#repository.homepage} ,
+ {"description", Repo#repository.description} ,
+ {"repo plugin", atom_to_list(Repo#repository.api_module)}
+ ]],
+ if
+ Tags =/= [] ->
+ io:format(" tags:~n"),
+ [io:format(" ~s~n", [Tag]) || Tag <- Tags];
+ true -> ok
+ end,
+ if
+ Branches =/= [] ->
+ io:format(" branches:~n"),
+ [io:format(" ~s~n", [Branch]) || Branch <- Branches];
+ true -> ok
+ end,
+ Count + 1
+ end , 0, Repos)
+ end.
fetch_not_installed_package_info([], _, Acc, _) -> Acc;
fetch_not_installed_package_info([#package{user=User,name=ProjectName}|Tail], RepoPlugins, Acc, IsExact) ->
Repos = retrieve_remote_repos(RepoPlugins, User, ProjectName, IsExact),
fetch_not_installed_package_info(Tail, RepoPlugins, lists:append(Acc, Repos), IsExact).
-
+
%% -----------------------------------------------------------------------------
%% INSTALL
%% -----------------------------------------------------------------------------
install_package(GlobalConfig, Package) ->
- Repo = Package#package.repo,
- User = Repo#repository.owner,
- Name = Repo#repository.name,
- Vsn = Package#package.vsn,
- %% switch to build home dir
- epm_util:set_cwd_build_home(GlobalConfig),
-
- %% download correct version of package
- LocalProjectDir = apply(Repo#repository.api_module, download_package, [Repo, Vsn]),
-
- %% switch to project dir
- epm_util:set_cwd_build_home(GlobalConfig),
- epm_util:set_cwd(LocalProjectDir),
-
- %% build/install project
- InstallDir = build_project(GlobalConfig, Package),
-
- %% switch to build home dir and delete cloned project
- epm_util:set_cwd_build_home(GlobalConfig),
- epm_util:del_dir(LocalProjectDir),
-
- dets:insert(epm_index, {{User, Name, Vsn}, Package#package{install_dir=InstallDir}}),
-
- ok.
+ Repo = Package#package.repo,
+ User = Repo#repository.owner,
+ Name = Repo#repository.name,
+ Vsn = Package#package.vsn,
+ %% switch to build home dir
+ epm_util:set_cwd_build_home(GlobalConfig),
+
+ %% download correct version of package
+ LocalProjectDir = apply(Repo#repository.api_module, download_package, [Repo, Vsn]),
+
+ %% switch to project dir
+ epm_util:set_cwd_build_home(GlobalConfig),
+ epm_util:set_cwd(LocalProjectDir),
+
+ %% build/install project
+ InstallDir = build_project(GlobalConfig, Package),
+
+ %% switch to build home dir and delete cloned project
+ epm_util:set_cwd_build_home(GlobalConfig),
+ epm_util:del_dir(LocalProjectDir),
+
+ dets:insert(epm_index, {{User, Name, Vsn}, Package#package{install_dir = InstallDir}}),
+
+ ok.
%% -----------------------------------------------------------------------------
%% REMOVE
%% -----------------------------------------------------------------------------
-remove_package(_GlobalConfig, #package{user=User, name=Name, vsn=Vsn, install_dir=InstallDir}) ->
- io:format("+ removing package ~s-~s-~s from ~s~n", [User, Name, Vsn, InstallDir]),
- RemoveCmd = "rm -rf " ++ InstallDir,
- epm_util:print_cmd_output("~s~n", [RemoveCmd]),
- epm_util:do_cmd(RemoveCmd, fail),
- dets:delete(epm_index, {User,Name,Vsn}).
+remove_package(_GlobalConfig, #package{user = User, name = Name, vsn = Vsn, install_dir = InstallDir}) ->
+ io:format("+ removing package ~s-~s-~s from ~s~n", [User, Name, Vsn, InstallDir]),
+ RemoveCmd = "rm -rf " ++ InstallDir,
+ epm_util:print_cmd_output("~s~n", [RemoveCmd]),
+ epm_util:do_cmd(RemoveCmd, fail),
+ dets:delete(epm_index, {User, Name, Vsn}).
%% -----------------------------------------------------------------------------
%% UPDATE
%% -----------------------------------------------------------------------------
update_package(GlobalConfig, Package) ->
- Repo = Package#package.repo,
- Vsn = Package#package.vsn,
- %% switch to build home dir
- epm_util:set_cwd_build_home(GlobalConfig),
-
- %% download correct version of package
- LocalProjectDir = apply(Repo#repository.api_module, download_package, [Repo, Vsn]),
-
- %% switch to project dir
- epm_util:set_cwd_build_home(GlobalConfig),
- epm_util:set_cwd(LocalProjectDir),
-
- %% build/install project
- _InstallDir = build_project(GlobalConfig, Package),
-
- %% switch to build home dir and delete cloned project
- epm_util:set_cwd_build_home(GlobalConfig),
- epm_util:del_dir(LocalProjectDir).
+ Repo = Package#package.repo,
+ Vsn = Package#package.vsn,
+ %% switch to build home dir
+ epm_util:set_cwd_build_home(GlobalConfig),
+
+ %% download correct version of package
+ LocalProjectDir = apply(Repo#repository.api_module, download_package, [Repo, Vsn]),
+
+ %% switch to project dir
+ epm_util:set_cwd_build_home(GlobalConfig),
+ epm_util:set_cwd(LocalProjectDir),
+
+ %% build/install project
+ _InstallDir = build_project(GlobalConfig, Package),
+
+ %% switch to build home dir and delete cloned project
+ epm_util:set_cwd_build_home(GlobalConfig),
+ epm_util:del_dir(LocalProjectDir).
%% -----------------------------------------------------------------------------
%% Replace epm script with most recent
%% -----------------------------------------------------------------------------
update_epm() ->
- File =
- case os:find_executable("epm") of
- false ->
- case filelib:is_regular("epm") of
- true -> "./epm";
- fasle -> exit("failed to find epm executable to replace")
- end;
- F -> F
- end,
- Fork = proplists:get_value(epm_fork, application:get_all_env(epm), "JacobVorreuter"),
- Url = "http://github.com/" ++ Fork ++ "/epm/raw/master/epm",
- case epm_util:http_request(Url, [{"Host", "github.com"}], [{body_format, binary}]) of
- {ok, {{_, 200, _}, _, Body}} ->
- case file:write_file(File, Body) of
- ok ->
- io:format("+ updated epm (~s) to latest version~n", [File]);
- {error, Reason} ->
- exit(lists:flatten(io_lib:format("failed to overwrite epm executable ~s: ~p~n", [File, Reason])))
- end;
- _ ->
- exit("failed to download latest version of epm")
- end.
+ File =
+ case os:find_executable("epm") of
+ false ->
+ case filelib:is_regular("epm") of
+ true -> "./epm";
+ fasle -> exit("failed to find epm executable to replace")
+ end;
+ F -> F
+ end,
+ Fork = proplists:get_value(epm_fork, application:get_all_env(epm), "JacobVorreuter"),
+ Url = "http://github.com/" ++ Fork ++ "/epm/raw/master/epm",
+ case epm_util:http_request(Url, [{"Host", "github.com"}], [{body_format, binary}]) of
+ {ok, {{_, 200, _}, _, Body}} ->
+ case file:write_file(File, Body) of
+ ok ->
+ io:format("+ updated epm (~s) to latest version~n", [File]);
+ {error, Reason} ->
+ exit(lists:flatten(io_lib:format("failed to overwrite epm executable ~s: ~p~n", [File, Reason])))
+ end;
+ _ ->
+ exit("failed to download latest version of epm")
+ end.
%% -----------------------------------------------------------------------------
%% Global Config
-%% -----------------------------------------------------------------------------
+%% -----------------------------------------------------------------------------
print_config_values(GlobalConfig) ->
[io:format("~p\t\t~p~n", [K,V]) || {K,V} <- GlobalConfig].
-
+
write_config_file(GlobalConfig) ->
- FileLoc = get(global_config),
- case file:open(FileLoc, [write]) of
- {ok, IoDevice} ->
- io:format(IoDevice, "[~n", []),
- lists:foldl(
- fun({Key, Val}, Count) ->
- if
- Count == 0 -> ok;
- true ->
- io:format(IoDevice, ",~n", [])
- end,
- case {Key,Val} of
- {repo_plugins, [C|_]} when is_integer(C) ->
- io:format(IoDevice, " {~p, ~s}", [Key, Val]);
- _ ->
- io:format(IoDevice, " {~p, ~p}", [Key, Val])
- end,
- Count+1
- end, 0, GlobalConfig),
- io:format(IoDevice, "~n].~n", []),
- io:format("+ updated .epm config~n");
- {error, Reason} ->
- ?EXIT("failed to update .epm config (~s): ~p", [FileLoc, Reason])
- end.
+ FileLoc = get(global_config),
+ case file:open(FileLoc, [write]) of
+ {ok, IoDevice} ->
+ io:format(IoDevice, "[~n", []),
+ lists:foldl(
+ fun({Key, Val}, Count) ->
+ if
+ Count == 0 -> ok;
+ true ->
+ io:format(IoDevice, ",~n", [])
+ end,
+ case {Key, Val} of
+ {repo_plugins, [C|_]} when is_integer(C) ->
+ io:format(IoDevice, " {~p, ~s}", [Key, Val]);
+ _ ->
+ io:format(IoDevice, " {~p, ~p}", [Key, Val])
+ end,
+ Count + 1
+ end , 0, GlobalConfig),
+ io:format(IoDevice, "~n].~n", []),
+ io:format("+ updated .epm config~n");
+ {error, Reason} ->
+ ?EXIT("failed to update .epm config (~s): ~p", [FileLoc, Reason])
+ end.
%% -----------------------------------------------------------------------------
%% Read vsn
-%% -----------------------------------------------------------------------------
+%% -----------------------------------------------------------------------------
read_vsn_from_args([{tag, Tag}|_], _) -> Tag;
read_vsn_from_args([{branch, Branch}|_], _) -> Branch;
read_vsn_from_args([{sha, Sha}|_], _) -> Sha;
read_vsn_from_args([_|Tail], Default) -> read_vsn_from_args(Tail, Default);
read_vsn_from_args([], Default) -> Default.
-
+
build_project(GlobalConfig, Package) ->
- ProjectName = (Package#package.repo)#repository.name,
- Props = Package#package.args,
- Config =
- case file:consult(ProjectName ++ ".epm") of
- {ok, [Config0]} -> Config0;
- _ -> []
- end,
- UserSuppliedPrebuildCommand = proplists:get_value(prebuild_command, Props),
- UserSuppliedBuildCommand = proplists:get_value(build_command, Props),
- UserSuppliedTestCommand = proplists:get_value(test_command, Props),
- prebuild(ProjectName, Config, UserSuppliedPrebuildCommand),
- build(ProjectName, Config, UserSuppliedBuildCommand),
- test(ProjectName, Config, UserSuppliedTestCommand),
- install(ProjectName, Config, proplists:get_value(install_dir, GlobalConfig)).
+ ProjectName = (Package#package.repo)#repository.name,
+ Props = Package#package.args,
+ Config =
+ case file:consult(ProjectName ++ ".epm") of
+ {ok, [Config0]} -> Config0;
+ _ -> []
+ end,
+ UserSuppliedPrebuildCommand = proplists:get_value(prebuild_command, Props),
+ UserSuppliedBuildCommand = proplists:get_value(build_command, Props),
+ UserSuppliedTestCommand = proplists:get_value(test_command, Props),
+ prebuild(ProjectName, Config, UserSuppliedPrebuildCommand),
+ build(ProjectName, Config, UserSuppliedBuildCommand),
+ test(ProjectName, Config, UserSuppliedTestCommand),
+ install(ProjectName, Config, proplists:get_value(install_dir, GlobalConfig)).
prebuild(ProjectName, Config, undefined) ->
case proplists:get_value(prebuild_command, Config) of
@@ -603,32 +606,32 @@ prebuild(ProjectName, Config, undefined) ->
end;
prebuild(ProjectName, _Config, PrebuildCmd) ->
prebuild1(ProjectName, PrebuildCmd).
-
+
prebuild1(ProjectName, PrebuildCmd) ->
io:format("+ running ~s prebuild command~n", [ProjectName]),
epm_util:print_cmd_output("~s~n", [PrebuildCmd]),
epm_util:do_cmd(PrebuildCmd, fail).
-
+
build(ProjectName, Config, undefined) ->
- case proplists:get_value(build_command, Config) of
- undefined ->
- case filelib:is_regular("Makefile") of
- true ->
- build1(ProjectName, "make");
- false ->
- case os:find_executable("rebar") of
- false ->
- exit("failed to build package: No Makefile and rebar not installed");
- RebarExec ->
- io:format("+ compiling with rebar...~n"),
- build1(ProjectName, RebarExec ++ " compile")
- end
- end;
- Cmd ->
- build1(ProjectName, Cmd)
- end;
+ case proplists:get_value(build_command, Config) of
+ undefined ->
+ case filelib:is_regular("Makefile") of
+ true ->
+ build1(ProjectName, "make");
+ false ->
+ case os:find_executable("rebar") of
+ false ->
+ exit("failed to build package: No Makefile and rebar not installed");
+ RebarExec ->
+ io:format("+ compiling with rebar...~n"),
+ build1(ProjectName, RebarExec ++ " compile")
+ end
+ end;
+ Cmd ->
+ build1(ProjectName, Cmd)
+ end;
build(ProjectName, _Config, BuildCmd) ->
- build1(ProjectName, BuildCmd).
+ build1(ProjectName, BuildCmd).
build1(ProjectName, BuildCmd) ->
io:format("+ running ~s build command~n", [ProjectName]),
@@ -642,41 +645,41 @@ test(ProjectName, Config, undefined) ->
end;
test(ProjectName, _Config, TestCmd) ->
test1(ProjectName, TestCmd).
-
+
test1(ProjectName, TestCmd) ->
io:format("+ running ~s test command~n", [ProjectName]),
epm_util:print_cmd_output("~s~n", [TestCmd]),
epm_util:do_cmd(TestCmd, fail).
-
+
install(ProjectName, Config, undefined) ->
install(ProjectName, Config, code:lib_dir());
install(ProjectName, _Config, LibDir) ->
- Vsn =
- case file:consult("ebin/" ++ ProjectName ++ ".app") of
- {ok,[{application,_,Props}]} ->
- proplists:get_value(vsn, Props);
- _ ->
- undefined
- end,
- Dir =
- case Vsn of
- undefined -> LibDir ++ "/" ++ ProjectName;
- _ -> LibDir ++ "/" ++ ProjectName ++ "-" ++ Vsn
- end,
- InstallCmd = "mkdir -p " ++ Dir ++ "; cp -R ./* " ++ Dir,
- io:format("+ running ~s install command~n", [ProjectName]),
- epm_util:print_cmd_output("~s~n", [InstallCmd]),
- epm_util:do_cmd(InstallCmd, fail),
- Ebin = Dir ++ "/ebin",
- case code:add_pathz(Ebin) of
- true ->
- ok;
- Err ->
- exit(lists:flatten(io_lib:format("failed to add path for ~s (~s): ~p", [ProjectName, Ebin, Err])))
- end,
- Dir.
-
+ Vsn =
+ case file:consult("ebin/" ++ ProjectName ++ ".app") of
+ {ok, [{application, _, Props}]} ->
+ proplists:get_value(vsn, Props);
+ _ ->
+ undefined
+ end,
+ Dir =
+ case Vsn of
+ undefined -> LibDir ++ "/" ++ ProjectName;
+ _ -> LibDir ++ "/" ++ ProjectName ++ "-" ++ Vsn
+ end,
+ InstallCmd = "mkdir -p " ++ Dir ++ "; cp -R ./* " ++ Dir,
+ io:format("+ running ~s install command~n", [ProjectName]),
+ epm_util:print_cmd_output("~s~n", [InstallCmd]),
+ epm_util:do_cmd(InstallCmd, fail),
+ Ebin = Dir ++ "/ebin",
+ case code:add_pathz(Ebin) of
+ true ->
+ ok;
+ Err ->
+ exit(lists:flatten(io_lib:format("failed to add path for ~s (~s): ~p", [ProjectName, Ebin, Err])))
+ end,
+ Dir.
+
%% -----------------------------------------------------------------------------
%% Compile list of dependencies
%% -----------------------------------------------------------------------------
@@ -687,127 +690,129 @@ package_dependencies(GlobalConfig, Packages) ->
Deps = digraph_utils:topsort(G),
digraph:delete(G),
[dict:fetch(Dep, UpdatedPackages) || Dep <- Deps].
-
+
package_dependencies1([], _, _, _, Dict) -> Dict;
package_dependencies1([Package|Tail], RepoPlugins, G, Parent, Dict) ->
- Repo = retrieve_remote_repo(RepoPlugins, Package#package.user, Package#package.name),
- WithoutDeps = lists:member(without_deps, Package#package.args),
- Key = {Repo#repository.owner, Repo#repository.name, Package#package.vsn},
-
- digraph:add_vertex(G, Key),
-
- case Parent of
- undefined -> ok;
- {_, ParentProjectName, _} ->
- digraph:add_edge(G, Parent, Key),
- case digraph_utils:is_acyclic(G) of
- true ->
- ok;
- false ->
- ?EXIT("circular dependency detected: ~s <--> ~s", [ParentProjectName, Repo#repository.name])
- end
+ Repo = retrieve_remote_repo(RepoPlugins, Package#package.user, Package#package.name),
+ WithoutDeps = lists:member(without_deps, Package#package.args),
+ Key = {Repo#repository.owner, Repo#repository.name, Package#package.vsn},
+
+ digraph:add_vertex(G, Key),
+
+ case Parent of
+ undefined -> ok;
+ {_, ParentProjectName, _} ->
+ digraph:add_edge(G, Parent, Key),
+ case digraph_utils:is_acyclic(G) of
+ true ->
+ ok;
+ false ->
+ ?EXIT("circular dependency detected: ~s <--> ~s", [ParentProjectName, Repo#repository.name])
+ end
+ end,
+
+ PkgVsn =
+ case Package#package.vsn of
+ undefined -> apply(Repo#repository.api_module, default_vsn, []);
+ _ -> Package#package.vsn
end,
-
- PkgVsn =
- case Package#package.vsn of
- undefined -> apply(Repo#repository.api_module, default_vsn, []);
- _ -> Package#package.vsn
- end,
-
- {Deps, Dict1} =
- case WithoutDeps of
- true ->
- {[], Dict};
- false ->
- Deps0 = apply(Repo#repository.api_module, package_deps, [Repo#repository.owner, Repo#repository.name, PkgVsn]),
- lists:mapfoldl(
- fun({Dep, Args}, TempDict) ->
- {DepName, DepUser} = split_package(Dep),
- DepVsn = read_vsn_from_args(Args, apply(Repo#repository.api_module, default_vsn, [])),
- Package0 = #package{
- user = DepUser,
- name = DepName,
- vsn = DepVsn,
- args = Args
- },
- TempDict1 = package_dependencies1([Package0], RepoPlugins, G, Key, TempDict),
- {{DepUser, DepName, DepVsn}, TempDict1}
- end, Dict, Deps0)
- end,
-
- Package1 = Package#package{
- user = Repo#repository.owner,
- name = Repo#repository.name,
- vsn = PkgVsn,
- deps = Deps,
- repo = Repo
- },
- package_dependencies1(Tail, RepoPlugins, G, Parent, dict:store(Key, Package1, Dict1)).
+
+ {Deps, Dict1} =
+ case WithoutDeps of
+ true ->
+ {[], Dict};
+ false ->
+ Deps0 = apply(Repo#repository.api_module, package_deps, [Repo#repository.owner, Repo#repository.name, PkgVsn]),
+ lists:mapfoldl(
+ fun({Dep, Args}, TempDict) ->
+ {DepName, DepUser} = split_package(Dep),
+ DepVsn = read_vsn_from_args(Args, apply(Repo#repository.api_module, default_vsn, [])),
+ Package0 = #package{
+ user = DepUser,
+ name = DepName,
+ vsn = DepVsn ,
+ args = Args
+ },
+ TempDict1 = package_dependencies1([Package0], RepoPlugins, G, Key, TempDict),
+ {{DepUser, DepName, DepVsn}, TempDict1}
+ end , Dict, Deps0)
+ end,
+
+ Package1 = Package#package{ user = Repo#repository.owner
+ , name = Repo#repository.name
+ , vsn = PkgVsn
+ , deps = Deps
+ , repo = Repo
+ },
+ package_dependencies1(Tail, RepoPlugins, G, Parent, dict:store(Key, Package1, Dict1)).
filter_installed_packages(Packages) ->
filter_installed_packages(Packages, [], []).
-
+
filter_installed_packages([], Installed, NotInstalled) ->
{lists:reverse(Installed), NotInstalled};
-
+
filter_installed_packages([Package|Tail], Installed, NotInstalled) ->
- case local_package_info(Package) of
- [] -> filter_installed_packages(Tail, Installed, [Package|NotInstalled]);
- [P|_] -> filter_installed_packages(Tail, [P|Installed], NotInstalled)
- end.
+ case local_package_info(Package) of
+ [] -> filter_installed_packages(Tail, Installed, [Package|NotInstalled]);
+ [P|_] -> filter_installed_packages(Tail, [P|Installed], NotInstalled)
+ end.
retrieve_remote_repo([], _, ProjectName) ->
?EXIT("failed to locate remote repo for ~s", [ProjectName]);
-
-retrieve_remote_repo([Module|Tail], none, ProjectName) ->
- case apply(Module, search, [ProjectName]) of
- [] ->
- retrieve_remote_repo(Tail, none, ProjectName);
- Repos when is_list(Repos) ->
- case lists:filter(fun(R1) -> R1#repository.name==ProjectName end, Repos) of
- [R0|_] -> R0;
- [] -> retrieve_remote_repo(Tail, none, ProjectName)
- end;
- Err ->
- ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
- end;
+
+retrieve_remote_repo([Module|Tail], none, ProjectName) ->
+ case apply(Module, search, [ProjectName]) of
+ [] ->
+ retrieve_remote_repo(Tail, none, ProjectName);
+ Repos when is_list(Repos) ->
+ case lists:filter (fun(R1) ->
+ R1#repository.name == ProjectName end, Repos) of
+ [R0|_] -> R0;
+ [] -> retrieve_remote_repo(Tail, none, ProjectName)
+ end;
+ Err ->
+ ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
+ end;
retrieve_remote_repo([Module|Tail], User, ProjectName) ->
- case apply(Module, info, [User, ProjectName]) of
- Repo when is_record(Repo, repository) ->
- Repo;
- undefined ->
- retrieve_remote_repo(Tail, User, ProjectName);
- Err ->
- ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
- end.
-
+ case apply(Module, info, [User, ProjectName]) of
+ Repo when is_record(Repo, repository) ->
+ Repo;
+ undefined ->
+ retrieve_remote_repo(Tail, User, ProjectName);
+ Err ->
+ ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
+ end.
+
retrieve_remote_repos(Modules, User, ProjectName, IsExact) ->
retrieve_remote_repos(Modules, User, ProjectName, IsExact, []).
-
+
retrieve_remote_repos([], _, _, _, Acc) -> Acc;
-
-retrieve_remote_repos([Module|Tail], none, ProjectName, IsExact, Acc) ->
- case apply(Module, search, [ProjectName]) of
- [] ->
- retrieve_remote_repos(Tail, none, ProjectName, IsExact, Acc);
- Repos when is_list(Repos), IsExact==true ->
- case lists:filter(fun(R1) -> R1#repository.name==ProjectName end, Repos) of
- [] -> retrieve_remote_repos(Tail, none, ProjectName, IsExact, Acc);
- R0s -> retrieve_remote_repos(Tail, none, ProjectName, IsExact, lists:append(Acc, R0s))
- end;
- Repos when is_list(Repos) ->
- retrieve_remote_repos(Tail, none, ProjectName, IsExact, lists:append(Acc, Repos));
- Err ->
- ?EXIT("failed to locate remote repos for ~s: ~p", [ProjectName, Err])
- end;
+
+retrieve_remote_repos([Module|Tail], none, ProjectName, IsExact, Acc) ->
+ case apply(Module, search, [ProjectName]) of
+ [] ->
+ retrieve_remote_repos(Tail, none, ProjectName, IsExact, Acc);
+ Repos when is_list(Repos), IsExact == true ->
+ case lists:filter (fun(R1) ->
+ R1#repository.name == ProjectName end, Repos) of
+ [] -> retrieve_remote_repos(Tail, none, ProjectName, IsExact, Acc);
+ R0s ->
+ retrieve_remote_repos(Tail, none, ProjectName, IsExact, lists:append(Acc, R0s))
+ end;
+ Repos when is_list(Repos) ->
+ retrieve_remote_repos(Tail, none, ProjectName, IsExact, lists:append(Acc, Repos));
+ Err ->
+ ?EXIT("failed to locate remote repos for ~s: ~p", [ProjectName, Err])
+ end;
retrieve_remote_repos([Module|Tail], User, ProjectName, IsExact, Acc) ->
- case apply(Module, info, [User, ProjectName]) of
- Repo when is_record(Repo, repository) ->
- retrieve_remote_repos(Tail, User, ProjectName, IsExact, Acc ++ [Repo]);
- undefined ->
- retrieve_remote_repos(Tail, User, ProjectName, IsExact, Acc);
- Err ->
- ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
- end.
+ case apply(Module, info, [User, ProjectName]) of
+ Repo when is_record(Repo, repository) ->
+ retrieve_remote_repos(Tail, User, ProjectName, IsExact, Acc ++ [Repo]);
+ undefined ->
+ retrieve_remote_repos(Tail, User, ProjectName, IsExact, Acc);
+ Err ->
+ ?EXIT("failed to locate remote repo for ~s: ~p", [ProjectName, Err])
+ end.
View
60 src/epm_package.erl
@@ -4,36 +4,36 @@
-include("epm.hrl").
download_tarball(Repo, Url) ->
- LocalProjectDir = Repo#repository.owner ++ "-" ++ Repo#repository.name,
- io:format("+ downloading ~s~n", [Url]),
- case epm_util:http_request(Url, undefined, [{response_format, binary}]) of
- {ok, "200", _, Bin} ->
- case erl_tar:table({binary, Bin}, [compressed]) of
- {ok,Files} ->
- TarName = tarname(Files),
- epm_util:del_dir(TarName),
- epm_util:del_dir(LocalProjectDir),
- case erl_tar:extract({binary, Bin}, [compressed]) of
- ok ->
- epm_util:rn_dir(TarName, LocalProjectDir),
- LocalProjectDir;
- {error, Reason} ->
- ?EXIT("failed to extract ~s tarball: ~p", [Repo#repository.name, Reason])
- end;
- {error, Reason1} ->
- ?EXIT("failed to extract ~s tarball: ~p", [Repo#repository.name, Reason1])
- end;
- {ok, "404", _, _} ->
- ?EXIT("remote project does not exist: ~s", [Url]);
- Error ->
- io:format("~p~n", [Error]),
- ?EXIT("failed to download ~s tarball: ~s", [Repo#repository.name, Url])
- end.
+ LocalProjectDir = Repo#repository.owner ++ "-" ++ Repo#repository.name,
+ io:format("+ downloading ~s~n", [Url]),
+ case epm_util:http_request(Url, undefined, [{response_format, binary}]) of
+ {ok, "200", _, Bin} ->
+ case erl_tar:table({binary, Bin}, [compressed]) of
+ {ok, Files} ->
+ TarName = tarname(Files),
+ epm_util:del_dir(TarName),
+ epm_util:del_dir(LocalProjectDir),
+ case erl_tar:extract({binary, Bin}, [compressed]) of
+ ok ->
+ epm_util:rn_dir(TarName, LocalProjectDir),
+ LocalProjectDir;
+ {error, Reason} ->
+ ?EXIT("failed to extract ~s tarball: ~p", [Repo#repository.name, Reason])
+ end;
+ {error, Reason1} ->
+ ?EXIT("failed to extract ~s tarball: ~p", [Repo#repository.name, Reason1])
+ end;
+ {ok, "404", _, _} ->
+ ?EXIT("remote project does not exist: ~s", [Url]);
+ Error ->
+ io:format("~p~n", [Error]),
+ ?EXIT("failed to download ~s tarball: ~s", [Repo#repository.name, Url])
+ end.
tarname([]) ->
- exit("package tarball does not contain proper folder structure");
+ exit("package tarball does not contain proper folder structure");
tarname([File|Tail]) ->
- case re:run(File, "/") of
- nomatch -> tarname(Tail);
- _ -> hd(string:tokens(File, "/"))
- end.
+ case re:run(File, "/") of
+ nomatch -> tarname(Tail);
+ _ -> hd(string:tokens(File, "/"))
+ end.
View
281 src/epm_util.erl
@@ -21,51 +21,51 @@ set_net_timeout(Timeout) when is_integer(Timeout) ->
put(net_timeout, Timeout).
request_as_str(Url, Host) ->
- case http_request(Url, Host) of
- {ok, "200", _, Body} ->
- Body;
- {ok, "403", _, _} ->
- not_found;
- {ok, "404", _, _} ->
- not_found;
- {ok, _} ->
- request_failed;
- {error, Reason} ->
- io:format("timeout? ~p~n", [Reason]),
- Reason
- end.
+ case http_request(Url, Host) of
+ {ok, "200", _, Body} ->
+ Body;
+ {ok, "403", _, _} ->
+ not_found;
+ {ok, "404", _, _} ->
+ not_found;
+ {ok, _} ->
+ request_failed;
+ {error, Reason} ->
+ io:format("timeout? ~p~n", [Reason]),
+ Reason
+ end.
http_request(Url, Host) ->
http_request(Url, Host, []).
http_request(Url, Host, ClientOpts) ->
- Hdrs = make_headers(Host),
- Opts = http_options(ClientOpts),
- Timeout = get(net_timeout),
- case ibrowse:send_req(Url, Hdrs, get, [], Opts, Timeout) of
- {ok, "302", Headers, _}=Response ->
- case proplists:get_value("Location", Headers) of
- undefined ->
- Response;
- Location ->
- http_request(Location, undefined, ClientOpts)
- end;
- Other -> Other
- end.
+ Hdrs = make_headers(Host),
+ Opts = http_options(ClientOpts),
+ Timeout = get(net_timeout),
+ case ibrowse:send_req(Url, Hdrs, get, [], Opts, Timeout) of
+ {ok, "302", Headers, _} = Response ->
+ case proplists:get_value("Location", Headers) of
+ undefined ->
+ Response;
+ Location ->
+ http_request(Location, undefined, ClientOpts)
+ end;
+ Other -> Other
+ end.
http_options(ClientOpts) ->
proxy_options() ++ ClientOpts.
proxy_options() ->
- case get(proxy_host) of
- undefined -> [];
- Host ->
- Port = case get(proxy_port) of
- none -> 8080;
- PortNum -> PortNum
- end,
- [{proxy_host, Host}, {proxy_port, Port}]
- end.
+ case get(proxy_host) of
+ undefined -> [];
+ Host ->
+ Port = case get(proxy_port) of
+ none -> 8080;
+ PortNum -> PortNum
+ end,
+ [{proxy_host, Host}, {proxy_port, Port}]
+ end.
make_headers(undefined) ->
[{"User-Agent", "EPM"}];
@@ -76,119 +76,122 @@ default_http_options() ->
[{timeout, get(net_timeout)}].
epm_home_dir(Home) ->
- EPM = filename:join([Home, "epm"]),
- case filelib:is_dir(EPM) of
- true -> EPM;
- false ->
- case file:make_dir(EPM) of
- ok -> EPM;
- {error, Reason} ->
- ?EXIT("failed to create epm home directory (~s): ~p", [EPM, Reason])
- end
- end.
+ EPM = filename:join([Home, "epm"]),
+ case filelib:is_dir(EPM) of
+ true -> EPM;
+ false ->
+ case file:make_dir(EPM) of
+ ok -> EPM;
+ {error, Reason} ->
+ ?EXIT("failed to create epm home directory (~s): ~p", [EPM, Reason])
+ end
+ end.
open_dets_table(Home, EpmHome) ->
- File = filename:join([EpmHome, "epm_index"]),
-
- %% TODO: delete this later
- Insert =
- case filelib:is_regular(filename:join([Home, "epm_index"])) of
- true ->
- case dets:open_file(epm_index, [{type, set}, {file, filename:join([Home, "epm_index"])}]) of
- {ok, _} ->
- Rows = dets:match(epm_index, '$1'),
- dets:close(epm_index),
-
- [{{User,Name,Vsn}, #package{
- user = User,
- name = Name,
- vsn = Vsn,
- install_dir = InstallDir,
- deps = Deps,
- repo = github_api:info(User, Name)
- }} || [{{User,Name,Vsn},InstallDir,Deps}] <- Rows];
- _ -> []
- end;
- false -> []
- end,
-
- case dets:open_file(epm_index, [{type, set}, {file, File}]) of
- {ok, _} ->
- %% TODO: delete this later
- [dets:insert(epm_index, I) || I <- Insert],
- file:delete(filename:join([Home, "epm_index"])),
- ok;
- {error, {file_error,_,eacces}} ->
- ?EXIT("insufficient access to epm index file: ~s", [File]);
- {error, Reason} ->
- ?EXIT("failed to open epm index file (~s): ~p", [File, Reason])
- end.
-
+ File = filename:join([EpmHome, "epm_index"]),
+
+ %% TODO: delete this later
+ Insert =
+ case filelib:is_regular(filename:join([Home, "epm_index"])) of
+ true ->
+ case dets:open_file(epm_index, [{type, set}, {file, filename:join([Home, "epm_index"])}]) of
+ {ok, _} ->
+ Rows = dets:match(epm_index, '$1'),
+ dets:close(epm_index),
+
+ [{{User, Name, Vsn}, #package{
+ user = User ,
+ name = Name ,
+ vsn = Vsn ,
+ install_dir = InstallDir,
+ deps = Deps ,
+ repo = github_api:info(User, Name)
+ }} || [{{User, Name, Vsn}, InstallDir, Deps}] <- Rows];
+ _ -> []
+ end;
+ false -> []
+ end,
+
+ case dets:open_file(epm_index, [{type, set}, {file, File}]) of
+ {ok, _} ->
+ %% TODO: delete this later
+ [dets:insert(epm_index, I) || I <- Insert],
+ file:delete(filename:join([Home, "epm_index"])),
+ ok;
+ {error, {file_error, _, eacces}} ->
+ ?EXIT("insufficient access to epm index file: ~s", [File]);
+ {error, Reason} ->
+ ?EXIT("failed to open epm index file (~s): ~p", [File, Reason])
+ end.
+
+%% TODO: Bleeding eyes
eval(Str) ->
- case erl_scan:string(Str) of
- {ok,Tokens,_} ->
- case erl_parse:parse_exprs(Tokens) of
- {ok,Forms} ->
- case erl_eval:exprs(Forms,[]) of
- {value, Terms, _} -> Terms;
- _ -> error
- end;
- _ -> error
- end;
+ case erl_scan:string(Str) of
+ {ok, Tokens, _} ->
+ case erl_parse:parse_exprs(Tokens) of
+ {ok, Forms} ->
+ case erl_eval:exprs(Forms, []) of
+ {value, Terms, _} -> Terms;
+ _ -> error
+ end;
_ -> error
- end.
+ end;
+ _ -> error
+ end.
+%% TODO: Bleeding eyes
add_to_path(InstallDir) ->
- case file:list_dir(InstallDir) of
- {ok, Files} ->