From 4f8f6125b3769e1eb107b4f02c2f039965688b08 Mon Sep 17 00:00:00 2001 From: Anthony Molinaro Date: Mon, 8 May 2017 19:04:36 +0000 Subject: Add the ability to chmod files in the overlay. Two types are supported, direct chmoding, like {chmod, 8#00700, "path/to/file/maybe/with/{{templates}}" } or templating the permission where you have a template var like {file_perm, 8#00700} and an overlay {chmod, "{{file_perm}}","path/to/file/maybe/with/{{templates}}" } --- src/rlx_prv_overlay.erl | 22 ++++++++++++++++++++++ test/rlx_archive_SUITE.erl | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/rlx_prv_overlay.erl b/src/rlx_prv_overlay.erl index a4c0fa4..dc57326 100644 --- a/src/rlx_prv_overlay.erl +++ b/src/rlx_prv_overlay.erl @@ -308,6 +308,28 @@ handle_errors(State, Result) -> -spec do_individual_overlay(rlx_state:t(), list(), proplists:proplist(), OverlayDirective::term()) -> {ok, rlx_state:t()} | relx:error(). +do_individual_overlay(State, _Files, OverlayVars, {chmod, Mode, Path}) -> + % mode can be specified directly as an integer value, or if it is + % not an integer we assume it's a template, which we render and convert + % blindly to an integer. So this will crash with an exception if for + % some reason something other than an integer is used + NewMode = + case is_integer(Mode) of + true -> Mode; + false -> erlang:list_to_integer(erlang:binary_to_list(render_string (OverlayVars, Mode))) + end, + + Root = rlx_state:output_dir(State), + file_render_do(OverlayVars, Path, + fun(NewPath) -> + Absolute = absolutize(State, + filename:join(Root,erlang:iolist_to_binary (NewPath))), + case file:change_mode(Absolute, NewMode) of + {error, Error} -> + ?RLX_ERROR({unable_to_chmod, NewMode, NewPath, Error}); + ok -> ok + end + end); do_individual_overlay(State, _Files, OverlayVars, {mkdir, Dir}) -> case rlx_util:render(erlang:iolist_to_binary(Dir), OverlayVars) of {ok, IoList} -> diff --git a/test/rlx_archive_SUITE.erl b/test/rlx_archive_SUITE.erl index 08da2b8..5122c11 100644 --- a/test/rlx_archive_SUITE.erl +++ b/test/rlx_archive_SUITE.erl @@ -249,6 +249,8 @@ overlay_archive(Config) -> TestDirFull = filename:join([LibDir1, TestDir]), TestFileFull = filename:join(TestDirFull, TestFile), SecondTestDir = "second_test_dir", + TestScript = "test_script", + TestScript2 = "test_script2", rlx_test_utils:write_config(ConfigFile, [{overlay_vars, [OverlayVars1, OverlayVars2]}, {overlay, [{mkdir, "{{target_dir}}/fooo"}, @@ -260,9 +262,17 @@ overlay_archive(Config) -> "{{target_dir}}/{{yahoo}}/vars.link.config"}, {copy, TestDirFull, "{{target_dir}}/"++SecondTestDir++"/"}, + {copy, TestScript, + "{{target_dir}}/"++SecondTestDir++"/"++TestScript}, + {chmod, 8#00700, + "{{target_dir}}/"++SecondTestDir++"/"++TestScript}, + {copy, TestScript2, + "{{target_dir}}/"++SecondTestDir++"/"++TestScript2}, + {chmod, "{{test_script_perm}}", + "{{target_dir}}/"++SecondTestDir++"/"++TestScript2}, {template, Template, "{{target_dir}}/test_template_resolved"}, - {template, Template, + {template, Template, "bin/{{default_release_name}}-{{default_release_version}}"}]}, {release, {foo, "0.0.1"}, [goal_app_1, @@ -272,7 +282,8 @@ overlay_archive(Config) -> rlx_test_utils:write_config(VarsFile1, [{yahoo, "yahoo"}, {yahoo2, [{foo, "bar"}]}, {foo_yahoo, "foo_{{yahoo}}"}, - {foo_dir, "foodir"}]), + {foo_dir, "foodir"}, + {test_script_perm,8#00770}]), VarsFile2 = filename:join([LibDir1, "vars2.config"]), rlx_test_utils:write_config(VarsFile2, [{google, "yahoo"}, @@ -283,6 +294,11 @@ overlay_archive(Config) -> rlx_test_utils:write_config(VarsFile3, [{google, "yahoo"}, {yahoo4, "{{yahoo}}/{{yahoo2}}4"}]), + TestScriptFile = filename:join([LibDir1,TestScript]), + ok = file:write_file(TestScriptFile, <<"#!/bin/sh\necho \"hello world\"">>), + TestScriptFile2 = filename:join([LibDir1,TestScript2]), + ok = file:write_file(TestScriptFile2, <<"#!/bin/sh\necho \"hello world 2\"">>), + ok = rlx_util:mkdir_p(TestDirFull), ok = file:write_file(TestFileFull, rlx_test_utils:test_template_contents()), @@ -312,6 +328,19 @@ overlay_archive(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)), + % check that the chmod of our file worked + ChmodedFile = filename:join([OutputDir,"foo",SecondTestDir,TestScript]), + {ok, ChmodedInfo} = file:read_file_info (ChmodedFile), + % mode from file_info is a bitmask which might have other bits set, but + % if we mask those we care about and check we should get true, see details + % here http://stackoverflow.com/questions/13183838/how-to-use-erlang-fileread-file-info-permissions-mode-info + ?assert(ChmodedInfo#file_info.mode band 8#00700 =:= 8#00700), + + % check that the templated chmod of our file worked + ChmodedFile2 = filename:join([OutputDir,"foo",SecondTestDir,TestScript2]), + {ok, ChmodedInfo2} = file:read_file_info (ChmodedFile2), + ?assert(ChmodedInfo2#file_info.mode band 8#00770 =:= 8#00770), + TarFile = filename:join([OutputDir, "foo", "foo-0.0.1.tar.gz"]), {ok, Files} = erl_tar:table(TarFile, [compressed]), ?assert(lists:any(fun(X) -> re:run(X, "lib/stdlib-.*/src/.*") =/= nomatch end, Files)), -- cgit v1.2.3