You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/02/03 13:59:42 UTC
[03/27] Build with rebar
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_protobuffs_compiler.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_protobuffs_compiler.erl b/src/rebar/src/rebar_protobuffs_compiler.erl
deleted file mode 100644
index 579ecfb..0000000
--- a/src/rebar/src/rebar_protobuffs_compiler.erl
+++ /dev/null
@@ -1,153 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_protobuffs_compiler).
-
--export([compile/2,
- clean/2]).
-
-%% for internal use only
--export([info/2]).
-
--include("rebar.hrl").
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-compile(Config, _AppFile) ->
- case rebar_utils:find_files("src", ".*\\.proto$") of
- [] ->
- ok;
- FoundFiles ->
- %% Check for protobuffs library -- if it's not present, fail
- %% since we have.proto files that need building
- case protobuffs_is_present() of
- true ->
- %% Build a list of output files - { Proto, Beam, Hrl }
- Targets = [{Proto, beam_file(Proto), hrl_file(Proto)} ||
- Proto <- FoundFiles],
-
- %% Compile each proto file
- compile_each(Config, Targets);
- false ->
- ?ERROR("Protobuffs library not present in code path!\n",
- []),
- ?FAIL
- end
- end.
-
-clean(_Config, _AppFile) ->
- %% Get a list of generated .beam and .hrl files and then delete them
- Protos = rebar_utils:find_files("src", ".*\\.proto$"),
- BeamFiles = [fq_beam_file(F) || F <- Protos],
- HrlFiles = [fq_hrl_file(F) || F <- Protos],
- Targets = BeamFiles ++ HrlFiles,
- case Targets of
- [] ->
- ok;
- _ ->
- delete_each(Targets)
- end.
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-info(help, compile) ->
- info_help("Build Protobuffs (*.proto) sources");
-info(help, clean) ->
- info_help("Delete Protobuffs (*.proto) build results").
-
-info_help(Description) ->
- ?CONSOLE(
- "~s.~n"
- "~n"
- "Valid rebar.config options:~n"
- " erl_opts is passed as compile_flags to "
- "protobuffs_compile:scan_file/2~n",
- [Description]).
-
-protobuffs_is_present() ->
- code:which(protobuffs_compile) =/= non_existing.
-
-beam_file(Proto) ->
- filename:basename(Proto, ".proto") ++ "_pb.beam".
-
-hrl_file(Proto) ->
- filename:basename(Proto, ".proto") ++ "_pb.hrl".
-
-fq_beam_file(Proto) ->
- filename:join(["ebin", filename:basename(Proto, ".proto") ++ "_pb.beam"]).
-
-fq_hrl_file(Proto) ->
- filename:join(["include", filename:basename(Proto, ".proto") ++ "_pb.hrl"]).
-
-needs_compile(Proto, Beam) ->
- ActualBeam = filename:join(["ebin", filename:basename(Beam)]),
- filelib:last_modified(ActualBeam) < filelib:last_modified(Proto).
-
-compile_each(_, []) ->
- ok;
-compile_each(Config, [{Proto, Beam, Hrl} | Rest]) ->
- case needs_compile(Proto, Beam) of
- true ->
- ?CONSOLE("Compiling ~s\n", [Proto]),
- ErlOpts = rebar_utils:erl_opts(Config),
- case protobuffs_compile:scan_file(Proto,
- [{compile_flags,ErlOpts}]) of
- ok ->
- %% Compilation worked, but we need to move the
- %% beam and .hrl file into the ebin/ and include/
- %% directories respectively
- %% TODO: Protobuffs really needs to be better about this
- ok = filelib:ensure_dir(filename:join("ebin","dummy")),
- ok = rebar_file_utils:mv(Beam, "ebin"),
- ok = filelib:ensure_dir(filename:join("include", Hrl)),
- ok = rebar_file_utils:mv(Hrl, "include"),
- ok;
- Other ->
- ?ERROR("Protobuffs compile of ~s failed: ~p\n",
- [Proto, Other]),
- ?FAIL
- end;
- false ->
- ok
- end,
- compile_each(Config, Rest).
-
-delete_each([]) ->
- ok;
-delete_each([File | Rest]) ->
- case file:delete(File) of
- ok ->
- ok;
- {error, enoent} ->
- ok;
- {error, Reason} ->
- ?ERROR("Failed to delete ~s: ~p\n", [File, Reason])
- end,
- delete_each(Rest).
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_qc.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_qc.erl b/src/rebar/src/rebar_qc.erl
deleted file mode 100644
index 53a6f52..0000000
--- a/src/rebar/src/rebar_qc.erl
+++ /dev/null
@@ -1,187 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2011-2012 Tuncer Ayaz
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_qc).
-
--export([qc/2, triq/2, eqc/2, clean/2]).
-
-%% for internal use only
--export([info/2]).
-
--include("rebar.hrl").
-
--define(QC_DIR, ".qc").
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-qc(Config, _AppFile) ->
- ?CONSOLE("NOTICE: Using experimental 'qc' command~n", []),
- run_qc(Config, qc_opts(Config)).
-
-triq(Config, _AppFile) ->
- ?CONSOLE("NOTICE: Using experimental 'triq' command~n", []),
- ok = load_qc_mod(triq),
- run_qc(Config, qc_opts(Config), triq).
-
-eqc(Config, _AppFile) ->
- ?CONSOLE("NOTICE: Using experimental 'eqc' command~n", []),
- ok = load_qc_mod(eqc),
- run_qc(Config, qc_opts(Config), eqc).
-
-clean(_Config, _File) ->
- rebar_file_utils:rm_rf(?QC_DIR).
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-info(help, qc) ->
- ?CONSOLE(
- "Test QuickCheck properties.~n"
- "~n"
- "Valid rebar.config options:~n"
- " {qc_opts, [{qc_mod, module()}, Options]}~n"
- " ~p~n"
- " ~p~n",
- [
- {qc_compile_opts, []},
- {qc_first_files, []}
- ]).
-
--define(TRIQ_MOD, triq).
--define(EQC_MOD, eqc).
-
-qc_opts(Config) ->
- rebar_config:get(Config, qc_opts, []).
-
-run_qc(Config, QCOpts) ->
- run_qc(Config, QCOpts, select_qc_mod(QCOpts)).
-
-run_qc(Config, RawQCOpts, QC) ->
- ?DEBUG("Selected QC module: ~p~n", [QC]),
- QCOpts = lists:filter(fun({qc_mod, _}) -> false;
- (_) -> true
- end, RawQCOpts),
- run(Config, QC, QCOpts).
-
-select_qc_mod(QCOpts) ->
- case proplists:get_value(qc_mod, QCOpts) of
- undefined ->
- detect_qc_mod();
- QC ->
- case code:ensure_loaded(QC) of
- {module, QC} ->
- QC;
- {error, nofile} ->
- ?ABORT("Configured QC library '~p' not available~n", [QC])
- end
- end.
-
-detect_qc_mod() ->
- case code:ensure_loaded(?TRIQ_MOD) of
- {module, ?TRIQ_MOD} ->
- ?TRIQ_MOD;
- {error, nofile} ->
- case code:ensure_loaded(?EQC_MOD) of
- {module, ?EQC_MOD} ->
- ?EQC_MOD;
- {error, nofile} ->
- ?ABORT("No QC library available~n", [])
- end
- end.
-
-load_qc_mod(Mod) ->
- case code:ensure_loaded(Mod) of
- {module, Mod} ->
- ok;
- {error, nofile} ->
- ?ABORT("Failed to load QC lib '~p'~n", [Mod])
- end.
-
-ensure_dirs() ->
- ok = filelib:ensure_dir(filename:join(qc_dir(), "dummy")),
- ok = filelib:ensure_dir(filename:join(rebar_utils:ebin_dir(), "dummy")).
-
-setup_codepath() ->
- CodePath = code:get_path(),
- true = code:add_patha(qc_dir()),
- true = code:add_pathz(rebar_utils:ebin_dir()),
- CodePath.
-
-qc_dir() ->
- filename:join(rebar_utils:get_cwd(), ?QC_DIR).
-
-run(Config, QC, QCOpts) ->
- ?DEBUG("qc_opts: ~p~n", [QCOpts]),
-
- ok = ensure_dirs(),
- CodePath = setup_codepath(),
-
- CompileOnly = rebar_utils:get_experimental_global(Config, compile_only,
- false),
- %% Compile erlang code to ?QC_DIR, using a tweaked config
- %% with appropriate defines, and include all the test modules
- %% as well.
- {ok, _SrcErls} = rebar_erlc_compiler:test_compile(Config, "qc", ?QC_DIR),
-
- case CompileOnly of
- "true" ->
- true = code:set_path(CodePath),
- ?CONSOLE("Compiled modules for qc~n", []);
- false ->
- run1(QC, QCOpts, CodePath)
- end.
-
-run1(QC, QCOpts, CodePath) ->
- TestModule = fun(M) -> qc_module(QC, QCOpts, M) end,
- case lists:flatmap(TestModule, find_prop_mods()) of
- [] ->
- true = code:set_path(CodePath),
- ok;
- Errors ->
- ?ABORT("One or more QC properties didn't hold true:~n~p~n",
- [Errors])
- end.
-
-qc_module(QC=triq, _QCOpts, M) ->
- case QC:module(M) of
- true ->
- [];
- Failed ->
- [Failed]
- end;
-qc_module(QC=eqc, [], M) -> QC:module(M);
-qc_module(QC=eqc, QCOpts, M) -> QC:module(QCOpts, M).
-
-find_prop_mods() ->
- Beams = rebar_utils:find_files(?QC_DIR, ".*\\.beam\$"),
- [M || M <- [rebar_utils:erl_to_mod(Beam) || Beam <- Beams], has_prop(M)].
-
-has_prop(Mod) ->
- lists:any(fun({F,_A}) -> lists:prefix("prop_", atom_to_list(F)) end,
- Mod:module_info(exports)).
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_rel_utils.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_rel_utils.erl b/src/rebar/src/rebar_rel_utils.erl
deleted file mode 100644
index 085dbd9..0000000
--- a/src/rebar/src/rebar_rel_utils.erl
+++ /dev/null
@@ -1,238 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_rel_utils).
-
--export([is_rel_dir/0,
- is_rel_dir/1,
- get_reltool_release_info/1,
- get_rel_release_info/1,
- get_rel_release_info/2,
- get_rel_apps/1,
- get_rel_apps/2,
- get_previous_release_path/1,
- get_rel_file_path/2,
- load_config/2,
- get_sys_tuple/1,
- get_target_dir/2,
- get_root_dir/2,
- get_target_parent_dir/2]).
-
--include("rebar.hrl").
-
-is_rel_dir() ->
- is_rel_dir(rebar_utils:get_cwd()).
-
-is_rel_dir(Dir) ->
- Fname = filename:join([Dir, "reltool.config"]),
- Scriptname = Fname ++ ".script",
- Res = case filelib:is_regular(Scriptname) of
- true ->
- {true, Scriptname};
- false ->
- case filelib:is_regular(Fname) of
- true ->
- {true, Fname};
- false ->
- false
- end
- end,
- ?DEBUG("is_rel_dir(~s) -> ~p~n", [Dir, Res]),
- Res.
-
-%% Get release name and version from a reltool.config
-get_reltool_release_info([{sys, Config}| _]) ->
- {rel, Name, Ver, _} = proplists:lookup(rel, Config),
- {Name, Ver};
-get_reltool_release_info(ReltoolFile) when is_list(ReltoolFile) ->
- case file:consult(ReltoolFile) of
- {ok, ReltoolConfig} ->
- get_reltool_release_info(ReltoolConfig);
- _ ->
- ?ABORT("Failed to parse ~s~n", [ReltoolFile])
- end.
-
-%% Get release name and version from a rel file
-get_rel_release_info(RelFile) ->
- case file:consult(RelFile) of
- {ok, [{release, {Name, Ver}, _, _}]} ->
- {Name, Ver};
- _ ->
- ?ABORT("Failed to parse ~s~n", [RelFile])
- end.
-
-%% Get release name and version from a name and a path
-get_rel_release_info(Name, Path) ->
- RelPath = get_rel_file_path(Name, Path),
- get_rel_release_info(RelPath).
-
-%% Get list of apps included in a release from a rel file
-get_rel_apps(RelFile) ->
- case file:consult(RelFile) of
- {ok, [{release, _, _, Apps}]} ->
- make_proplist(Apps, []);
- _ ->
- ?ABORT("Failed to parse ~s~n", [RelFile])
- end.
-
-%% Get list of apps included in a release from a name and a path
-get_rel_apps(Name, Path) ->
- RelPath = get_rel_file_path(Name, Path),
- get_rel_apps(RelPath).
-
-%% Get rel file path from name and path
-get_rel_file_path(Name, Path) ->
- [RelFile] = filelib:wildcard(filename:join([Path, "releases", "*",
- Name ++ ".rel"])),
- RelFile.
-
-%% Get the previous release path from a global variable
-get_previous_release_path(Config) ->
- case rebar_config:get_global(Config, previous_release, false) of
- false ->
- ?ABORT("previous_release=PATH is required to "
- "create upgrade package~n", []);
- OldVerPath ->
- OldVerPath
- end.
-
-%%
-%% Load terms from reltool.config
-%%
-load_config(Config, ReltoolFile) ->
- case rebar_config:consult_file(ReltoolFile) of
- {ok, Terms} ->
- expand_version(Config, Terms, filename:dirname(ReltoolFile));
- Other ->
- ?ABORT("Failed to load expected config from ~s: ~p\n",
- [ReltoolFile, Other])
- end.
-
-%%
-%% Look for the {sys, [...]} tuple in the reltool.config file.
-%% Without this present, we can't run reltool.
-%%
-get_sys_tuple(ReltoolConfig) ->
- case lists:keyfind(sys, 1, ReltoolConfig) of
- {sys, _} = SysTuple ->
- SysTuple;
- false ->
- ?ABORT("Failed to find {sys, [...]} tuple in reltool.config.", [])
- end.
-
-%%
-%% Look for {target_dir, TargetDir} in the reltool config file; if none is
-%% found, use the name of the release as the default target directory.
-%%
-get_target_dir(Config, ReltoolConfig) ->
- case rebar_config:get_global(Config, target_dir, undefined) of
- undefined ->
- case lists:keyfind(target_dir, 1, ReltoolConfig) of
- {target_dir, TargetDir} ->
- filename:absname(TargetDir);
- false ->
- {sys, SysInfo} = get_sys_tuple(ReltoolConfig),
- case lists:keyfind(rel, 1, SysInfo) of
- {rel, Name, _Vsn, _Apps} ->
- filename:absname(Name);
- false ->
- filename:absname("target")
- end
- end;
- TargetDir ->
- filename:absname(TargetDir)
- end.
-
-get_target_parent_dir(Config, ReltoolConfig) ->
- TargetDir = get_target_dir(Config, ReltoolConfig),
- case lists:reverse(tl(lists:reverse(filename:split(TargetDir)))) of
- [] -> ".";
- Components -> filename:join(Components)
- end.
-
-%%
-%% Look for root_dir in sys tuple and command line; fall back to
-%% code:root_dir().
-%%
-get_root_dir(Config, ReltoolConfig) ->
- {sys, SysInfo} = get_sys_tuple(ReltoolConfig),
- SysRootDirTuple = lists:keyfind(root_dir, 1, SysInfo),
- CmdRootDir = rebar_config:get_global(Config, root_dir, undefined),
- case {SysRootDirTuple, CmdRootDir} of
- %% root_dir in sys typle and no root_dir on cmd-line
- {{root_dir, SysRootDir}, undefined} ->
- SysRootDir;
- %% root_dir in sys typle and also root_dir on cmd-line
- {{root_dir, SysRootDir}, CmdRootDir} when CmdRootDir =/= undefined ->
- case string:equal(SysRootDir, CmdRootDir) of
- true ->
- ok;
- false ->
- ?WARN("overriding reltool.config root_dir with "
- "different command line root_dir~n", [])
- end,
- CmdRootDir;
- %% no root_dir in sys typle and no root_dir on cmd-line
- {false, undefined} ->
- code:root_dir();
- %% no root_dir in sys tuple but root_dir on cmd-line
- {false, CmdRootDir} when CmdRootDir =/= undefined ->
- CmdRootDir
- end.
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-make_proplist([{_,_}=H|T], Acc) ->
- make_proplist(T, [H|Acc]);
-make_proplist([H|T], Acc) ->
- App = element(1, H),
- Ver = element(2, H),
- make_proplist(T, [{App,Ver}|Acc]);
-make_proplist([], Acc) ->
- Acc.
-
-expand_version(Config, ReltoolConfig, Dir) ->
- case lists:keyfind(sys, 1, ReltoolConfig) of
- {sys, Sys} ->
- {Config1, Rels} =
- lists:foldl(
- fun(Term, {C, R}) ->
- {C1, Rel} = expand_rel_version(C, Term, Dir),
- {C1, [Rel|R]}
- end, {Config, []}, Sys),
- ExpandedSys = {sys, lists:reverse(Rels)},
- {Config1, lists:keyreplace(sys, 1, ReltoolConfig, ExpandedSys)};
- _ ->
- {Config, ReltoolConfig}
- end.
-
-expand_rel_version(Config, {rel, Name, Version, Apps}, Dir) ->
- {NewConfig, VsnString} = rebar_utils:vcs_vsn(Config, Version, Dir),
- {NewConfig, {rel, Name, VsnString, Apps}};
-expand_rel_version(Config, Other, _Dir) ->
- {Config, Other}.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_reltool.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_reltool.erl b/src/rebar/src/rebar_reltool.erl
deleted file mode 100644
index 9f9488e..0000000
--- a/src/rebar/src/rebar_reltool.erl
+++ /dev/null
@@ -1,408 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_reltool).
-
--export([generate/2,
- overlay/2,
- clean/2]).
-
-%% for internal use only
--export([info/2]).
-
--include("rebar.hrl").
--include_lib("kernel/include/file.hrl").
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-generate(Config0, ReltoolFile) ->
- %% Make sure we have decent version of reltool available
- check_vsn(),
-
- %% Load the reltool configuration from the file
- {Config, ReltoolConfig} = rebar_rel_utils:load_config(Config0, ReltoolFile),
-
- Sys = rebar_rel_utils:get_sys_tuple(ReltoolConfig),
-
- %% Spin up reltool server and load our config into it
- {ok, Server} = reltool:start_server([Sys]),
-
- %% Do some validation of the reltool configuration; error messages out of
- %% reltool are still pretty cryptic
- validate_rel_apps(Server, Sys),
-
- %% Finally, run reltool
- case catch(run_reltool(Server, Config, ReltoolConfig)) of
- ok ->
- {ok, Config};
- {error, failed} ->
- ?FAIL;
- Other2 ->
- ?ERROR("Unexpected error: ~p\n", [Other2]),
- ?FAIL
- end.
-
-overlay(Config, ReltoolFile) ->
- %% Load the reltool configuration from the file
- {Config1, ReltoolConfig} = rebar_rel_utils:load_config(Config, ReltoolFile),
- {process_overlay(Config, ReltoolConfig), Config1}.
-
-clean(Config, ReltoolFile) ->
- {Config1, ReltoolConfig} = rebar_rel_utils:load_config(Config, ReltoolFile),
- TargetDir = rebar_rel_utils:get_target_dir(Config, ReltoolConfig),
- rebar_file_utils:rm_rf(TargetDir),
- rebar_file_utils:delete_each(["reltool.spec"]),
- {ok, Config1}.
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-info(help, generate) ->
- info_help("Build release with reltool");
-info(help, clean) ->
- info_help("Delete release");
-info(help, overlay) ->
- info_help("Run reltool overlays only").
-
-info_help(Description) ->
- ?CONSOLE(
- "~s.~n"
- "~n"
- "Valid rebar.config options:~n"
- " ~n"
- "Valid reltool.config options:~n"
- " {sys, []}~n"
- " {target_dir, \"target\"}~n"
- " {overlay_vars, \"overlay\"}~n"
- " {overlay, []}~n"
- "Valid command line options:~n"
- " target_dir=target~n"
- " overlay_vars=VarsFile~n"
- " dump_spec=1 (write reltool target spec to reltool.spec)~n",
- [
- Description
- ]).
-
-check_vsn() ->
- %% TODO: use application:load and application:get_key once we require
- %% R14A or newer. There's no reltool.app before R14A.
- case code:lib_dir(reltool) of
- {error, bad_name} ->
- ?ABORT("Reltool support requires the reltool application "
- "to be installed!", []);
- Path ->
- ReltoolVsn = filename:basename(Path),
- case ReltoolVsn < "reltool-0.5.2" of
- true ->
- ?ABORT("Reltool support requires at least reltool-0.5.2; "
- "this VM is using ~s\n", [ReltoolVsn]);
- false ->
- ok
- end
- end.
-
-process_overlay(Config, ReltoolConfig) ->
- TargetDir = rebar_rel_utils:get_target_dir(Config, ReltoolConfig),
-
- {_BootRelName, BootRelVsn} =
- rebar_rel_utils:get_reltool_release_info(ReltoolConfig),
-
- %% Initialize overlay vars with some basics
- %% (that can get overwritten)
- OverlayVars0 =
- dict:from_list([{erts_vsn, "erts-" ++ erlang:system_info(version)},
- {rel_vsn, BootRelVsn},
- {target_dir, TargetDir},
- {hostname, net_adm:localhost()}]),
-
- %% Load up any variables specified by overlay_vars
- OverlayVars1 = overlay_vars(Config, OverlayVars0, ReltoolConfig),
- OverlayVars = rebar_templater:resolve_variables(dict:to_list(OverlayVars1),
- OverlayVars1),
-
- %% Finally, overlay the files specified by the overlay section
- case lists:keyfind(overlay, 1, ReltoolConfig) of
- {overlay, Overlay} when is_list(Overlay) ->
- execute_overlay(Overlay, OverlayVars, rebar_utils:get_cwd(),
- TargetDir);
- false ->
- ?INFO("No {overlay, [...]} found in reltool.config.\n", []);
- _ ->
- ?ABORT("{overlay, [...]} entry in reltool.config "
- "must be a list.\n", [])
- end.
-
-%%
-%% Look for overlay_vars file reference. If the user provides an overlay_vars on
-%% the command line (i.e. a global), the terms from that file OVERRIDE the one
-%% listed in reltool.config. To re-iterate, this means you can specify a
-%% variable in the file from reltool.config and then override that value by
-%% providing an additional file on the command-line.
-%%
-overlay_vars(Config, Vars0, ReltoolConfig) ->
- BaseVars = load_vars_file([proplists:get_value(overlay_vars, ReltoolConfig)]),
- OverlayVars = rebar_config:get_global(Config, overlay_vars, []),
- OverrideVars = load_vars_file(string:tokens(OverlayVars, ",")),
- M = fun merge_overlay_var/3,
- dict:merge(M, dict:merge(M, Vars0, BaseVars), OverrideVars).
-
-merge_overlay_var(_Key, _Base, Override) -> Override.
-
-%%
-%% If a filename is provided, construct a dict of terms
-%%
-load_vars_file([undefined]) ->
- dict:new();
-load_vars_file([]) ->
- dict:new();
-load_vars_file(Files) ->
- load_vars_file(Files, dict:new()).
-
-load_vars_file([], Dict) ->
- Dict;
-load_vars_file([File | Files], BaseVars) ->
- case rebar_config:consult_file(File) of
- {ok, Terms} ->
- OverrideVars = dict:from_list(Terms),
- M = fun merge_overlay_var/3,
- load_vars_file(Files, dict:merge(M, BaseVars, OverrideVars));
- {error, Reason} ->
- ?ABORT("Unable to load overlay_vars from ~p: ~p\n", [File, Reason])
- end.
-
-validate_rel_apps(ReltoolServer, {sys, ReltoolConfig}) ->
- case lists:keyfind(rel, 1, ReltoolConfig) of
- false ->
- ok;
- {rel, _Name, _Vsn, Apps} ->
- %% Identify all the apps that do NOT exist, based on
- %% what's available from the reltool server
- Missing = lists:sort(
- [App || App <- Apps,
- app_exists(App, ReltoolServer) == false]),
- case Missing of
- [] ->
- ok;
- _ ->
- ?ABORT("Apps in {rel, ...} section not found by "
- "reltool: ~p\n", [Missing])
- end;
- Rel ->
- %% Invalid release format!
- ?ABORT("Invalid {rel, ...} section in reltools.config: ~p\n", [Rel])
- end.
-
-app_exists(App, Server) when is_atom(App) ->
- case reltool_server:get_app(Server, App) of
- {ok, _} ->
- true;
- _ ->
- false
- end;
-app_exists(AppTuple, Server) when is_tuple(AppTuple) ->
- app_exists(element(1, AppTuple), Server).
-
-run_reltool(Server, Config, ReltoolConfig) ->
- case reltool:get_target_spec(Server) of
- {ok, Spec} ->
- %% Pull the target dir and make sure it exists
- TargetDir = rebar_rel_utils:get_target_dir(Config, ReltoolConfig),
- mk_target_dir(Config, TargetDir),
-
- %% Determine the otp root dir to use
- RootDir = rebar_rel_utils:get_root_dir(Config, ReltoolConfig),
-
- %% Dump the spec, if necessary
- dump_spec(Config, Spec),
-
- %% Have reltool actually run
- case reltool:eval_target_spec(Spec, RootDir, TargetDir) of
- ok ->
- ok;
- {error, Reason} ->
- ?ABORT("Failed to generate target from spec: ~p\n",
- [Reason])
- end,
-
- {BootRelName, BootRelVsn} =
- rebar_rel_utils:get_reltool_release_info(ReltoolConfig),
-
- ok = create_RELEASES(TargetDir, BootRelName, BootRelVsn),
-
- process_overlay(Config, ReltoolConfig);
-
- {error, Reason} ->
- ?ABORT("Unable to generate spec: ~s\n", [Reason])
- end.
-
-mk_target_dir(Config, TargetDir) ->
- case filelib:ensure_dir(filename:join(TargetDir, "dummy")) of
- ok ->
- ok;
- {error, eexist} ->
- %% Output directory already exists; if force=1, wipe it out
- case rebar_config:get_global(Config, force, "0") of
- "1" ->
- rebar_file_utils:rm_rf(TargetDir),
- ok = file:make_dir(TargetDir);
- _ ->
- ?ERROR("Release target directory ~p already exists!\n",
- [TargetDir]),
- ?FAIL
- end;
- {error, Reason} ->
- ?ERROR("Failed to make target dir ~p: ~s\n",
- [TargetDir, file:format_error(Reason)]),
- ?FAIL
- end.
-
-dump_spec(Config, Spec) ->
- case rebar_config:get_global(Config, dump_spec, "0") of
- "1" ->
- SpecBin = list_to_binary(io_lib:print(Spec, 1, 120, -1)),
- ok = file:write_file("reltool.spec", SpecBin);
- _ ->
- ok
- end.
-
-
-%% TODO: Merge functionality here with rebar_templater
-
-execute_overlay([], _Vars, _BaseDir, _TargetDir) ->
- ok;
-execute_overlay([{mkdir, Out} | Rest], Vars, BaseDir, TargetDir) ->
- OutFile = rebar_templater:render(
- filename:join([TargetDir, Out, "dummy"]), Vars),
- ok = filelib:ensure_dir(OutFile),
- ?DEBUG("Created dir ~s\n", [filename:dirname(OutFile)]),
- execute_overlay(Rest, Vars, BaseDir, TargetDir);
-execute_overlay([{copy, In} | Rest], _Vars, BaseDir, TargetDir) ->
- execute_overlay([{copy, In, ""} | Rest], _Vars, BaseDir, TargetDir);
-execute_overlay([{copy, In, Out} | Rest], Vars, BaseDir, TargetDir) ->
- InFile = rebar_templater:render(filename:join(BaseDir, In), Vars),
- OutFile = rebar_templater:render(filename:join(TargetDir, Out), Vars),
- case filelib:is_dir(InFile) of
- true ->
- ok;
- false ->
- ok = filelib:ensure_dir(OutFile)
- end,
- rebar_file_utils:cp_r([InFile], OutFile),
- execute_overlay(Rest, Vars, BaseDir, TargetDir);
-execute_overlay([{template_wildcard, Wildcard, OutDir} | Rest], Vars,
- BaseDir, TargetDir) ->
- %% Generate a series of {template, In, Out} instructions from the wildcard
- %% that will get processed per normal
- Ifun = fun(F, Acc0) ->
- [{template, F,
- filename:join(OutDir, filename:basename(F))} | Acc0]
- end,
- NewInstrs = lists:foldl(Ifun, Rest, filelib:wildcard(Wildcard, BaseDir)),
- case length(NewInstrs) =:= length(Rest) of
- true ->
- ?WARN("template_wildcard: ~s did not match any files!\n",
- [Wildcard]);
- false ->
- ok
- end,
- ?DEBUG("template_wildcard: ~s expanded to ~p\n", [Wildcard, NewInstrs]),
- execute_overlay(NewInstrs, Vars, BaseDir, TargetDir);
-execute_overlay([{template, In, Out} | Rest], Vars, BaseDir, TargetDir) ->
- InFile = rebar_templater:render(filename:join(BaseDir, In), Vars),
- {ok, InFileData} = file:read_file(InFile),
- OutFile = rebar_templater:render(filename:join(TargetDir, Out), Vars),
- ok = filelib:ensure_dir(OutFile),
- case file:write_file(OutFile, rebar_templater:render(InFileData, Vars)) of
- ok ->
- ok = apply_file_info(InFile, OutFile),
- ?DEBUG("Templated ~p\n", [OutFile]),
- execute_overlay(Rest, Vars, BaseDir, TargetDir);
- {error, Reason} ->
- ?ABORT("Failed to template ~p: ~p\n", [OutFile, Reason])
- end;
-execute_overlay([{create, Out, Contents} | Rest], Vars, BaseDir, TargetDir) ->
- OutFile = rebar_templater:render(filename:join(TargetDir, Out), Vars),
- ok = filelib:ensure_dir(OutFile),
- case file:write_file(OutFile, Contents) of
- ok ->
- ?DEBUG("Created ~p\n", [OutFile]),
- execute_overlay(Rest, Vars, BaseDir, TargetDir);
- {error, Reason} ->
- ?ABORT("Failed to create ~p: ~p\n", [OutFile, Reason])
- end;
-execute_overlay([{replace, Out, Regex, Replacement} | Rest],
- Vars, BaseDir, TargetDir) ->
- execute_overlay([{replace, Out, Regex, Replacement, []} | Rest],
- Vars, BaseDir, TargetDir);
-execute_overlay([{replace, Out, Regex, Replacement, Opts} | Rest],
- Vars, BaseDir, TargetDir) ->
- Filename = rebar_templater:render(filename:join(TargetDir, Out), Vars),
- {ok, OrigData} = file:read_file(Filename),
- Data = re:replace(OrigData, Regex,
- rebar_templater:render(Replacement, Vars),
- [global, {return, binary}] ++ Opts),
- case file:write_file(Filename, Data) of
- ok ->
- ?DEBUG("Edited ~s: s/~s/~s/\n", [Filename, Regex, Replacement]),
- execute_overlay(Rest, Vars, BaseDir, TargetDir);
- {error, Reason} ->
- ?ABORT("Failed to edit ~p: ~p\n", [Filename, Reason])
- end;
-execute_overlay([Other | _Rest], _Vars, _BaseDir, _TargetDir) ->
- {error, {unsupported_operation, Other}}.
-
-
-apply_file_info(InFile, OutFile) ->
- {ok, FileInfo} = file:read_file_info(InFile),
- ok = file:write_file_info(OutFile, FileInfo).
-
-create_RELEASES(TargetDir, RelName, RelVsn) ->
- ReleasesDir = filename:join(TargetDir, "releases"),
- RelFile = filename:join([ReleasesDir, RelVsn, RelName ++ ".rel"]),
- Apps = rebar_rel_utils:get_rel_apps(RelFile),
- TargetLib = filename:join(TargetDir,"lib"),
-
- AppDirs =
- [ {App, Vsn, TargetLib}
- || {App, Vsn} <- Apps,
- filelib:is_dir(
- filename:join(TargetLib,
- lists:concat([App, "-", Vsn]))) ],
-
- case release_handler:create_RELEASES(
- code:root_dir(),
- ReleasesDir,
- RelFile,
- AppDirs) of
- ok ->
- ok;
- {error, Reason} ->
- ?ABORT("Failed to create RELEASES file: ~p\n",
- [Reason])
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_require_vsn.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_require_vsn.erl b/src/rebar/src/rebar_require_vsn.erl
deleted file mode 100644
index 385f55c..0000000
--- a/src/rebar/src/rebar_require_vsn.erl
+++ /dev/null
@@ -1,121 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%%
-%% -------------------------------------------------------------------
-
--module(rebar_require_vsn).
-
--include("rebar.hrl").
-
--export([compile/2,
- eunit/2]).
-
-%% for internal use only
--export([info/2]).
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-compile(Config, _) ->
- check_versions(Config).
-
-eunit(Config, _) ->
- check_versions(Config).
-
-%% ====================================================================
-%% Internal functions
-%% ====================================================================
-
-info(help, compile) ->
- info_help();
-info(help, eunit) ->
- info_help().
-
-info_help() ->
- ?CONSOLE(
- "Check required ERTS or OTP release version.~n"
- "~n"
- "Valid rebar.config options:~n"
- " ~p~n"
- " ~p~n"
- " ~p~n",
- [
- {require_erts_vsn, ".*"},
- {require_otp_vsn, ".*"},
- {require_min_otp_vsn, ".*"}
- ]).
-
-check_versions(Config) ->
- ErtsRegex = rebar_config:get(Config, require_erts_vsn, ".*"),
- ReOpts = [{capture, none}],
- case re:run(erlang:system_info(version), ErtsRegex, ReOpts) of
- match ->
- ?DEBUG("Matched required ERTS version: ~s -> ~s\n",
- [erlang:system_info(version), ErtsRegex]);
- nomatch ->
- ?ABORT("ERTS version ~s does not match required regex ~s\n",
- [erlang:system_info(version), ErtsRegex])
- end,
-
- OtpRegex = rebar_config:get(Config, require_otp_vsn, ".*"),
- case re:run(erlang:system_info(otp_release), OtpRegex, ReOpts) of
- match ->
- ?DEBUG("Matched required OTP release: ~s -> ~s\n",
- [erlang:system_info(otp_release), OtpRegex]);
- nomatch ->
- ?ABORT("OTP release ~s does not match required regex ~s\n",
- [erlang:system_info(otp_release), OtpRegex])
- end,
-
- case rebar_config:get(Config, require_min_otp_vsn, undefined) of
- undefined -> ?DEBUG("Min OTP version unconfigured~n", []);
- MinOtpVsn ->
- {MinMaj, MinMin} = version_tuple(MinOtpVsn, "configured"),
- {OtpMaj, OtpMin} = version_tuple(erlang:system_info(otp_release),
- "OTP Release"),
- case {OtpMaj, OtpMin} >= {MinMaj, MinMin} of
- true ->
- ?DEBUG("~s satisfies the requirement for vsn ~s~n",
- [erlang:system_info(otp_release),
- MinOtpVsn]);
- false ->
- ?ABORT("OTP release ~s or later is required, you have: ~s~n",
- [MinOtpVsn,
- erlang:system_info(otp_release)])
- end
- end.
-
-version_tuple(OtpRelease, Type) ->
- case re:run(OtpRelease, "R(\\d+)B?-?(\\d+)?", [{capture, all, list}]) of
- {match, [_Full, Maj, Min]} ->
- {list_to_integer(Maj), list_to_integer(Min)};
- {match, [_Full, Maj]} ->
- {list_to_integer(Maj), 0};
- nomatch ->
- ?ABORT("Cannot parse ~s version string: ~s~n",
- [Type, OtpRelease])
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_shell.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_shell.erl b/src/rebar/src/rebar_shell.erl
deleted file mode 100644
index 2dbf4a0..0000000
--- a/src/rebar/src/rebar_shell.erl
+++ /dev/null
@@ -1,56 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2011 Trifork
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
-
--module(rebar_shell).
--author("Kresten Krab Thorup <kr...@trifork.com>").
-
--include("rebar.hrl").
-
--export([shell/2]).
-
-shell(_Config, _AppFile) ->
- ?CONSOLE("NOTICE: Using experimental 'shell' command~n", []),
- %% backwards way to say we only want this executed
- %% for the "top level" directory
- case is_deps_dir(rebar_utils:get_cwd()) of
- false ->
- true = code:add_pathz(rebar_utils:ebin_dir()),
- user_drv:start(),
- %% this call never returns (until user quits shell)
- shell:server(false, false);
- true ->
- ok
- end,
- ok.
-
-is_deps_dir(Dir) ->
- case lists:reverse(filename:split(Dir)) of
- [_, "deps" | _] ->
- true;
- _V ->
- false
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_subdirs.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_subdirs.erl b/src/rebar/src/rebar_subdirs.erl
deleted file mode 100644
index f444a59..0000000
--- a/src/rebar/src/rebar_subdirs.erl
+++ /dev/null
@@ -1,84 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_subdirs).
-
--include("rebar.hrl").
--include_lib("kernel/include/file.hrl").
-
--export([preprocess/2]).
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-preprocess(Config, _) ->
- %% Get the list of subdirs specified in the config (if any).
- Cwd = rebar_utils:get_cwd(),
- ListSubdirs = rebar_config:get_local(Config, sub_dirs, []),
- Subdirs0 = lists:flatmap(fun filelib:wildcard/1, ListSubdirs),
- case {rebar_config:is_skip_dir(Config, Cwd), Subdirs0} of
- {true, []} ->
- {ok, []};
- {true, _} ->
- ?WARN("Ignoring sub_dirs for ~s~n", [Cwd]),
- {ok, []};
- {false, _} ->
- Check = check_loop(Cwd),
- ok = lists:foreach(Check, Subdirs0),
- Subdirs = [filename:join(Cwd, Dir) || Dir <- Subdirs0],
- {ok, Subdirs}
- end.
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-check_loop(Cwd) ->
- RebarConfig = filename:join(Cwd, "rebar.config"),
- fun(Dir0) ->
- IsSymlink = case file:read_link_info(Dir0) of
- {ok, #file_info{type=symlink}} ->
- {true, resolve_symlink(Dir0)};
- _ ->
- {false, Dir0}
- end,
- case IsSymlink of
- {false, Dir="."} ->
- ?ERROR("infinite loop detected:~nsub_dirs"
- " entry ~p in ~s~n", [Dir, RebarConfig]);
- {true, Cwd} ->
- ?ERROR("infinite loop detected:~nsub_dirs"
- " entry ~p in ~s is a symlink to \".\"~n",
- [Dir0, RebarConfig]);
- _ ->
- ok
- end
- end.
-
-resolve_symlink(Dir0) ->
- {ok, Dir} = file:read_link(Dir0),
- Dir.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_templater.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_templater.erl b/src/rebar/src/rebar_templater.erl
deleted file mode 100644
index b8f7087..0000000
--- a/src/rebar/src/rebar_templater.erl
+++ /dev/null
@@ -1,462 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
--module(rebar_templater).
-
--export(['create-app'/2,
- 'create-node'/2,
- 'list-templates'/2,
- create/2]).
-
-%% API for other utilities that need templating functionality
--export([resolve_variables/2,
- render/2]).
-
-%% for internal use only
--export([info/2]).
-
--include("rebar.hrl").
-
--define(TEMPLATE_RE, ".*\\.template\$").
-
-%% ===================================================================
-%% Public API
-%% ===================================================================
-
-'create-app'(Config, _File) ->
- %% Alias for create w/ template=simpleapp
- create1(Config, "simpleapp").
-
-'create-node'(Config, _File) ->
- %% Alias for create w/ template=simplenode
- create1(Config, "simplenode").
-
-'list-templates'(Config, _File) ->
- {AvailTemplates, Files} = find_templates(Config),
- ?DEBUG("Available templates: ~p\n", [AvailTemplates]),
-
- lists:foreach(
- fun({Type, F}) ->
- BaseName = filename:basename(F, ".template"),
- TemplateTerms = consult(load_file(Files, Type, F)),
- {_, VarList} = lists:keyfind(variables, 1, TemplateTerms),
- Vars = lists:foldl(fun({V,_}, Acc) ->
- [atom_to_list(V) | Acc]
- end, [], VarList),
- ?CONSOLE(" * ~s: ~s (~p) (variables: ~p)\n",
- [BaseName, F, Type, string:join(Vars, ", ")])
- end, AvailTemplates),
- ok.
-
-create(Config, _) ->
- TemplateId = template_id(Config),
- create1(Config, TemplateId).
-
-%%
-%% Given a list of key value pairs, for each string value attempt to
-%% render it using Dict as the context. Storing the result in Dict as Key.
-%%
-resolve_variables([], Dict) ->
- Dict;
-resolve_variables([{Key, Value0} | Rest], Dict) when is_list(Value0) ->
- Value = render(list_to_binary(Value0), Dict),
- resolve_variables(Rest, dict:store(Key, Value, Dict));
-resolve_variables([{Key, {list, Dicts}} | Rest], Dict) when is_list(Dicts) ->
- %% just un-tag it so mustache can use it
- resolve_variables(Rest, dict:store(Key, Dicts, Dict));
-resolve_variables([_Pair | Rest], Dict) ->
- resolve_variables(Rest, Dict).
-
-%%
-%% Render a binary to a string, using mustache and the specified context
-%%
-render(Bin, Context) ->
- %% Be sure to escape any double-quotes before rendering...
- ReOpts = [global, {return, list}],
- Str0 = re:replace(Bin, "\\\\", "\\\\\\", ReOpts),
- Str1 = re:replace(Str0, "\"", "\\\\\"", ReOpts),
- mustache:render(Str1, Context).
-
-%% ===================================================================
-%% Internal functions
-%% ===================================================================
-
-info(help, create) ->
- ?CONSOLE(
- "Create skel based on template and vars.~n"
- "~n"
- "Valid command line options:~n"
- " template= [var=foo,...]~n", []);
-info(help, 'create-app') ->
- ?CONSOLE(
- "Create simple app skel.~n"
- "~n"
- "Valid command line options:~n"
- " [appid=myapp]~n", []);
-info(help, 'create-node') ->
- ?CONSOLE(
- "Create simple node skel.~n"
- "~n"
- "Valid command line options:~n"
- " [nodeid=mynode]~n", []);
-info(help, 'list-templates') ->
- ?CONSOLE("List available templates.~n", []).
-
-create1(Config, TemplateId) ->
- {AvailTemplates, Files} = find_templates(Config),
- ?DEBUG("Available templates: ~p\n", [AvailTemplates]),
-
- %% Using the specified template id, find the matching template file/type.
- %% Note that if you define the same template in both ~/.rebar/templates
- %% that is also present in the escript, the one on the file system will
- %% be preferred.
- {Type, Template} = select_template(AvailTemplates, TemplateId),
-
- %% Load the template definition as is and get the list of variables the
- %% template requires.
- TemplateTerms = consult(load_file(Files, Type, Template)),
- case lists:keyfind(variables, 1, TemplateTerms) of
- {variables, Vars} ->
- case parse_vars(Vars, dict:new()) of
- {error, Entry} ->
- Context0 = undefined,
- ?ABORT("Failed while processing variables from template ~p."
- "Variable definitions must follow form of "
- "[{atom(), term()}]. Failed at: ~p\n",
- [TemplateId, Entry]);
- Context0 ->
- ok
- end;
- false ->
- ?WARN("No variables section found in template ~p; "
- "using empty context.\n", [TemplateId]),
- Context0 = dict:new()
- end,
-
- %% Load variables from disk file, if provided
- Context1 = case rebar_config:get_global(Config, template_vars, undefined) of
- undefined ->
- Context0;
- File ->
- case consult(load_file([], file, File)) of
- {error, Reason} ->
- ?ABORT("Unable to load template_vars from ~s: ~p\n",
- [File, Reason]);
- Terms ->
- %% TODO: Cleanup/merge with similar code in rebar_reltool
- M = fun(_Key, _Base, Override) -> Override end,
- dict:merge(M, Context0, dict:from_list(Terms))
- end
- end,
-
- %% For each variable, see if it's defined in global vars -- if it is,
- %% prefer that value over the defaults
- Context2 = update_vars(Config, dict:fetch_keys(Context1), Context1),
- ?DEBUG("Template ~p context: ~p\n", [TemplateId, dict:to_list(Context1)]),
-
- %% Handle variables that possibly include other variables in their
- %% definition
- Context = resolve_variables(dict:to_list(Context2), Context2),
-
- ?DEBUG("Resolved Template ~p context: ~p\n",
- [TemplateId, dict:to_list(Context)]),
-
- %% Now, use our context to process the template definition -- this
- %% permits us to use variables within the definition for filenames.
- FinalTemplate = consult(render(load_file(Files, Type, Template), Context)),
- ?DEBUG("Final template def ~p: ~p\n", [TemplateId, FinalTemplate]),
-
- %% Execute the instructions in the finalized template
- Force = rebar_config:get_global(Config, force, "0"),
- execute_template(Files, FinalTemplate, Type, Template, Context, Force, []).
-
-find_templates(Config) ->
- %% Load a list of all the files in the escript -- cache them since
- %% we'll potentially need to walk it several times over the course of
- %% a run.
- Files = cache_escript_files(Config),
-
- %% Build a list of available templates
- AvailTemplates = find_disk_templates(Config)
- ++ find_escript_templates(Files),
-
- {AvailTemplates, Files}.
-
-%%
-%% Scan the current escript for available files
-%%
-cache_escript_files(Config) ->
- {ok, Files} = rebar_utils:escript_foldl(
- fun(Name, _, GetBin, Acc) ->
- [{Name, GetBin()} | Acc]
- end,
- [], rebar_config:get_xconf(Config, escript)),
- Files.
-
-template_id(Config) ->
- case rebar_config:get_global(Config, template, undefined) of
- undefined ->
- ?ABORT("No template specified.\n", []);
- TemplateId ->
- TemplateId
- end.
-
-find_escript_templates(Files) ->
- [{escript, Name}
- || {Name, _Bin} <- Files,
- re:run(Name, ?TEMPLATE_RE, [{capture, none}]) == match].
-
-find_disk_templates(Config) ->
- OtherTemplates = find_other_templates(Config),
- HomeFiles = rebar_utils:find_files(filename:join([os:getenv("HOME"),
- ".rebar", "templates"]),
- ?TEMPLATE_RE),
- LocalFiles = rebar_utils:find_files(".", ?TEMPLATE_RE),
- [{file, F} || F <- OtherTemplates ++ HomeFiles ++ LocalFiles].
-
-find_other_templates(Config) ->
- case rebar_config:get_global(Config, template_dir, undefined) of
- undefined ->
- [];
- TemplateDir ->
- rebar_utils:find_files(TemplateDir, ?TEMPLATE_RE)
- end.
-
-select_template([], Template) ->
- ?ABORT("Template ~s not found.\n", [Template]);
-select_template([{Type, Avail} | Rest], Template) ->
- case filename:basename(Avail, ".template") == Template of
- true ->
- {Type, Avail};
- false ->
- select_template(Rest, Template)
- end.
-
-%%
-%% Read the contents of a file from the appropriate source
-%%
-load_file(Files, escript, Name) ->
- {Name, Bin} = lists:keyfind(Name, 1, Files),
- Bin;
-load_file(_Files, file, Name) ->
- {ok, Bin} = file:read_file(Name),
- Bin.
-
-%%
-%% Parse/validate variables out from the template definition
-%%
-parse_vars([], Dict) ->
- Dict;
-parse_vars([{Key, Value} | Rest], Dict) when is_atom(Key) ->
- parse_vars(Rest, dict:store(Key, Value, Dict));
-parse_vars([Other | _Rest], _Dict) ->
- {error, Other};
-parse_vars(Other, _Dict) ->
- {error, Other}.
-
-%%
-%% Given a list of keys in Dict, see if there is a corresponding value defined
-%% in the global config; if there is, update the key in Dict with it
-%%
-update_vars(_Config, [], Dict) ->
- Dict;
-update_vars(Config, [Key | Rest], Dict) ->
- Value = rebar_config:get_global(Config, Key, dict:fetch(Key, Dict)),
- update_vars(Config, Rest, dict:store(Key, Value, Dict)).
-
-
-%%
-%% Given a string or binary, parse it into a list of terms, ala file:consult/1
-%%
-consult(Str) when is_list(Str) ->
- consult([], Str, []);
-consult(Bin) when is_binary(Bin)->
- consult([], binary_to_list(Bin), []).
-
-consult(Cont, Str, Acc) ->
- case erl_scan:tokens(Cont, Str, 0) of
- {done, Result, Remaining} ->
- case Result of
- {ok, Tokens, _} ->
- {ok, Term} = erl_parse:parse_term(Tokens),
- consult([], Remaining, [maybe_dict(Term) | Acc]);
- {eof, _Other} ->
- lists:reverse(Acc);
- {error, Info, _} ->
- {error, Info}
- end;
- {more, Cont1} ->
- consult(Cont1, eof, Acc)
- end.
-
-
-maybe_dict({Key, {list, Dicts}}) ->
- %% this is a 'list' element; a list of lists representing dicts
- {Key, {list, [dict:from_list(D) || D <- Dicts]}};
-maybe_dict(Term) ->
- Term.
-
-
-write_file(Output, Data, Force) ->
- %% determine if the target file already exists
- FileExists = filelib:is_regular(Output),
-
- %% perform the function if we're allowed,
- %% otherwise just process the next template
- case Force =:= "1" orelse FileExists =:= false of
- true ->
- ok = filelib:ensure_dir(Output),
- case {Force, FileExists} of
- {"1", true} ->
- ?CONSOLE("Writing ~s (forcibly overwriting)~n",
- [Output]);
- _ ->
- ?CONSOLE("Writing ~s~n", [Output])
- end,
- case file:write_file(Output, Data) of
- ok ->
- ok;
- {error, Reason} ->
- ?ABORT("Failed to write output file ~p: ~p\n",
- [Output, Reason])
- end;
- false ->
- {error, exists}
- end.
-
-prepend_instructions(Instructions, Rest) when is_list(Instructions) ->
- Instructions ++ Rest;
-prepend_instructions(Instruction, Rest) ->
- [Instruction|Rest].
-
-%%
-%% Execute each instruction in a template definition file.
-%%
-execute_template(_Files, [], _TemplateType, _TemplateName,
- _Context, _Force, ExistingFiles) ->
- case ExistingFiles of
- [] ->
- ok;
- _ ->
- Msg = lists:flatten([io_lib:format("\t* ~p~n", [F]) ||
- F <- lists:reverse(ExistingFiles)]),
- Help = "To force overwriting, specify -f/--force/force=1"
- " on the command line.\n",
- ?ERROR("One or more files already exist on disk and "
- "were not generated:~n~s~s", [Msg , Help])
- end;
-execute_template(Files, [{'if', Cond, True} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- execute_template(Files, [{'if', Cond, True, []}|Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles);
-execute_template(Files, [{'if', Cond, True, False} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- Instructions = case dict:find(Cond, Context) of
- {ok, true} ->
- True;
- {ok, "true"} ->
- True;
- _ ->
- False
- end,
- execute_template(Files, prepend_instructions(Instructions, Rest),
- TemplateType, TemplateName, Context, Force,
- ExistingFiles);
-execute_template(Files, [{template, Input, Output} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- InputName = filename:join(filename:dirname(TemplateName), Input),
- File = load_file(Files, TemplateType, InputName),
- case write_file(Output, render(File, Context), Force) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
- {error, exists} ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, [Output|ExistingFiles])
- end;
-execute_template(Files, [{file, Input, Output} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- InputName = filename:join(filename:dirname(TemplateName), Input),
- File = load_file(Files, TemplateType, InputName),
- case write_file(Output, File, Force) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
- {error, exists} ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, [Output|ExistingFiles])
- end;
-execute_template(Files, [{dir, Name} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- case filelib:ensure_dir(filename:join(Name, "dummy")) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
- {error, Reason} ->
- ?ABORT("Failed while processing template instruction "
- "{dir, ~s}: ~p\n", [Name, Reason])
- end;
-execute_template(Files, [{copy, Input, Output} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- InputName = filename:join(filename:dirname(TemplateName), Input),
- try rebar_file_utils:cp_r([InputName ++ "/*"], Output) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles)
- catch _:_ ->
- ?ABORT("Failed while processing template instruction "
- "{copy, ~s, ~s}~n", [Input, Output])
- end;
-execute_template(Files, [{chmod, Mod, File} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles)
- when is_integer(Mod) ->
- case file:change_mode(File, Mod) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
- {error, Reason} ->
- ?ABORT("Failed while processing template instruction "
- "{chmod, ~b, ~s}: ~p~n", [Mod, File, Reason])
- end;
-execute_template(Files, [{symlink, Existing, New} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- case file:make_symlink(Existing, New) of
- ok ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
- {error, Reason} ->
- ?ABORT("Failed while processing template instruction "
- "{symlink, ~s, ~s}: ~p~n", [Existing, New, Reason])
- end;
-execute_template(Files, [{variables, _} | Rest], TemplateType,
- TemplateName, Context, Force, ExistingFiles) ->
- execute_template(Files, Rest, TemplateType, TemplateName,
- Context, Force, ExistingFiles);
-execute_template(Files, [Other | Rest], TemplateType, TemplateName,
- Context, Force, ExistingFiles) ->
- ?WARN("Skipping unknown template instruction: ~p\n", [Other]),
- execute_template(Files, Rest, TemplateType, TemplateName, Context,
- Force, ExistingFiles).
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f84eb4fc/src/rebar/src/rebar_upgrade.erl
----------------------------------------------------------------------
diff --git a/src/rebar/src/rebar_upgrade.erl b/src/rebar/src/rebar_upgrade.erl
deleted file mode 100644
index 5814e51..0000000
--- a/src/rebar/src/rebar_upgrade.erl
+++ /dev/null
@@ -1,268 +0,0 @@
-%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
-%% ex: ts=4 sw=4 et
-%% -------------------------------------------------------------------
-%%
-%% rebar: Erlang Build Tools
-%%
-%% Copyright (c) 2011 Joe Williams (joe@joetify.com)
-%%
-%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%% of this software and associated documentation files (the "Software"), to deal
-%% in the Software without restriction, including without limitation the rights
-%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the Software is
-%% furnished to do so, subject to the following conditions:
-%%
-%% The above copyright notice and this permission notice shall be included in
-%% all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%% THE SOFTWARE.
-%% -------------------------------------------------------------------
-
--module(rebar_upgrade).
-
--include("rebar.hrl").
--include_lib("kernel/include/file.hrl").
-
--export(['generate-upgrade'/2]).
-
-%% for internal use only
--export([info/2]).
-
--define(TMP, "_tmp").
-
-%% ====================================================================
-%% Public API
-%% ====================================================================
-
-'generate-upgrade'(Config0, ReltoolFile) ->
- %% Get the old release path
- {Config, ReltoolConfig} = rebar_rel_utils:load_config(Config0, ReltoolFile),
- TargetParentDir = rebar_rel_utils:get_target_parent_dir(Config,
- ReltoolConfig),
- TargetDir = rebar_rel_utils:get_target_dir(Config, ReltoolConfig),
-
- PrevRelPath = rebar_rel_utils:get_previous_release_path(Config),
- OldVerPath = filename:join([TargetParentDir, PrevRelPath]),
-
- %% Run checks to make sure that building a package is possible
- {NewVerPath, NewName, NewVer} = run_checks(Config, OldVerPath,
- ReltoolConfig),
- NameVer = NewName ++ "_" ++ NewVer,
-
- %% Save the code path prior to doing anything
- OrigPath = code:get_path(),
-
- %% Prepare the environment for building the package
- ok = setup(OldVerPath, NewVerPath, NewName, NewVer, NameVer),
-
- %% Build the package
- run_systools(NameVer, NewName),
-
- %% Boot file changes
- {ok, _} = boot_files(TargetDir, NewVer, NewName),
-
- %% Extract upgrade and tar it back up with changes
- make_tar(NameVer, NewVer, NewName),
-
- %% Clean up files that systools created
- ok = cleanup(NameVer),
-
- %% Restore original path
- true = code:set_path(OrigPath),
-
- {ok, Config}.
-
-%% ===================================================================
-%% Internal functions
-%% ==================================================================
-
-info(help, 'generate-upgrade') ->
- ?CONSOLE("Build an upgrade package.~n"
- "~n"
- "Valid command line options:~n"
- " previous_release=path~n",
- []).
-
-run_checks(Config, OldVerPath, ReltoolConfig) ->
- true = rebar_utils:prop_check(filelib:is_dir(OldVerPath),
- "Release directory doesn't exist (~p)~n",
- [OldVerPath]),
-
- {Name, Ver} = rebar_rel_utils:get_reltool_release_info(ReltoolConfig),
-
- NewVerPath =
- filename:join(
- [rebar_rel_utils:get_target_parent_dir(Config, ReltoolConfig),
- Name]),
- true = rebar_utils:prop_check(filelib:is_dir(NewVerPath),
- "Release directory doesn't exist (~p)~n",
- [NewVerPath]),
-
- {NewName, NewVer} = rebar_rel_utils:get_rel_release_info(Name, NewVerPath),
- {OldName, OldVer} = rebar_rel_utils:get_rel_release_info(Name, OldVerPath),
-
- true =
- rebar_utils:prop_check(NewName == OldName,
- "New and old .rel release names do not match~n",
- []),
- true =
- rebar_utils:prop_check(Name == NewName,
- "Reltool and .rel release names do not match~n",
- []),
- true =
- rebar_utils:prop_check(NewVer =/= OldVer,
- "New and old .rel contain the same version~n",
- []),
- true =
- rebar_utils:prop_check(Ver == NewVer,
- "Reltool and .rel versions do not match~n", []),
-
- {NewVerPath, NewName, NewVer}.
-
-setup(OldVerPath, NewVerPath, NewName, NewVer, NameVer) ->
- Src = filename:join([NewVerPath, "releases",
- NewVer, NewName ++ ".rel"]),
- Dst = filename:join([".", NameVer ++ ".rel"]),
- {ok, _} = file:copy(Src, Dst),
- ok = code:add_pathsa(
- lists:append([
- filelib:wildcard(filename:join([NewVerPath,
- "lib", "*", "ebin"])),
- filelib:wildcard(filename:join([OldVerPath,
- "releases", "*"])),
- filelib:wildcard(filename:join([OldVerPath,
- "lib", "*", "ebin"]))
- ])).
-
-run_systools(NewVer, Name) ->
- Opts = [silent],
- NameList = [Name],
- case systools:make_relup(NewVer, NameList, NameList, Opts) of
- {error, _, Msg} ->
- ?ABORT("Systools [systools:make_relup/4] aborted with: ~p~n",
- [Msg]);
- _ ->
- ?DEBUG("Relup created~n", []),
- case systools:make_script(NewVer, Opts) of
- {error, _, Msg1} ->
- ?ABORT("Systools [systools:make_script/2] "
- "aborted with: ~p~n", [Msg1]);
- _ ->
- ?DEBUG("Script created~n", []),
- case systools:make_tar(NewVer, Opts) of
- {error, _, Msg2} ->
- ?ABORT("Systools [systools:make_tar/2] "
- "aborted with: ~p~n", [Msg2]);
- _ ->
- ?DEBUG("Tarball created~n", []),
- ok
- end
- end
- end.
-
-boot_files(TargetDir, Ver, Name) ->
- ok = file:make_dir(filename:join([".", ?TMP])),
- ok = file:make_dir(filename:join([".", ?TMP, "releases"])),
- ok = file:make_dir(filename:join([".", ?TMP, "releases", Ver])),
- case os:type() of
- {win32,_} ->
- ok;
- _ ->
- ok = file:make_symlink(
- filename:join(["start.boot"]),
- filename:join([".", ?TMP, "releases", Ver, Name ++ ".boot"]))
- end,
- {ok, _} =
- file:copy(
- filename:join([TargetDir, "releases", Ver, "start_clean.boot"]),
- filename:join([".", ?TMP, "releases", Ver, "start_clean.boot"])),
-
- SysConfig = filename:join([TargetDir, "releases", Ver, "sys.config"]),
- _ = case filelib:is_regular(SysConfig) of
- true ->
- {ok, _} = file:copy(
- SysConfig,
- filename:join([".", ?TMP, "releases", Ver,
- "sys.config"]));
- false -> ok
- end,
-
- VmArgs = filename:join([TargetDir, "releases", Ver, "vm.args"]),
- case filelib:is_regular(VmArgs) of
- true ->
- {ok, _} = file:copy(
- VmArgs,
- filename:join([".", ?TMP, "releases", Ver, "vm.args"]));
- false -> {ok, 0}
- end.
-
-make_tar(NameVer, NewVer, NewName) ->
- Filename = NameVer ++ ".tar.gz",
- {ok, Cwd} = file:get_cwd(),
- Absname = filename:join([Cwd, Filename]),
- ok = file:set_cwd(?TMP),
- ok = erl_tar:extract(Absname, [compressed]),
- ok = file:delete(Absname),
- case os:type() of
- {win32,_} ->
- {ok, _} =
- file:copy(
- filename:join([".", "releases", NewVer, "start.boot"]),
- filename:join([".", "releases", NewVer, NewName ++ ".boot"])),
- ok;
- _ ->
- ok
- end,
- {ok, Tar} = erl_tar:open(Absname, [write, compressed]),
- ok = erl_tar:add(Tar, "lib", []),
- ok = erl_tar:add(Tar, "releases", []),
- ok = erl_tar:close(Tar),
- ok = file:set_cwd(Cwd),
- ?CONSOLE("~s upgrade package created~n", [NameVer]).
-
-cleanup(NameVer) ->
- ?DEBUG("Removing files needed for building the upgrade~n", []),
- Files = [
- filename:join([".", NameVer ++ ".rel"]),
- filename:join([".", NameVer ++ ".boot"]),
- filename:join([".", NameVer ++ ".script"]),
- filename:join([".", "relup"])
- ],
- lists:foreach(fun(F) -> ok = file:delete(F) end, Files),
-
- ok = remove_dir_tree(?TMP).
-
-%% adapted from http://www.erlang.org/doc/system_principles/create_target.html
-remove_dir_tree(Dir) ->
- remove_all_files(".", [Dir]).
-remove_all_files(Dir, Files) ->
- lists:foreach(fun(File) ->
- FilePath = filename:join([Dir, File]),
- {ok, FileInfo, Link} = file_info(FilePath),
- case {Link, FileInfo#file_info.type} of
- {false, directory} ->
- {ok, DirFiles} = file:list_dir(FilePath),
- remove_all_files(FilePath, DirFiles),
- file:del_dir(FilePath);
- _ ->
- file:delete(FilePath)
- end
- end, Files).
-
-file_info(Path) ->
- case file:read_file_info(Path) of
- {ok, Info} ->
- {ok, Info, false};
- {error, enoent} ->
- {ok, Info} = file:read_link_info(Path),
- {ok, Info, true};
- Error ->
- Error
- end.