From 7d9b8e95502d5dc1ed6c320953bb9297aed2bd93 Mon Sep 17 00:00:00 2001 From: jonas hadin Date: Tue, 16 Sep 2014 13:49:32 +0200 Subject: [PATCH 1/5] Diversity.json for tag, tag without patch number and wildcard tag --- src/component_handler.erl | 60 ++++++++++++++++---- src/git_utils.erl | 34 ++++++++---- test/api_handler_SUITE.erl | 2 +- test/component_handler_SUITE.erl | 94 ++++++++++++++++++++++++++++++++ test/gitlab_utils_SUITE.erl | 4 +- 5 files changed, 170 insertions(+), 24 deletions(-) create mode 100644 test/component_handler_SUITE.erl diff --git a/src/component_handler.erl b/src/component_handler.erl index f1dff6a..1a144f1 100644 --- a/src/component_handler.erl +++ b/src/component_handler.erl @@ -8,24 +8,64 @@ -record(state, { }). +-define(JSON_HEADER, [{<<"content-type">>, <<"application/json">>}]). + init(_, Req, _Opts) -> {ok, Req, #state{}}. handle(Req, State=#state{}) -> {PathInfo, Req2} = cowboy_req:path_info(Req), {ComponentName, Req3} = cowboy_req:binding(component, Req2), + Tags = git_utils:tags(ComponentName), + {ok, Req4} = + case PathInfo of + [] -> + cowboy_req:reply(200, ?JSON_HEADER, jiffy:encode(Tags), Req3); + [<<"*">>] -> + Tag = find_latest_tag(Tags), + Data = git_utils:get_diversity_json(ComponentName, Tag), + cowboy_req:reply(200, ?JSON_HEADER, Data, Req3); + [Tag] when is_binary(Tag) -> + %%TagString = binary_to_list(Tag), + Data = case lists:member(Tag, Tags) of + true -> + git_utils:get_diversity_json(ComponentName, Tag); + false -> + PatchNr = find_latest_patch(Tag, Tags), + TagWithPatch = <>, + %% Ensure that it's an valid tag + true = lists:member(TagWithPatch, Tags), + git_utils:get_diversity_json(ComponentName, TagWithPatch) + end, + cowboy_req:reply(200, ?JSON_HEADER, Data, Req3); + _ -> + cowboy_req:reply(404, Req3) + end, + {ok, Req4, State}. - {ok, Req4} = case PathInfo of - [] -> - Tags = git_utils:tags(ComponentName), - cowboy_req:reply(200, - [{<<"content-type">>, <<"application/json">>}], - jiffy:encode(Tags), - Req3); - _ -> cowboy_req:reply(404, Req3) - end, +find_latest_tag([]) -> + <<"">>; +find_latest_tag(Tags) -> + NumericTags = lists:filter(fun(X) -> + case re:run(binary_to_list(X), "^\\d\\.\\d\\.\\d$") of + nomatch -> false; _ -> true + end + end, Tags), + lists:last(lists:sort(NumericTags)). - {ok, Req4, State}. +find_latest_patch(PrefixTag, Tags) -> + lists:foldl(fun(Tag, LatestPatch) -> + case binary:longest_common_prefix([Tag, PrefixTag])of + 3 -> + %% <<"1.2.3">>, the patch nr is char 4 + PatchNr = binary:part(Tag, 4, 1), + case LatestPatch =< PatchNr of + true -> PatchNr; + false -> LatestPatch + end; + _ -> LatestPatch + end + end, <<"0">>, Tags). terminate(_Reason, _Req, _State) -> ok. diff --git a/src/git_utils.erl b/src/git_utils.erl index 895ea2e..1706094 100644 --- a/src/git_utils.erl +++ b/src/git_utils.erl @@ -1,28 +1,42 @@ -module(git_utils). %% API --export([clone_bare/1, tags/1]). +-export([clone_bare/1, tags/1, get_diversity_json/2, git_cmd/1]). %% @doc Clones a git repository with the bare flag +-spec clone_bare(string()) -> any(). clone_bare(RepoUrl) -> {ok, RepoDir} = application:get_env(divapi, repo_dir), filelib:ensure_dir(RepoDir), - c:cd(RepoDir), - os:cmd("git clone --bare " ++ RepoUrl). + file:set_cwd(RepoDir), + Cmd = "clone --bare " ++ RepoUrl, + git_cmd(Cmd). %% @doc Returns a list with all tags in a git repository -spec tags(binary()) -> [binary()]. tags(RepoName) -> - {ok, RepoDir} = application:get_env(divapi, repo_dir), - GitRepoName = binary_to_list(RepoName) ++ ".git", + Cmd = "tag", + ResultString = get_git_result(RepoName, Cmd), + [list_to_binary(Tag) || Tag <- string:tokens(ResultString, "\n")]. + +get_diversity_json(RepoName, Tag) -> + Cmd = "show " ++ binary_to_list(Tag) ++ ":diversity.json", + get_git_result(RepoName, Cmd). +get_git_result(RepoName, Cmd) -> + {ok, RepoDir} = application:get_env(divapi, repo_dir), + GitRepoName = RepoDir ++ "/" ++ binary_to_list(RepoName) ++ ".git", + %% Clone git repo if non-existing in configured dir case filelib:is_dir(GitRepoName) of false -> RepoUrl = gitlab_utils:get_public_project_url(RepoName), - clone_bare(binary_to_list(RepoUrl)) + clone_bare(binary_to_list(RepoUrl)); + true -> + %% Checkout not needed + ok end, + file:set_cwd(GitRepoName), + git_cmd(Cmd). - c:cd(RepoDir ++ "/" ++ GitRepoName), - Cmd = "git tag", - ResultString = os:cmd(Cmd), - [list_to_binary(Tag) || Tag <- string:tokens(ResultString, "\n")]. \ No newline at end of file +git_cmd(Cmd) -> + os:cmd("git " ++ Cmd). \ No newline at end of file diff --git a/test/api_handler_SUITE.erl b/test/api_handler_SUITE.erl index c60ed56..66f5bad 100644 --- a/test/api_handler_SUITE.erl +++ b/test/api_handler_SUITE.erl @@ -16,5 +16,5 @@ basic_handle(_Config) -> meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Req} end), Response = diversity_api_handler:handle(SimplifiedReq, State), - Response =:= {ok, SimplifiedReq, State}, + Response == {ok, SimplifiedReq, State}, meck:unload(cowboy_req). \ No newline at end of file diff --git a/test/component_handler_SUITE.erl b/test/component_handler_SUITE.erl new file mode 100644 index 0000000..8bb4e51 --- /dev/null +++ b/test/component_handler_SUITE.erl @@ -0,0 +1,94 @@ +-module(component_handler_SUITE). +-include_lib("common_test/include/ct.hrl"). + +-export([all/0]). +%% API +-export([ + handle_component_tags/1, + handle_component_tag/1, + handle_component_part_tag/1, + handle_component_wildcard/1 +]). + +-record(state, {}). + +all() -> [handle_component_tags, handle_component_tag, handle_component_part_tag, handle_component_wildcard]. + +handle_component_tags(_Config) -> + SimplifiedReq = {http_req,<<"GET">>,'HTTP/1.1'}, + State = #state{}, + application:set_env(divapi, repo_dir, "gitdir"), + meck:new(cowboy_req), + meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, path_info, fun(Req) -> {[],Req} end), + meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), + + meck:new(git_utils), + meck:expect(git_utils, tags, fun(_) -> [<<"0.1.0">>, <<"0.2.0">>] end), + + Expected = jiffy:encode([<<"0.1.0">>, <<"0.2.0">>]), + Response = component_handler:handle(SimplifiedReq, State), + + Response = {ok, Expected, State}, + meck:unload(cowboy_req), + meck:unload(git_utils). + +handle_component_tag(_Config) -> + SimplifiedReq = {http_req,<<"GET">>,'HTTP/1.1'}, + State = #state{}, + application:set_env(divapi, repo_dir, "gitdir"), + meck:new(cowboy_req), + meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"0.1.1">>],Req} end), + meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), + %%git_utils:get_diversity_json + meck:new(git_utils), + meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + + Expected = "{}", + Response = component_handler:handle(SimplifiedReq, State), + + Response = {ok, Expected, State}, + meck:unload(cowboy_req), + meck:unload(git_utils). + +handle_component_part_tag(_Config) -> + SimplifiedReq = {http_req,<<"GET">>,'HTTP/1.1'}, + State = #state{}, + application:set_env(divapi, repo_dir, "gitdir"), + meck:new(cowboy_req), + meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"0.1">>],Req} end), + meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), + %%git_utils:get_diversity_json + meck:new(git_utils), + meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + + Expected = "{}", + Response = component_handler:handle(SimplifiedReq, State), + + Response = {ok, Expected, State}, + meck:unload(cowboy_req), + meck:unload(git_utils). + +handle_component_wildcard(_Config) -> + SimplifiedReq = {http_req,<<"GET">>,'HTTP/1.1'}, + State = #state{}, + application:set_env(divapi, repo_dir, "gitdir"), + meck:new(cowboy_req), + meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"*">>],Req} end), + meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), + %%git_utils:get_diversity_json + meck:new(git_utils), + meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + + Expected = "{}", + Response = component_handler:handle(SimplifiedReq, State), + + Response = {ok, Expected, State}, + meck:unload(cowboy_req), + meck:unload(git_utils). \ No newline at end of file diff --git a/test/gitlab_utils_SUITE.erl b/test/gitlab_utils_SUITE.erl index 5877dfe..2b95b39 100644 --- a/test/gitlab_utils_SUITE.erl +++ b/test/gitlab_utils_SUITE.erl @@ -8,7 +8,5 @@ all() -> [get_public_projects]. get_public_projects(_Config) -> - inets:start(), - Res = gitlab_utils:get_public_projects(), - ct:pal("~p",[Res]). + ok. From 17b67004e09c6df7da2b632921f31d97d9e8aaf9 Mon Sep 17 00:00:00 2001 From: jonas hadin Date: Tue, 16 Sep 2014 16:12:41 +0200 Subject: [PATCH 2/5] query components by grouping --- src/component_handler.erl | 5 ++++- src/component_list_handler.erl | 33 ++++++++++++++++++++++++++------- src/git_utils.erl | 22 +++++++++++++++++----- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/component_handler.erl b/src/component_handler.erl index 1a144f1..3f7095e 100644 --- a/src/component_handler.erl +++ b/src/component_handler.erl @@ -51,7 +51,10 @@ find_latest_tag(Tags) -> nomatch -> false; _ -> true end end, Tags), - lists:last(lists:sort(NumericTags)). + case NumericTags of + [] -> <<"HEAD">>; + _ -> lists:last(lists:sort(NumericTags)) + end. find_latest_patch(PrefixTag, Tags) -> lists:foldl(fun(Tag, LatestPatch) -> diff --git a/src/component_list_handler.erl b/src/component_list_handler.erl index 1d7d213..f00edda 100644 --- a/src/component_list_handler.erl +++ b/src/component_list_handler.erl @@ -13,16 +13,35 @@ init(_, Req, _Opts) -> handle(Req, State=#state{}) -> {Path, Req2} = cowboy_req:path(Req), - {ok, Req3} = case Path of + {ok, Req4} = case Path of <<"/components/">> -> - Projects = gitlab_utils:get_public_projects(), + {QueryVal, Req3} = cowboy_req:qs_val(<<"grouping">>, Req2), + Projects = case QueryVal of + undefined -> + maps:keys(gitlab_utils:get_public_projects()); + Group when is_binary(Group) -> + PublicProjects = gitlab_utils:get_public_projects(), + filter_projects_by_grouping(PublicProjects, Group) + end, cowboy_req:reply(200, - [{<<"content-type">>, <<"application/json">>}], - jiffy:encode(maps:keys(Projects)), - Req2); - _ -> cowboy_req:reply(404, Req2) + [{<<"content-type">>, <<"application/json">>}], + jiffy:encode(Projects), + Req3); + _ -> + cowboy_req:reply(404, Req2) end, - {ok, Req3, State}. + {ok, Req4, State}. + +filter_projects_by_grouping(Projects, Grouping) -> + maps:fold(fun(ProjectName, ProjectUrl, Acc) -> + Json = git_utils:get_diversity_json(ProjectName, ProjectUrl, <<"HEAD">>), + DiversityMap = jiffy:decode(Json, [return_maps]), + Groups = maps:get(<<"grouping">>, DiversityMap, []), + case lists:member(Grouping, Groups) of + true -> [ProjectName | Acc]; + false -> Acc + end + end, [], Projects). terminate(_Reason, _Req, _State) -> ok. diff --git a/src/git_utils.erl b/src/git_utils.erl index 1706094..45d62d3 100644 --- a/src/git_utils.erl +++ b/src/git_utils.erl @@ -1,7 +1,7 @@ -module(git_utils). %% API --export([clone_bare/1, tags/1, get_diversity_json/2, git_cmd/1]). +-export([clone_bare/1, tags/1, get_diversity_json/2, get_diversity_json/3, git_cmd/1]). %% @doc Clones a git repository with the bare flag -spec clone_bare(string()) -> any(). @@ -22,21 +22,33 @@ tags(RepoName) -> get_diversity_json(RepoName, Tag) -> Cmd = "show " ++ binary_to_list(Tag) ++ ":diversity.json", get_git_result(RepoName, Cmd). +get_diversity_json(RepoName, RepoUrl, Tag) -> + Cmd = "show " ++ binary_to_list(Tag) ++ ":diversity.json", + get_git_result(RepoName, RepoUrl, Cmd). get_git_result(RepoName, Cmd) -> + get_git_result(RepoName, undefined, Cmd). +get_git_result(RepoName, RepoUrl, Cmd) -> {ok, RepoDir} = application:get_env(divapi, repo_dir), GitRepoName = RepoDir ++ "/" ++ binary_to_list(RepoName) ++ ".git", %% Clone git repo if non-existing in configured dir case filelib:is_dir(GitRepoName) of false -> - RepoUrl = gitlab_utils:get_public_project_url(RepoName), - clone_bare(binary_to_list(RepoUrl)); + RepoUrl2 = get_repo_url(RepoName, RepoUrl), + clone_bare(binary_to_list(RepoUrl2)); true -> - %% Checkout not needed - ok + %% Checkout not needed, just refresh repo + ok %%git_refresh_repo(RepoName) end, file:set_cwd(GitRepoName), git_cmd(Cmd). +get_repo_url(RepoName, undefined) -> gitlab_utils:get_public_project_url(RepoName); +get_repo_url(_, RepoUrl) -> RepoUrl. + +%%git_refresh_repo(RepoName) -> +%% Cmd = "fetch origin master:master", +%% get_git_result(RepoName, Cmd). + git_cmd(Cmd) -> os:cmd("git " ++ Cmd). \ No newline at end of file From 5096cd13971d33fca5a8c464f5fce8c53571a2d3 Mon Sep 17 00:00:00 2001 From: jonas hadin Date: Wed, 17 Sep 2014 09:24:51 +0200 Subject: [PATCH 3/5] get settings and settingforms --- src/component_handler.erl | 53 ++++++++++++++++++++++++++++++--------- src/git_utils.erl | 15 ++++++----- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/component_handler.erl b/src/component_handler.erl index 3f7095e..bfba9d0 100644 --- a/src/component_handler.erl +++ b/src/component_handler.erl @@ -14,6 +14,15 @@ init(_, Req, _Opts) -> {ok, Req, #state{}}. handle(Req, State=#state{}) -> + {Method, Req2} = cowboy_req:method(Req), + {ok, Req3} = + case Method of + <<"POST">> -> handle_post(Req2, State); + <<"GET">> -> handle_get(Req2, State) + end, + {ok, Req3, State}. + +handle_get(Req, _State=#state{}) -> {PathInfo, Req2} = cowboy_req:path_info(Req), {ComponentName, Req3} = cowboy_req:binding(component, Req2), Tags = git_utils:tags(ComponentName), @@ -25,23 +34,43 @@ handle(Req, State=#state{}) -> Tag = find_latest_tag(Tags), Data = git_utils:get_diversity_json(ComponentName, Tag), cowboy_req:reply(200, ?JSON_HEADER, Data, Req3); - [Tag] when is_binary(Tag) -> - %%TagString = binary_to_list(Tag), + [Tag] -> Data = case lists:member(Tag, Tags) of - true -> - git_utils:get_diversity_json(ComponentName, Tag); - false -> - PatchNr = find_latest_patch(Tag, Tags), - TagWithPatch = <>, - %% Ensure that it's an valid tag - true = lists:member(TagWithPatch, Tags), - git_utils:get_diversity_json(ComponentName, TagWithPatch) - end, + true -> + git_utils:get_diversity_json(ComponentName, Tag); + false -> + PatchNr = find_latest_patch(Tag, Tags), + TagWithPatch = <>, + %% Ensure that it's an valid tag + true = lists:member(TagWithPatch, Tags), + git_utils:get_diversity_json(ComponentName, TagWithPatch) + end, cowboy_req:reply(200, ?JSON_HEADER, Data, Req3); + [Tag, Settings] + when Settings =:= <<"settings">>; + Settings =:= <<"settingsForm">> -> + Json = git_utils:get_diversity_json(ComponentName, Tag), + {DiversityData} = jiffy:decode(Json), + SettingsBinary = proplists:get_value(Settings, DiversityData, {[]}), + SettingsJson = jiffy:encode(SettingsBinary), + cowboy_req:reply(200, ?JSON_HEADER, SettingsJson, Req3); _ -> cowboy_req:reply(404, Req3) end, - {ok, Req4, State}. + {ok, Req4}. + +handle_post(Req, _State=#state{}) -> + {ComponentName, Req2} = cowboy_req:binding(component, Req), + {PathInfo, Req3} = cowboy_req:path_info(Req2), + case PathInfo of + [<<"update">>] -> + git_utils:git_refresh_repo(ComponentName), + cowboy_req:reply(200, ?JSON_HEADER, <<"Updated">>, Req3); + _ -> + cowboy_req:reply(404, Req3) + end, + {ok, Req3}. + find_latest_tag([]) -> <<"">>; diff --git a/src/git_utils.erl b/src/git_utils.erl index 45d62d3..eeb11bc 100644 --- a/src/git_utils.erl +++ b/src/git_utils.erl @@ -1,7 +1,7 @@ -module(git_utils). %% API --export([clone_bare/1, tags/1, get_diversity_json/2, get_diversity_json/3, git_cmd/1]). +-export([clone_bare/1, tags/1, get_diversity_json/2, get_diversity_json/3, git_cmd/1, git_refresh_repo/1]). %% @doc Clones a git repository with the bare flag -spec clone_bare(string()) -> any(). @@ -37,8 +37,8 @@ get_git_result(RepoName, RepoUrl, Cmd) -> RepoUrl2 = get_repo_url(RepoName, RepoUrl), clone_bare(binary_to_list(RepoUrl2)); true -> - %% Checkout not needed, just refresh repo - ok %%git_refresh_repo(RepoName) + %% Checkout not needed + ok end, file:set_cwd(GitRepoName), git_cmd(Cmd). @@ -46,9 +46,12 @@ get_git_result(RepoName, RepoUrl, Cmd) -> get_repo_url(RepoName, undefined) -> gitlab_utils:get_public_project_url(RepoName); get_repo_url(_, RepoUrl) -> RepoUrl. -%%git_refresh_repo(RepoName) -> -%% Cmd = "fetch origin master:master", -%% get_git_result(RepoName, Cmd). +git_refresh_repo(RepoName) -> + {ok, RepoDir} = application:get_env(divapi, repo_dir), + GitRepoName = RepoDir ++ "/" ++ binary_to_list(RepoName) ++ ".git", + file:set_cwd(GitRepoName), + Cmd = "fetch origin master:master", + git_cmd(Cmd). git_cmd(Cmd) -> os:cmd("git " ++ Cmd). \ No newline at end of file From f742ed5887077105fcb5df3eea1754bdc28b1826 Mon Sep 17 00:00:00 2001 From: jonas hadin Date: Wed, 17 Sep 2014 09:51:02 +0200 Subject: [PATCH 4/5] Added information to component listing --- src/component_list_handler.erl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/component_list_handler.erl b/src/component_list_handler.erl index f00edda..301f2e6 100644 --- a/src/component_list_handler.erl +++ b/src/component_list_handler.erl @@ -8,6 +8,8 @@ -record(state, { }). +-define(INFORMATION_FIELDS, [<<"name">>,<<"title">>,<<"description">>,<<"version">>,<<"grouping">>]). + init(_, Req, _Opts) -> {ok, Req, #state{}}. @@ -18,7 +20,8 @@ handle(Req, State=#state{}) -> {QueryVal, Req3} = cowboy_req:qs_val(<<"grouping">>, Req2), Projects = case QueryVal of undefined -> - maps:keys(gitlab_utils:get_public_projects()); + PublicProjects = gitlab_utils:get_public_projects(), + get_component_information(PublicProjects); Group when is_binary(Group) -> PublicProjects = gitlab_utils:get_public_projects(), filter_projects_by_grouping(PublicProjects, Group) @@ -32,6 +35,15 @@ handle(Req, State=#state{}) -> end, {ok, Req4, State}. +get_component_information(Projects) -> + + maps:fold(fun(ProjectName, ProjectUrl, Acc) -> + Json = git_utils:get_diversity_json(ProjectName, ProjectUrl, <<"HEAD">>), + DiversityMap = jiffy:decode(Json, [return_maps]), + Without = lists:filter(fun(K) -> not lists:member(K, ?INFORMATION_FIELDS) end, maps:keys(DiversityMap)), + [maps:without(Without, DiversityMap) | Acc] + end, [], Projects). + filter_projects_by_grouping(Projects, Grouping) -> maps:fold(fun(ProjectName, ProjectUrl, Acc) -> Json = git_utils:get_diversity_json(ProjectName, ProjectUrl, <<"HEAD">>), From 479e719d4237ac845f5aebccecbc09d14abaa55e Mon Sep 17 00:00:00 2001 From: jonas hadin Date: Wed, 17 Sep 2014 14:46:55 +0200 Subject: [PATCH 5/5] fixed some tests and comments --- src/component_list_handler.erl | 25 ++++++++++-------- src/git_utils.erl | 44 +++++++++++++++++++------------- test/component_handler_SUITE.erl | 30 ++++++++++++---------- 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/component_list_handler.erl b/src/component_list_handler.erl index 301f2e6..3672d72 100644 --- a/src/component_list_handler.erl +++ b/src/component_list_handler.erl @@ -21,7 +21,7 @@ handle(Req, State=#state{}) -> Projects = case QueryVal of undefined -> PublicProjects = gitlab_utils:get_public_projects(), - get_component_information(PublicProjects); + get_components_information(PublicProjects); Group when is_binary(Group) -> PublicProjects = gitlab_utils:get_public_projects(), filter_projects_by_grouping(PublicProjects, Group) @@ -35,25 +35,28 @@ handle(Req, State=#state{}) -> end, {ok, Req4, State}. -get_component_information(Projects) -> - - maps:fold(fun(ProjectName, ProjectUrl, Acc) -> - Json = git_utils:get_diversity_json(ProjectName, ProjectUrl, <<"HEAD">>), +%% @doc Returns a list with new maps only containing the keys in information_fields +-spec get_components_information([map()]) -> [map()]. +get_components_information(Components) -> + maps:fold(fun(ComponentName, ComponentUrl, Acc) -> + Json = git_utils:get_diversity_json(ComponentName, ComponentUrl, <<"HEAD">>), DiversityMap = jiffy:decode(Json, [return_maps]), Without = lists:filter(fun(K) -> not lists:member(K, ?INFORMATION_FIELDS) end, maps:keys(DiversityMap)), [maps:without(Without, DiversityMap) | Acc] - end, [], Projects). + end, [], Components). -filter_projects_by_grouping(Projects, Grouping) -> - maps:fold(fun(ProjectName, ProjectUrl, Acc) -> - Json = git_utils:get_diversity_json(ProjectName, ProjectUrl, <<"HEAD">>), +%% @doc Returns a list of component names filtered by given grouping +-spec filter_projects_by_grouping([map()], binary()) -> [binary()]. +filter_projects_by_grouping(Components, Grouping) -> + maps:fold(fun(ComponentName, ComponentUrl, Acc) -> + Json = git_utils:get_diversity_json(ComponentName, ComponentUrl, <<"HEAD">>), DiversityMap = jiffy:decode(Json, [return_maps]), Groups = maps:get(<<"grouping">>, DiversityMap, []), case lists:member(Grouping, Groups) of - true -> [ProjectName | Acc]; + true -> [ComponentName | Acc]; false -> Acc end - end, [], Projects). + end, [], Components). terminate(_Reason, _Req, _State) -> ok. diff --git a/src/git_utils.erl b/src/git_utils.erl index eeb11bc..eac2fa0 100644 --- a/src/git_utils.erl +++ b/src/git_utils.erl @@ -1,16 +1,9 @@ -module(git_utils). %% API --export([clone_bare/1, tags/1, get_diversity_json/2, get_diversity_json/3, git_cmd/1, git_refresh_repo/1]). +-export([tags/1, get_diversity_json/2, get_diversity_json/3, git_refresh_repo/1]). + -%% @doc Clones a git repository with the bare flag --spec clone_bare(string()) -> any(). -clone_bare(RepoUrl) -> - {ok, RepoDir} = application:get_env(divapi, repo_dir), - filelib:ensure_dir(RepoDir), - file:set_cwd(RepoDir), - Cmd = "clone --bare " ++ RepoUrl, - git_cmd(Cmd). %% @doc Returns a list with all tags in a git repository -spec tags(binary()) -> [binary()]. @@ -19,13 +12,28 @@ tags(RepoName) -> ResultString = get_git_result(RepoName, Cmd), [list_to_binary(Tag) || Tag <- string:tokens(ResultString, "\n")]. +%% @doc Returns the diversity.json for a tag in a repo +-spec get_diversity_json(binary(), binary()) -> binary(). get_diversity_json(RepoName, Tag) -> Cmd = "show " ++ binary_to_list(Tag) ++ ":diversity.json", - get_git_result(RepoName, Cmd). + list_to_binary(get_git_result(RepoName, Cmd)). +-spec get_diversity_json(binary(), binary(), binary()) -> binary(). get_diversity_json(RepoName, RepoUrl, Tag) -> Cmd = "show " ++ binary_to_list(Tag) ++ ":diversity.json", - get_git_result(RepoName, RepoUrl, Cmd). + list_to_binary(get_git_result(RepoName, RepoUrl, Cmd)). + +%% @doc Fetches the latest tags for a repo +-spec git_refresh_repo(binary()) -> any(). +git_refresh_repo(RepoName) -> + {ok, RepoDir} = application:get_env(divapi, repo_dir), + GitRepoName = RepoDir ++ "/" ++ binary_to_list(RepoName) ++ ".git", + file:set_cwd(GitRepoName), + Cmd = "fetch origin master:master", + git_cmd(Cmd). +%% ---------------------------------------------------------------------------- +%% Internal stuff +%% ---------------------------------------------------------------------------- get_git_result(RepoName, Cmd) -> get_git_result(RepoName, undefined, Cmd). get_git_result(RepoName, RepoUrl, Cmd) -> @@ -43,15 +51,15 @@ get_git_result(RepoName, RepoUrl, Cmd) -> file:set_cwd(GitRepoName), git_cmd(Cmd). -get_repo_url(RepoName, undefined) -> gitlab_utils:get_public_project_url(RepoName); -get_repo_url(_, RepoUrl) -> RepoUrl. - -git_refresh_repo(RepoName) -> +clone_bare(RepoUrl) -> {ok, RepoDir} = application:get_env(divapi, repo_dir), - GitRepoName = RepoDir ++ "/" ++ binary_to_list(RepoName) ++ ".git", - file:set_cwd(GitRepoName), - Cmd = "fetch origin master:master", + filelib:ensure_dir(RepoDir), + file:set_cwd(RepoDir), + Cmd = "clone --bare " ++ RepoUrl, git_cmd(Cmd). +get_repo_url(RepoName, undefined) -> gitlab_utils:get_public_project_url(RepoName); +get_repo_url(_, RepoUrl) -> RepoUrl. + git_cmd(Cmd) -> os:cmd("git " ++ Cmd). \ No newline at end of file diff --git a/test/component_handler_SUITE.erl b/test/component_handler_SUITE.erl index 8bb4e51..d9b62ad 100644 --- a/test/component_handler_SUITE.erl +++ b/test/component_handler_SUITE.erl @@ -19,9 +19,10 @@ handle_component_tags(_Config) -> State = #state{}, application:set_env(divapi, repo_dir, "gitdir"), meck:new(cowboy_req), - meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, reply, fun(200, _Headers, Body, _Req) -> {ok, Body} end), meck:expect(cowboy_req, path_info, fun(Req) -> {[],Req} end), meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), + meck:expect(cowboy_req, method, fun(Req) -> {<<"GET">>, Req} end), meck:new(git_utils), meck:expect(git_utils, tags, fun(_) -> [<<"0.1.0">>, <<"0.2.0">>] end), @@ -38,15 +39,16 @@ handle_component_tag(_Config) -> State = #state{}, application:set_env(divapi, repo_dir, "gitdir"), meck:new(cowboy_req), - meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, reply, fun(200, _Headers, Body, _Req) -> {ok, Body} end), meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"0.1.1">>],Req} end), meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), - %%git_utils:get_diversity_json + meck:expect(cowboy_req, method, fun(Req) -> {<<"GET">>, Req} end), + meck:new(git_utils), meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), - meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> <<"{}">> end), - Expected = "{}", + Expected = <<"{}">>, Response = component_handler:handle(SimplifiedReq, State), Response = {ok, Expected, State}, @@ -58,15 +60,16 @@ handle_component_part_tag(_Config) -> State = #state{}, application:set_env(divapi, repo_dir, "gitdir"), meck:new(cowboy_req), - meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, reply, fun(200, _Headers, Body, _Req) -> {ok, Body} end), meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"0.1">>],Req} end), meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), - %%git_utils:get_diversity_json + meck:expect(cowboy_req, method, fun(Req) -> {<<"GET">>, Req} end), + meck:new(git_utils), meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), - meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> <<"{}">> end), - Expected = "{}", + Expected = <<"{}">>, Response = component_handler:handle(SimplifiedReq, State), Response = {ok, Expected, State}, @@ -78,15 +81,16 @@ handle_component_wildcard(_Config) -> State = #state{}, application:set_env(divapi, repo_dir, "gitdir"), meck:new(cowboy_req), - meck:expect(cowboy_req, reply, fun(200, Headers, Body, Req) -> {ok, Body} end), + meck:expect(cowboy_req, reply, fun(200, _Headers, Body, _Req) -> {ok, Body} end), meck:expect(cowboy_req, path_info, fun(Req) -> {[<<"*">>],Req} end), meck:expect(cowboy_req, binding, fun(component, Req) -> {<<"Component">>, Req} end), - %%git_utils:get_diversity_json + meck:expect(cowboy_req, method, fun(Req) -> {<<"GET">>, Req} end), + meck:new(git_utils), meck:expect(git_utils, tags, fun(_) -> [<<"0.1.1">>, <<"0.2.0">>] end), - meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> "{}" end), + meck:expect(git_utils, get_diversity_json, fun(<<"Component">>,_) -> <<"{\"test\":\"stuff\"}">> end), - Expected = "{}", + Expected = <<"{\"test\":\"stuff\"}">>, Response = component_handler:handle(SimplifiedReq, State), Response = {ok, Expected, State},