Skip to content

Commit

Permalink
reformatting and todo: learning the code
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmytro Lytovchenko committed Feb 7, 2014
1 parent 36e9f97 commit d61a5d1
Show file tree
Hide file tree
Showing 9 changed files with 1,216 additions and 1,189 deletions.
41 changes: 23 additions & 18 deletions README.markdown
Original file line number Original file line Diff line number Diff line change
@@ -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_ ### epm _IS_
* an Erlang package manager meant to have _minimal_ impact on projects * an Erlang package manager meant to have _minimal_ impact on projects
* a simple and easy dependency tracker * a simple and easy dependency tracker
Expand All @@ -11,13 +17,13 @@
curl "https://github.com/JacobVorreuter/epm/raw/master/epm" > epm curl "https://github.com/JacobVorreuter/epm/raw/master/epm" > epm
chmod +x epm chmod +x epm
sudo mv epm /usr/local/bin/ sudo mv epm /usr/local/bin/

epm config --set build_dir "/tmp" epm config --set build_dir "/tmp"
epm config --set install_dir "/Users/jvorreuter/erl_libs" epm config --set install_dir "/Users/jvorreuter/erl_libs"
epm config --set proxy_host http://my.corporate.proxy epm config --set proxy_host http://my.corporate.proxy
epm config --set proxy_port 80 epm config --set proxy_port 80
epm config --set net_timeout 60000 # for a slow network... epm config --set net_timeout 60000 # for a slow network...

### Read the blog post ### Read the blog post


<http://www.jkvor.com/erlang-package-manager> <http://www.jkvor.com/erlang-package-manager>
Expand Down Expand Up @@ -77,7 +83,7 @@
--get (default) --get (default)
--set <key> <value> --set <key> <value>
--remove <key> --remove <key>

### Do it ### Do it


tell epm where to install packages tell epm where to install packages
Expand All @@ -86,8 +92,8 @@ tell epm where to install packages
epm v0.1.1, 2010 epm v0.1.1, 2010


+ updated .epm config + updated .epm config

search for an Erlang app search for an Erlang app


jvorreuter$ ./epm search excavator jvorreuter$ ./epm search excavator
epm v0.1.1, 2010 epm v0.1.1, 2010
Expand All @@ -98,15 +104,15 @@ search for an Erlang app
name: excavator name: excavator
owner: JacobVorreuter owner: JacobVorreuter
followers: 7 followers: 7
homepage: homepage:
description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc) description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
tags: tags:
"0.3" "0.3"
branches: branches:
master master
scheduler 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 jvorreuter$ ./epm install excavator
epm v0.1.1, 2010 epm v0.1.1, 2010
Expand Down Expand Up @@ -142,7 +148,7 @@ install that app that you wanted (its dependencies will be installed too)
+ running excavator build command + running excavator build command
+ running excavator install 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 jvorreuter$ ./epm info excavator
epm v0.1.1, 2010 epm v0.1.1, 2010
Expand All @@ -154,16 +160,16 @@ get some info about that app you just installed
owner: JacobVorreuter owner: JacobVorreuter
vsn: master vsn: master
install dir: /Users/jvorreuter/dev/excavator-0.3 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) description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
dependencies: dependencies:
clones/mochiweb/master clones/mochiweb/master
mochixpath/master mochixpath/master
dynamic_compile/master dynamic_compile/master
epm/etap/master epm/etap/master
mochiweb_server_behavior/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 jvorreuter$ ./epm list
epm v0.1.1, 2010 epm v0.1.1, 2010
Expand All @@ -175,9 +181,9 @@ how 'bout a list of all apps I've installed?
owner: JacobVorreuter owner: JacobVorreuter
vsn: master vsn: master
install dir: /Users/jvorreuter/dev/excavator-0.3 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) description: An Erlang application for ingesting data from various sources (APIs, data feeds, web content, etc)
dependencies: dependencies:
clones/mochiweb/master clones/mochiweb/master
mochixpath/master mochixpath/master
dynamic_compile/master dynamic_compile/master
Expand All @@ -195,23 +201,23 @@ how 'bout a list of all apps I've installed?
owner: JacobVorreuter owner: JacobVorreuter
vsn: master vsn: master
install dir: /Users/jvorreuter/dev/dynamic_compile-0.1 install dir: /Users/jvorreuter/dev/dynamic_compile-0.1
homepage: homepage:
description: compile and load erlang modules from string input description: compile and load erlang modules from string input


