Skip to content

Commit

Permalink
all dist task to correctly position new release
Browse files Browse the repository at this point in the history
Signed-off-by: Jordan Wilberding <diginux@gmail.com>
  • Loading branch information
ericbmerritt authored and jwilberding committed Mar 23, 2012
1 parent ac16f2b commit f9a166c
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 180 deletions.
17 changes: 12 additions & 5 deletions smoketests/sin_testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def do_release(self, child, appdesc):
@sinan("dist")
def do_dist(self, child, appdesc):
child.expect(pexpect.EOF)
build_tmp = self.get_build_root_path()
build_tmp = self.get_release_root_path()
build_tmp.append("tar")
build_tmp.append("%s-%s.tar.gz" %
(appdesc.project_name, appdesc.project_version))
Expand Down Expand Up @@ -286,8 +286,7 @@ def do_run(self, appdesc):

def get_build_root_path(self, project_dir=None, release_name=None,
release_version=None):
if not project_dir:
project_dir = self.project_dir
release_root = self.get_release_root_path(project_dir)

if not release_name and not self.release_name:
release_name = self.current_app_desc.project_name
Expand All @@ -299,7 +298,15 @@ def get_build_root_path(self, project_dir=None, release_name=None,
elif not release_version:
release_version = self.release_version

release_root.append(release_name)
return release_root


def get_release_root_path(self, project_dir=None):
if not project_dir:
project_dir = self.project_dir

return [project_dir,
"_build",
release_name]
"_build"]


3 changes: 1 addition & 2 deletions smoketests/tests/release_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ def run_dist(self, child):
self.release_name + ".script"])


