Skip to content
This repository
Newer
Older
100644 161 lines (140 sloc) 5.333 kb
44a5bb48 » jlouis
2011-01-28 Hint Emacs that the Tab Stop of the files are 4 spaces.
1 %% -*- Mode: Erlang; tab-width: 4 -*-
3d5cf189 » yrashk
2011-01-25 Made agner_github a parametrized module
2 -module(agner_github, [Account]).
61c97b0e » yrashk
2011-01-25 Added modular indeces support
3 -behaviour(agner_index).
4 -include_lib("agner.hrl").
5 -include_lib("agner_index.hrl").
1f567bbb » yrashk
2011-02-04 Everybody shpuld be able to read cache files in /tmp
6 -include_lib("kernel/include/file.hrl").
61c97b0e » yrashk
2011-01-25 Added modular indeces support
7
8 -export([repositories/0,
9 repository/1,
10 tags/1,
11 branches/1,
7e7089d3 » yrashk
2011-01-27 Added -b/--browser option that will open browser to show the specific…
12 spec/2,
13 spec_url/2
1aabca94 » yrashk
2011-01-25 Initial WIP, nothing to see yet
14 ]).
15
61c97b0e » yrashk
2011-01-25 Added modular indeces support
16 repositories() ->
38f928ba » yrashk
2011-01-31 Apparently GitHub API or listing repositories paginates results, so w…
17 repositories(1).
18
19 repositories(Page) ->
20 case request("https://github.com/api/v2/json/repos/show/" ++ Account ++ "?page=" ++ integer_to_list(Page)) of
61c97b0e » yrashk
2011-01-25 Added modular indeces support
21 {error, _Reason} = Error ->
22 Error;
23 {struct, Object} ->
38f928ba » yrashk
2011-01-31 Apparently GitHub API or listing repositories paginates results, so w…
24 case proplists:get_value(<<"repositories">>, Object) of
25 [] ->
26 [];
27 Repositories ->
94bf9770 » yrashk
2011-01-31 Empty .agner repos shouldn't cause failure listing other packages
28 Repos = lists:filter(fun
29 ({_,undefined}) ->
30 false;
31 ({invalid,_}) ->
32 false;
33 (_) ->
34 true
35 end,
36 lists:map(fun ({struct, RepObject}) ->
37 {repo_name(proplists:get_value(<<"name">>, RepObject)),
38 proplists:get_value(<<"pushed_at">>, RepObject)}
39 end, Repositories)),
38f928ba » yrashk
2011-01-31 Apparently GitHub API or listing repositories paginates results, so w…
40 Repos ++ repositories(Page + 1)
41 end
61c97b0e » yrashk
2011-01-25 Added modular indeces support
42 end.
43
44 repository(Name) ->
1539ddef » yrashk
2011-01-25 Allow using github accounts other than 'agner'
45 case request("https://github.com/api/v2/json/repos/show/" ++ proper_repo_name(Name)) of
61c97b0e » yrashk
2011-01-25 Added modular indeces support
46 {error, _Reason} = Error ->
47 Error;
48 {struct, Object} ->
49 {struct, Repo} = proplists:get_value(<<"repository">>, Object),
50 Repo
51 end.
52
1aabca94 » yrashk
2011-01-25 Initial WIP, nothing to see yet
53
61c97b0e » yrashk
2011-01-25 Added modular indeces support
54 tags(Name) ->
26b6f04d » yrashk
2011-01-27 Use https for github
55 case request("https://github.com/api/v2/json/repos/show/" ++ proper_repo_name(Name) ++ "/tags") of
61c97b0e » yrashk
2011-01-25 Added modular indeces support
56 {struct, Object} ->
57 {struct, Tags} = proplists:get_value(<<"tags">>, Object),
58 lists:map(fun({Tag, SHA1}) ->
59 {binary_to_list(Tag),
60 binary_to_list(SHA1)}
61 end, Tags)
62 end.
63
64
65 branches(Name) ->
26b6f04d » yrashk
2011-01-27 Use https for github
66 case request("https://github.com/api/v2/json/repos/show/" ++ proper_repo_name(Name) ++ "/branches") of
61c97b0e » yrashk
2011-01-25 Added modular indeces support
67 {error, _Reason} = Error ->
68 Error;
69 {struct, Object} ->
70 {struct, Branches} = proplists:get_value(<<"branches">>, Object),
71 lists:map(fun({Branch, SHA1}) ->
72 {binary_to_list(Branch),
73 binary_to_list(SHA1)}
74 end, Branches)
75 end.
1aabca94 » yrashk
2011-01-25 Initial WIP, nothing to see yet
76
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
77 spec(Name, Version) ->
78 {ok, RepoServer} = agner_repo_server:create(Name, Version),
79 case agner_repo_server:pushed_at(RepoServer) of
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
80 At when is_list(At) ->
92da7d62 » yrashk
2011-02-04 Use /tmp/agner instead of HOME/.agner for caching
81 DotDir = filename:join("/tmp",".agner"),
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
82 filelib:ensure_dir(DotDir ++ "/"),
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
83 AtFilename = filename:join([DotDir, "cache." ++ Name ++ integer_to_list(erlang:phash2(Version)) ++
84 lists:map(fun ($/) ->
85 $_;
86 ($\s) ->
87 $_;
88 (C) ->
89 C
90 end, At)]),
91 spec_1(RepoServer, AtFilename);
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
92 undefined ->
93 {A,B,C} = now(),
94 N = node(),
95 TmpFile = lists:flatten(io_lib:format("/tmp/agner-~p-~p.~p.~p",[N,A,B,C])),
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
96 Result = spec_1(RepoServer, TmpFile),
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
97 file:delete(TmpFile),
98 Result
99 end.
100
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
101 spec_1(RepoServer, AtFilename) ->
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
102 case file:read_file_info(AtFilename) of
103 {error, enoent} ->
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
104 ok = agner_repo_server:clone(RepoServer, fun (Name) -> "git://github.com/" ++ proper_repo_name(Name) ++ ".git" end),
105
106 Config = agner_repo_server:file(RepoServer, "agner.config"),
107 {ok, S} = file:consult(Config),
108 {ok, _} = file:copy(Config, AtFilename),
1f567bbb » yrashk
2011-02-04 Everybody shpuld be able to read cache files in /tmp
109 {ok, #file_info{mode = Mode}} = file:read_file_info(AtFilename),
110 file:change_mode(AtFilename, Mode bor 8#00444),
7ee519f3 » yrashk
2011-01-30 Extracted agner_repo_server
111 S;
77ad16b9 » yrashk
2011-01-27 Implemented some aggressive caching and got rid of another GitHub API…
112 {ok, _} ->
113 {ok, S} = file:consult(AtFilename),
114 S
115 end.
116
7e7089d3 » yrashk
2011-01-27 Added -b/--browser option that will open browser to show the specific…
117 spec_url(Name, SHA1) ->
118 "https://github.com/" ++ proper_repo_name(Name) ++ "/blob/" ++ SHA1 ++ "/agner.config".
1aabca94 » yrashk
2011-01-25 Initial WIP, nothing to see yet
119
120 %%%
121
1539ddef » yrashk
2011-01-25 Allow using github accounts other than 'agner'
122 proper_repo_name(Name) ->
123 case string:tokens(Name,"/") of
124 [_, _]=L ->
125 string:join(L,"/") ++ ".agner";
126 [Name] ->
127 string:join([Account, Name],"/") ++ ".agner"
128 end.
129
130 %%%
131
1aabca94 » yrashk
2011-01-25 Initial WIP, nothing to see yet
132 request(URL) ->
133 parse_response(httpc_request(URL)).
134
135 httpc_request(URL) ->
136 httpc_request_1(URL,[]).
137
138 httpc_request_1(URL, Opts) ->
139 httpc:request(get,{URL,
140 []},
141 [{timeout, 60000}],
142 Opts,
143 agner).
61c97b0e » yrashk
2011-01-25 Added modular indeces support
144
145 parse_response({ok, {{"HTTP/1.1",200,_},_Headers,Body}}) ->
146 mochijson2:decode(Body);
147 parse_response({ok, {{"HTTP/1.1",404,_},_Headers,_Body}}) ->
4877e631 » yrashk
2011-01-27 Added a clause for GitHub's 403 status code (normally used when API r…
148 {error, not_found};
149 parse_response({ok, {{"HTTP/1.1",403,_}, _Headers, _Body}}) ->
150 {error, github_rate_limit_exceeded}.
61c97b0e » yrashk
2011-01-25 Added modular indeces support
151 %%%
152
153 repo_name(B) when is_binary(B) ->
154 S = binary_to_list(B),
155 case string:tokens(S,".") of
156 [Name,"agner"] ->
157 Name;
158 _ ->
159 invalid
160 end.
161
Something went wrong with that request. Please try again.