name: mochiweb_server_behavior name: mochiweb_server_behavior
owner: JacobVorreuter owner: JacobVorreuter
vsn: master vsn: master
install dir: /Users/jvorreuter/dev/mochiweb_server_behavior-0.1 install dir: /Users/jvorreuter/dev/mochiweb_server_behavior-0.1
homepage: homepage:
description: Erlang behavior for a simple mochiweb web server description: Erlang behavior for a simple mochiweb web server
dependencies: dependencies:
clones/mochiweb/master clones/mochiweb/master


name: etap name: etap
owner: epm owner: epm
vsn: master vsn: master
install dir: /Users/jvorreuter/dev/etap-0.3.4 install dir: /Users/jvorreuter/dev/etap-0.3.4
homepage: homepage:
description: etap is a simple erlang testing library that provides TAP compliant output. description: etap is a simple erlang testing library that provides TAP compliant output.


name: mochiweb name: mochiweb
Expand All @@ -234,4 +240,3 @@ what have I done? I must remove that terrible app. Its dependencies can stay tho
([y]/n) y ([y]/n) y


+ removing package JacobVorreuter-excavator-master from /Users/jvorreuter/dev/excavator-0.3 + removing package JacobVorreuter-excavator-master from /Users/jvorreuter/dev/excavator-0.3

3 changes: 3 additions & 0 deletions include/epm.hrl
Original file line number Original file line Diff line number Diff line change
@@ -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)))). -define(EXIT(Format, Args), exit(lists:flatten(io_lib:format(Format, Args)))).


-record(repository, {name, owner, description, homepage, followers, pushed, api_module}). -record(repository, {name, owner, description, homepage, followers, pushed, api_module}).
Expand Down
184 changes: 93 additions & 91 deletions src/bitbucket_api.erl
Original file line number Original file line Diff line number Diff line change
@@ -1,23 +1,23 @@
%% OMFG, this API sucks. %% OMFG, this API sucks.
%% %%
%% explain to me how this is even remotely useful: %% explain to me how this is even remotely useful:
%% jacobvorreuter$ curl "http://api.bitbucket.org/1.0/repositories/?name=rebar" %% jacobvorreuter$ curl "http://api.bitbucket.org/1.0/repositories/?name=rebar"
%% { %% {
%% "count": 12, %% "count": 12,
%% "query": "rebar", %% "query": "rebar",
%% "repositories": [ %% "repositories": [
%% { %% {
%% "website": "", %% "website": "",
%% "slug": "rebar", %% "slug": "rebar",
%% "name": "rebar", %% "name": "rebar",
%% "followers_count": 0, %% "followers_count": 0,
%% "description": "" %% "description": ""
%% }, %% },
%% { %% {
%% "website": null, %% "website": null,
%% "slug": "rebar", %% "slug": "rebar",
%% "name": "rebar", %% "name": "rebar",
%% "followers_count": 0, %% "followers_count": 0,
%% "description": "" %% "description": ""
%% }, %% },
%% ... %% ...
Expand All @@ -35,52 +35,55 @@
-include("epm.hrl"). -include("epm.hrl").


package_deps(User, ProjectName, Vsn) -> package_deps(User, ProjectName, Vsn) ->
if if
User == undefined -> ?EXIT("get_package_deps/3 user cannot be undefined",[]); User == undefined ->
true -> ok ?EXIT("get_package_deps/3 user cannot be undefined", []);
end, true -> ok
if end,
ProjectName == undefined -> ?EXIT("get_package_deps/3 name cannot be undefined",[]); if
true -> ok ProjectName == undefined ->
end, ?EXIT("get_package_deps/3 name cannot be undefined", []);
if true -> ok
Vsn == undefined -> ?EXIT("get_package_deps/3 vsn cannot be undefined",[]); end,
true -> ok if
end, Vsn == undefined -> ?EXIT("get_package_deps/3 vsn cannot be undefined", []);
Url = lists:flatten(io_lib:format("http://bitbucket.org/~s/~s/raw/~s/~s.epm", [User, ProjectName, Vsn, ProjectName])), true -> ok
case epm_util:request_as_str(Url, "bitbucket.org") of end,
Body when is_list(Body) -> proplists:get_value(deps, epm_util:eval(Body), []); 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
end. Body when is_list(Body) ->

proplists:get_value(deps, epm_util:eval(Body), []);
_ -> []
end.

search(ProjectName) -> search(ProjectName) ->
case request_as_xml("http://bitbucket.org/repo/all/?name=" ++ ProjectName) of case request_as_xml("http://bitbucket.org/repo/all/?name=" ++ ProjectName) of
{html,_,_}=Html -> {html, _, _} = Html ->
case search_xml_for_repos(Html) of case search_xml_for_repos(Html) of
undefined -> []; undefined -> [];
Repos -> extract_repo_info_from_html(Repos) Repos -> extract_repo_info_from_html(Repos)
end; end;
Err -> Err ->
Err Err
end. end.

info(User, ProjectName) -> info(User, ProjectName) ->
case search(ProjectName) of case search(ProjectName) of
[#repository{}|_]=Repos -> [#repository{}|_] = Repos ->
case lists:filter( case lists:filter(
fun(Repo) -> fun(Repo) ->
Repo#repository.owner==User andalso Repo#repository.owner == User andalso
Repo#repository.name==ProjectName Repo#repository.name == ProjectName
end, Repos) of end , Repos) of
[R|_] -> R; [R|_] -> R;
_ -> undefined _ -> undefined
end; end;
[] -> [] ->
undefined; undefined;
Err -> Err ->
Err Err
end. end.

tags(User, ProjectName) -> 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]))), 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 case Xml of
Expand All @@ -102,26 +105,26 @@ branches(User, ProjectName) ->
download_package(Repo, Vsn) -> 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])), 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). epm_package:download_tarball(Repo, Url).