self.assert_files_exist("_build",
[r, "tar",
self.assert_files_exist(["tar",
"%s-%s.tar.gz" % (self.release_name,
self.release_version)])

Expand Down
211 changes: 45 additions & 166 deletions src/sin_task_dist.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,29 @@ description() ->
Desc = "This command creates a release, then tars that release into a
standard erlang distribution tarball that can be deployed in the standard
erlang manner. Check the erlang documentation about sys_tools and
distribution tarballs. Configuration options are as follows: <break> <break>
{include_dirs, List}. <break> <break> This is a list of directories rooted
at the project that you would like included in the tarball. You do not need
to include your OTP Application directories or metadata files as they are
included automatically. However, you should include any additionally
directories that you would like to ship. <break> <break> {include_erts, true
| false}. <break> <break> This is a boolean that indicates to the system
whether or not you want the Erlang runtime system included in the
tarball. This allows you to distribute the vm with your release but has the
drawback of turning your tarball into a platform specific thing.",
distribution tarballs. Configuration options are as follows:
<break>
<break>
{include_dirs, List}.
<break>
<break>
This is a list of directories rooted at the project that you would like
included in the tarball. You do not need to include your OTP Application
directories or metadata files as they are included automatically. However,
you should include any additionally directories that you would like to
ship.
<break>
<break>
{include_erts, true | false}.
<break>
<break>
This is a boolean that indicates to the system whether or not you want the
Erlang runtime system included in the tarball. This allows you to distribute
the vm with your release but has the drawback of turning your tarball into a
platform specific thing.",

#task{name = ?TASK,
task_impl = ?MODULE,
Expand All @@ -55,10 +68,18 @@ description() ->
%% @doc Build a dist tarball for this project
-spec do_task(sin_config:matcher(), sin_state:state()) -> sin_state:state().
do_task(Config, State) ->
ProjectDir = sin_state:get_value(project_dir, State),
ReleaseApps = sin_state:get_value(release_runtime_deps, State) ++
sin_state:get_value(project_apps, State),
make_tar(Config, State, ProjectDir, ReleaseApps).
BuildRoot = sin_state:get_value(build_root, State),
TarDir = filename:join([BuildRoot, "tar"]),
filelib:ensure_dir(filename:join([TarDir, "tmp"])),
ReleaseName = erlang:atom_to_list(sin_state:get_value(release, State)) ++ "-"
++ sin_state:get_value(release_vsn, State),
BuildDir = sin_state:get_value(build_dir, State),
List1 = exclude_erts_dir(Config, ReleaseName, gather_dirs(BuildDir, ReleaseName)),
create_tar_file(Config, State, filename:join([TarDir,
lists:flatten([ReleaseName, ".tar.gz"])]),
List1),
State.


%% @doc Format an exception thrown by this module
-spec format_exception(sin_exceptions:exception()) ->
Expand All @@ -70,43 +91,6 @@ format_exception(Exception) ->
%%% Internal functions
%%====================================================================

%% @doc Go through and actually build up the tar file.
-spec make_tar(sin_config:matcher(),
sin_state:state(), string(), [sinan:app()]) ->
sin_state:state().
make_tar(Config, State, ProjectDir, ReleaseApps) ->
BuildDir = sin_state:get_value(build_dir, State),
TarDir = filename:join([BuildDir, "tar"]),
filelib:ensure_dir(filename:join([TarDir, "tmp"])),
ReleaseName = erlang:atom_to_list(sin_state:get_value(release, State)) ++ "-"
++ sin_state:get_value(release_vsn, State),
LibDir = filename:join([ReleaseName, "lib"]),
List1 = gather_dirs(LibDir, ReleaseApps, []),
List3 = List1 ++ copy_additional_dirs(Config, State, ReleaseName, ProjectDir) ++
get_release_dirs(Config, State, ProjectDir) ++
add_defaults(State, ProjectDir, ReleaseName),
create_tar_file(Config, State, filename:join([TarDir,
lists:flatten([ReleaseName, ".tar.gz"])]),
List3),
State.

%% @doc Add default directories/files to list of things to include in the dist.
-spec add_defaults(sin_state:state(),
string(), string()) -> [{string(), string()}].
add_defaults(State, ProjectDir, TopLevel) ->
Bin = "bin",
lists:foldl(fun(Ele, Acc) ->
File = filename:join([ProjectDir, Ele]),
case sin_utils:file_exists(State, File) of
true ->
[{File, filename:join([TopLevel, Ele])} | Acc ];
false ->
Acc
end
end,
[],
[Bin]).

%% @doc Actually create the tar file and write in all of the contents.
-spec create_tar_file(sin_config:config(), sin_state:state(), string(), [string()]) ->
ok.
Expand All @@ -125,128 +109,23 @@ create_tar_file(Config, State, FileName, TarContents) ->
erl_tar:close(Tar)
end.

%% @doc Create addition file links for the system.
-spec copy_additional_dirs(sin_config:matcher(), sin_state:state(), string(), string()) ->
[string()].
copy_additional_dirs(Config, State, TopLevel, ProjectDir) ->
NewDirs =
case Config:match(include_dirs, undefined) of
undefined ->
[];
RequiredDirs ->
lists:map(fun(Elem) ->
NewElem =
case is_binary(Elem) of
true ->
binary_to_list(Elem);
false ->
Elem
end,
Name = filename:join([ProjectDir, NewElem]),
NewName = filename:join([TopLevel, NewElem]),
{Name, NewName}
end,
RequiredDirs)
end,
hooks_dir(State, TopLevel, ProjectDir) ++
erts_dir(Config, TopLevel) ++
NewDirs.

%% @doc Check to see if there are faxien hooks in the hooks dir. If so copy it.
-spec hooks_dir(sin_state:state(),
string(), string()) -> {string(), string()}.
hooks_dir(State, TopLevel, ProjectDir) ->
HooksDir = filename:join([ProjectDir, "_hooks"]),
case sin_utils:file_exists(State, HooksDir) andalso
filelib:fold_files(HooksDir, "fax.*\.erl",
false, fun(_,_) -> true end, false) of
true ->
[{HooksDir, filename:join([TopLevel, "_hooks"])}];
_ ->
[]
end.

%% @doc If an erts version should be included in the dist include it copy it.
-spec erts_dir(sin_config:matcher(), string()) -> {string(), string()}.
erts_dir(Config, TopLevel) ->
ErtsToInclude = sin_utils:get_erts_dir(),
exclude_erts_dir(Config, TopLevel, Entries) ->
case Config:match(include_erts, false) of
true ->
ErtsVersion = erlang:system_info(version),
[{ErtsToInclude,
filename:join([TopLevel, "erts-" ++ ErtsVersion])}];
[Entry || Entry={_, Erts} <- Entries,
Erts =/= filename:join(TopLevel, "erts-" ++ ErtsVersion)];
_ ->
[]
Entries
end.

%% @doc Gather up the applications and return a list of {DirName, InTarName}
%% pairs.
-spec gather_dirs(string(), [string()], list()) ->
-spec gather_dirs(string(), string()) ->
[{string(), string()}].
gather_dirs(LibDir, [#app{name=AppName, vsn=Vsn, path=Path} | T], Acc) ->
DirName = lists:flatten([atom_to_list(AppName), "-", Vsn]),
NewName = filename:join([LibDir, DirName]),
gather_dirs(LibDir, T, [{Path, NewName} | Acc]);
gather_dirs(_, [], Acc) ->
Acc.

%% @doc Get the release information for the system.
-spec get_release_dirs(sin_config:matcher(),
sin_state:state(), string()) -> [{string(), string()}].
get_release_dirs(Config, State, ProjectDir) ->
Name = sin_state:get_value(release, State),
Vsn = sin_state:get_value(release_vsn, State),
ReleaseDir = sin_state:get_value(release_dir, State),
SourceReleases = filename:join(ReleaseDir, Vsn),
TargetReleases = filename:join([erlang:atom_to_list(Name) ++ "-" ++ Vsn,
"releases", Vsn]),
Result =
case Config:match(include_release_info, undefined) of
Value when Value == true; Value == undefined ->
[{filename:join([SourceReleases,
lists:flatten([Name, ".boot"])]),
filename:join([TargetReleases,
lists:flatten([Name, ".boot"])])},
{filename:join([SourceReleases,
lists:flatten([Name, ".script"])]),
filename:join([TargetReleases,
lists:flatten([Name, ".script"])])},
{filename:join([SourceReleases,
lists:flatten([Name, ".rel"])]),
filename:join([TargetReleases,
lists:flatten([Name, ".rel"])])}];
_ ->
[]
end,
Result ++ get_config_info(State, ProjectDir, TargetReleases).

%% @doc Copy information in config into the releases directory
-spec get_config_info(sin_state:state(),
string(), string) -> [{string(), string()}].
get_config_info(State, ProjectDir, TargetReleases) ->
Target = filename:join([ProjectDir, "config"]),
case sin_utils:file_exists(State, Target) of
true ->
{ok, Files} = file:list_dir(Target),
lists:foldl(fun(File, Acc) ->
gather_config_info(Target,
TargetReleases, File, Acc)
end,
[],
Files);
_ ->
[]
end.
gather_dirs(ActualDir, TarDir) ->
{ok, Files} = file:list_dir(ActualDir),
[{filename:join(ActualDir, File), filename:join(TarDir, filename:basename(File))} ||
File <- Files,
File =/= ".sig"].

%% @doc If its not a directory return it in the correct format
-spec gather_config_info(string(), string(), string(), [{string(), string()}]) ->
[{string(), string()}].
gather_config_info(Source, TargetReleases, File, Acc) ->
ActualName = filename:join([Source, File]),
case filelib:is_dir(ActualName) of
true ->
Acc;
false ->
[{ActualName,
filename:join(TargetReleases, File)} | Acc]
end.
40 changes: 33 additions & 7 deletions src/sin_task_release.erl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,17 @@ description() ->
<break><break>
Not that the value for script_args must always be a list" ,
Not that the value for script_args must always be a list
You may also include additional directories into the release with
<break>
<break>
{include_dirs, List}.
<break>
<break>
" ,

#task{name = ?TASK,
task_impl = ?MODULE,
Expand All @@ -75,10 +85,11 @@ do_task(Config, State0) ->
ReleaseInfo = generate_rel_file(Config, State0, ReleaseDir,
ReleaseName, Version),
State1 = sin_state:store(rel, ReleaseInfo, State0),
copy_include_dirs(Config, State1, BuildDir),
copy_apps(Config, State1),
create_bin_file(State1, BuildDir,
ReleaseName, Version, get_erts_info()),
copy_or_generate_sys_config_file(Config, ReleaseDir, Version),
copy_apps(Config, State1, BuildDir),
include_erts(Config, State1, BuildDir),
make_boot_script(State1, Config, ReleaseInfo),
State1.
Expand Down Expand Up @@ -258,12 +269,30 @@ include_erts(Config, State, ReleaseRootDir) ->
ErtsDir = sin_utils:get_erts_dir(),
sin_utils:copy_dir(Config, State, ReleaseRootDir, ErtsDir, [keep_parent]).

copy_apps(Config, State, BuildDir) ->
LibDir = filename:join(BuildDir, "lib"),
copy_apps(Config, State) ->
LibDir = sin_state:get_value(apps_dir, State),
Apps = sin_state:get_value(release_runtime_deps, State),
lists:foreach(fun(#app{path=Path}) ->
sin_utils:copy_dir(Config, State, LibDir, Path, [keep_parent])
end, Apps).

copy_include_dirs(Config, State, BuildDir) ->
case Config:match(include_dirs, undefined) of
undefined ->
[];
RequiredDirs ->
lists:foreach(fun(File) ->
case sin_utils:file_exists(State, File) of
true ->
sin_utils:copy_dir(Config, State, BuildDir,
File, [keep_parent]);
false ->
ok
end
%% Bin is always included by default
end, ["bin" | RequiredDirs])
end.

create_bin_file(State, BuildDir, RelName, RelVsn, ErtsVsn) ->
BinDir = filename:join([BuildDir, "bin"]),
filelib:ensure_dir(filename:join(BinDir, "tmp")),
Expand All @@ -287,9 +316,6 @@ create_bin_file(State, BuildDir, RelName, RelVsn, ErtsVsn) ->
end.





bin_file_contents(RelName, RelVsn, ErtsVsn) ->

[<<"#!/bin/sh
Expand Down

0 comments on commit f9a166c

Please sign in to comment.