mirror of
https://github.com/correl/rebar.git
synced 2024-11-23 19:19:54 +00:00
Add 'p4' (Perforce) as a dependency type
This calls the 'p4' command-line tool to checkout and sync Perforce trees. It involves significantly more special code in Rebar than using 'git p4', but it eliminates the indirection of Rebar->Git->Python->Perforce
This commit is contained in:
parent
47c089aa80
commit
41f1a891d9
3 changed files with 70 additions and 4 deletions
|
@ -155,7 +155,7 @@
|
||||||
%% name as an atom, eg. mochiweb, a name and a version (from the .app file), or
|
%% name as an atom, eg. mochiweb, a name and a version (from the .app file), or
|
||||||
%% an application name, a version and the SCM details on how to fetch it (SCM
|
%% an application name, a version and the SCM details on how to fetch it (SCM
|
||||||
%% type, location and revision).
|
%% type, location and revision).
|
||||||
%% Rebar currently supports git, hg, bzr, svn, rsync, and fossil.
|
%% Rebar currently supports git, hg, bzr, svn, rsync, fossil, and p4.
|
||||||
{deps, [app_name,
|
{deps, [app_name,
|
||||||
{rebar, "1.0.*"},
|
{rebar, "1.0.*"},
|
||||||
{rebar, ".*",
|
{rebar, ".*",
|
||||||
|
@ -188,7 +188,8 @@
|
||||||
{app_name, ".*", {svn, "svn://svn.example.org/url"}},
|
{app_name, ".*", {svn, "svn://svn.example.org/url"}},
|
||||||
{app_name, ".*", {bzr, "https://www.example.org/url", "Rev"}},
|
{app_name, ".*", {bzr, "https://www.example.org/url", "Rev"}},
|
||||||
{app_name, ".*", {fossil, "https://www.example.org/url"}},
|
{app_name, ".*", {fossil, "https://www.example.org/url"}},
|
||||||
{app_name, ".*", {fossil, "https://www.example.org/url", "Vsn"}}]}.
|
{app_name, ".*", {fossil, "https://www.example.org/url", "Vsn"}},
|
||||||
|
{app_name, ".*", {p4, "//depot/subdir/app_dir"}}]}.
|
||||||
|
|
||||||
%% == Subdirectories ==
|
%% == Subdirectories ==
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,8 @@ info_help(Description) ->
|
||||||
{app_name, ".*", {svn, "svn://svn.example.org/url"}},
|
{app_name, ".*", {svn, "svn://svn.example.org/url"}},
|
||||||
{app_name, ".*", {bzr, "https://www.example.org/url", "Rev"}},
|
{app_name, ".*", {bzr, "https://www.example.org/url", "Rev"}},
|
||||||
{app_name, ".*", {fossil, "https://www.example.org/url"}},
|
{app_name, ".*", {fossil, "https://www.example.org/url"}},
|
||||||
{app_name, ".*", {fossil, "https://www.example.org/url", "Vsn"}}]}
|
{app_name, ".*", {fossil, "https://www.example.org/url", "Vsn"}},
|
||||||
|
{app_name, ".*", {p4, "//depot/subdir/app_dir"}}]}
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% Added because of trans deps,
|
%% Added because of trans deps,
|
||||||
|
@ -507,6 +508,40 @@ use_source(Config, Dep, Count) ->
|
||||||
use_source(Config, Dep#dep { dir = TargetDir }, Count-1)
|
use_source(Config, Dep#dep { dir = TargetDir }, Count-1)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-record(p4_settings, {
|
||||||
|
client=undefined,
|
||||||
|
transport="tcp4:perforce:1666",
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}).
|
||||||
|
init_p4_settings(Basename) ->
|
||||||
|
#p4_settings{client =
|
||||||
|
case inet:gethostname() of
|
||||||
|
{ok,HostName} ->
|
||||||
|
HostName ++ "-"
|
||||||
|
++ os:getenv("USER") ++ "-"
|
||||||
|
++ Basename
|
||||||
|
++ "-Rebar-automated-download"
|
||||||
|
end}.
|
||||||
|
|
||||||
|
download_source(AppDir, {p4, Url}) ->
|
||||||
|
download_source(AppDir, {p4, Url, "#head"});
|
||||||
|
download_source(AppDir, {p4, Url, Rev}) ->
|
||||||
|
download_source(AppDir, {p4, Url, Rev, init_p4_settings(filename:basename(AppDir))});
|
||||||
|
download_source(AppDir, {p4, Url, _Rev, Settings}) ->
|
||||||
|
ok = filelib:ensure_dir(AppDir),
|
||||||
|
rebar_utils:sh_send("p4 client -i",
|
||||||
|
?FMT("Client: ~s~n"
|
||||||
|
++"Description: generated by Rebar~n"
|
||||||
|
++"Root: ~s~n"
|
||||||
|
++"View:~n"
|
||||||
|
++" ~s/... //~s/...~n",
|
||||||
|
[Settings#p4_settings.client,
|
||||||
|
AppDir,
|
||||||
|
Url,
|
||||||
|
Settings#p4_settings.client]),
|
||||||
|
[]),
|
||||||
|
rebar_utils:sh(?FMT("p4 -c ~s sync -f", [Settings#p4_settings.client]), []);
|
||||||
download_source(AppDir, {hg, Url, Rev}) ->
|
download_source(AppDir, {hg, Url, Rev}) ->
|
||||||
ok = filelib:ensure_dir(AppDir),
|
ok = filelib:ensure_dir(AppDir),
|
||||||
rebar_utils:sh(?FMT("hg clone -U ~s ~s", [Url, filename:basename(AppDir)]),
|
rebar_utils:sh(?FMT("hg clone -U ~s ~s", [Url, filename:basename(AppDir)]),
|
||||||
|
@ -573,6 +608,8 @@ update_source(Config, Dep) ->
|
||||||
Dep
|
Dep
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
update_source1(AppDir, Args) when element(1, Args) =:= p4 ->
|
||||||
|
download_source(AppDir, Args);
|
||||||
update_source1(AppDir, {git, Url}) ->
|
update_source1(AppDir, {git, Url}) ->
|
||||||
update_source1(AppDir, {git, Url, {branch, "HEAD"}});
|
update_source1(AppDir, {git, Url, {branch, "HEAD"}});
|
||||||
update_source1(AppDir, {git, Url, ""}) ->
|
update_source1(AppDir, {git, Url, ""}) ->
|
||||||
|
@ -696,7 +733,7 @@ source_engine_avail(Source) ->
|
||||||
|
|
||||||
source_engine_avail(Name, Source)
|
source_engine_avail(Name, Source)
|
||||||
when Name == hg; Name == git; Name == svn; Name == bzr; Name == rsync;
|
when Name == hg; Name == git; Name == svn; Name == bzr; Name == rsync;
|
||||||
Name == fossil ->
|
Name == fossil; Name == p4 ->
|
||||||
case vcs_client_vsn(Name) >= required_vcs_client_vsn(Name) of
|
case vcs_client_vsn(Name) >= required_vcs_client_vsn(Name) of
|
||||||
true ->
|
true ->
|
||||||
true;
|
true;
|
||||||
|
@ -717,6 +754,7 @@ vcs_client_vsn(Path, VsnArg, VsnRegex) ->
|
||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
required_vcs_client_vsn(p4) -> {2013, 1};
|
||||||
required_vcs_client_vsn(hg) -> {1, 1};
|
required_vcs_client_vsn(hg) -> {1, 1};
|
||||||
required_vcs_client_vsn(git) -> {1, 5};
|
required_vcs_client_vsn(git) -> {1, 5};
|
||||||
required_vcs_client_vsn(bzr) -> {2, 0};
|
required_vcs_client_vsn(bzr) -> {2, 0};
|
||||||
|
@ -724,6 +762,9 @@ required_vcs_client_vsn(svn) -> {1, 6};
|
||||||
required_vcs_client_vsn(rsync) -> {2, 0};
|
required_vcs_client_vsn(rsync) -> {2, 0};
|
||||||
required_vcs_client_vsn(fossil) -> {1, 0}.
|
required_vcs_client_vsn(fossil) -> {1, 0}.
|
||||||
|
|
||||||
|
vcs_client_vsn(p4) ->
|
||||||
|
vcs_client_vsn(rebar_utils:find_executable("p4"), " -V",
|
||||||
|
"Rev\\. .*/(\\d+)\\.(\\d)/");
|
||||||
vcs_client_vsn(hg) ->
|
vcs_client_vsn(hg) ->
|
||||||
vcs_client_vsn(rebar_utils:find_executable("hg"), " --version",
|
vcs_client_vsn(rebar_utils:find_executable("hg"), " --version",
|
||||||
"version (\\d+).(\\d+)");
|
"version (\\d+).(\\d+)");
|
||||||
|
@ -743,6 +784,8 @@ vcs_client_vsn(fossil) ->
|
||||||
vcs_client_vsn(rebar_utils:find_executable("fossil"), " version",
|
vcs_client_vsn(rebar_utils:find_executable("fossil"), " version",
|
||||||
"version (\\d+).(\\d+)").
|
"version (\\d+).(\\d+)").
|
||||||
|
|
||||||
|
has_vcs_dir(p4, _) ->
|
||||||
|
true;
|
||||||
has_vcs_dir(git, Dir) ->
|
has_vcs_dir(git, Dir) ->
|
||||||
filelib:is_dir(filename:join(Dir, ".git"));
|
filelib:is_dir(filename:join(Dir, ".git"));
|
||||||
has_vcs_dir(hg, Dir) ->
|
has_vcs_dir(hg, Dir) ->
|
||||||
|
@ -760,6 +803,8 @@ has_vcs_dir(_, _) ->
|
||||||
print_source(#dep{app=App, source=Source}) ->
|
print_source(#dep{app=App, source=Source}) ->
|
||||||
?CONSOLE("~s~n", [format_source(App, Source)]).
|
?CONSOLE("~s~n", [format_source(App, Source)]).
|
||||||
|
|
||||||
|
format_source(App, {p4, Url}) ->
|
||||||
|
format_source(App, {p4, Url, "#head"});
|
||||||
format_source(App, {git, Url}) ->
|
format_source(App, {git, Url}) ->
|
||||||
?FMT("~p BRANCH ~s ~s", [App, "HEAD", Url]);
|
?FMT("~p BRANCH ~s ~s", [App, "HEAD", Url]);
|
||||||
format_source(App, {git, Url, ""}) ->
|
format_source(App, {git, Url, ""}) ->
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
get_arch/0,
|
get_arch/0,
|
||||||
wordsize/0,
|
wordsize/0,
|
||||||
sh/2,
|
sh/2,
|
||||||
|
sh_send/3,
|
||||||
find_files/2, find_files/3,
|
find_files/2, find_files/3,
|
||||||
now_str/0,
|
now_str/0,
|
||||||
ensure_dir/1,
|
ensure_dir/1,
|
||||||
|
@ -87,6 +88,24 @@ wordsize() ->
|
||||||
integer_to_list(8 * erlang:system_info(wordsize))
|
integer_to_list(8 * erlang:system_info(wordsize))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
sh_send(Command0, String, Options0) ->
|
||||||
|
?INFO("sh_send info:\n\tcwd: ~p\n\tcmd: ~s < ~s\n", [get_cwd(), Command0, String]),
|
||||||
|
?DEBUG("\topts: ~p\n", [Options0]),
|
||||||
|
|
||||||
|
DefaultOptions = [use_stdout, abort_on_error],
|
||||||
|
Options = [expand_sh_flag(V)
|
||||||
|
|| V <- proplists:compact(Options0 ++ DefaultOptions)],
|
||||||
|
|
||||||
|
Command = patch_on_windows(Command0, proplists:get_value(env, Options, [])),
|
||||||
|
PortSettings = proplists:get_all_values(port_settings, Options) ++
|
||||||
|
[exit_status, {line, 16384}, use_stdio, stderr_to_stdout, hide],
|
||||||
|
Port = open_port({spawn, Command}, PortSettings),
|
||||||
|
|
||||||
|
%% allow us to send some data to the shell command's STDIN
|
||||||
|
%% Erlang doesn't let us get any reply after sending an EOF, though...
|
||||||
|
Port ! {self(), {command, String}},
|
||||||
|
port_close(Port).
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Options = [Option] -- defaults to [use_stdout, abort_on_error]
|
%% Options = [Option] -- defaults to [use_stdout, abort_on_error]
|
||||||
%% Option = ErrorOption | OutputOption | {cd, string()} | {env, Env}
|
%% Option = ErrorOption | OutputOption | {cd, string()} | {env, Env}
|
||||||
|
@ -478,6 +497,7 @@ vcs_vsn_1(Vcs, Dir) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
vcs_vsn_cmd(git) -> "git describe --always --tags";
|
vcs_vsn_cmd(git) -> "git describe --always --tags";
|
||||||
|
vcs_vsn_cmd(p4) -> "echo #head";
|
||||||
vcs_vsn_cmd(hg) -> "hg identify -i";
|
vcs_vsn_cmd(hg) -> "hg identify -i";
|
||||||
vcs_vsn_cmd(bzr) -> "bzr revno";
|
vcs_vsn_cmd(bzr) -> "bzr revno";
|
||||||
vcs_vsn_cmd(svn) -> "svnversion";
|
vcs_vsn_cmd(svn) -> "svnversion";
|
||||||
|
|
Loading…
Reference in a new issue