default_vsn() -> "tip". default_vsn() -> "tip".


request_as_xml(Url) -> request_as_xml(Url) ->
case epm_util:request_as_str(Url, "bitbucket.org") of case epm_util:request_as_str(Url, "bitbucket.org") of
Body when is_list(Body) -> Body when is_list(Body) ->
case yaws_html:h2e(Body) of case yaws_html:h2e(Body) of
{ehtml,[],[_,Xml]} -> Xml; {ehtml, [], [_, Xml]} -> Xml;
_ -> poorly_formatted_xml _ -> poorly_formatted_xml
end; end;
Err -> Err ->
Err Err
end. end.

%% fake xpaths %% fake xpaths


search_xml_for_repos({'div',[{class,"repos-all"}|_],Repos}) -> search_xml_for_repos({'div',[{class,"repos-all"}|_],Repos}) ->
Repos; Repos;
search_xml_for_repos({_,_,Children}) -> 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) -> search_xml_for_repos([Child|Tail]) when not is_integer(Child) ->
case search_xml_for_repos(Child) of case search_xml_for_repos(Child) of
undefined -> undefined ->
Expand All @@ -132,24 +135,23 @@ search_xml_for_repos([Child|Tail]) when not is_integer(Child) ->
search_xml_for_repos(_) -> undefined. search_xml_for_repos(_) -> undefined.


extract_repo_info_from_html(Repos) -> extract_repo_info_from_html(Repos) ->
lists:foldl( lists:foldl(
fun({'div',_,Props}, Acc) -> fun({'div', _, Props}, Acc) ->
case Props of case Props of
[{'div',_,_},{span,[],[{a,_,User},_,{a,_,RepoName}]},{br,_},Desc|_] -> [{'div', _, _}, {span, [], [{a, _, User}, _, {a, _, RepoName}]}, {br, _}, Desc|_] ->
Desc1 = string:strip(re:replace(Desc, "[\\t\\n]", "", [global, {return, list}])), Desc1 = string:strip(re:replace(Desc, "[\\t\\n]", "", [global, {return, list}])),
Desc2 = Desc2 =
case Desc1 of case Desc1 of
"Clone URL" ++ _ -> undefined; "Clone URL" ++ _ -> undefined;
_ -> Desc1 _ -> Desc1
end, end,
[#repository{ [#repository{
owner = User, owner = User ,
name = RepoName, name = RepoName ,
description = Desc2, description = Desc2,
api_module = ?MODULE api_module = ?MODULE
}|Acc]; }|Acc];
_ -> _ ->
Acc Acc
end end
end, [], lists:reverse(Repos)). end, [], lists:reverse(Repos)).

Loading

0 comments on commit d61a5d1

Please sign in to comment.