- -module(rebar_file_utils_SUITE).
-
- -export([all/0,
- groups/0,
- init_per_group/2,
- end_per_group/2,
- init_per_testcase/2,
- end_per_testcase/2,
- raw_tmpdir/1,
- empty_tmpdir/1,
- simple_tmpdir/1,
- multi_tmpdir/1,
- reset_nonexistent_dir/1,
- reset_empty_dir/1,
- reset_dir/1,
- path_from_ancestor/1,
- canonical_path/1,
- resolve_link/1,
- split_dirname/1,
- mv_warning_is_ignored/1,
- mv_dir/1,
- mv_file_same/1,
- mv_file_diff/1,
- mv_file_dir_same/1,
- mv_file_dir_diff/1,
- mv_no_clobber/1]).
-
- -include_lib("common_test/include/ct.hrl").
- -include_lib("eunit/include/eunit.hrl").
- -include_lib("kernel/include/file.hrl").
-
-
- all() ->
- [{group, tmpdir},
- {group, reset_dir},
- {group, mv},
- path_from_ancestor,
- canonical_path,
- resolve_link,
- split_dirname,
- mv_warning_is_ignored].
-
- groups() ->
- [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]},
- {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]},
- {mv, [], [mv_dir, mv_file_same, mv_file_diff,
- mv_file_dir_same, mv_file_dir_diff, mv_no_clobber]}].
-
- init_per_group(reset_dir, Config) ->
- TmpDir = rebar_file_utils:system_tmpdir(["rebar_file_utils_SUITE", "resetable"]),
- [{tmpdir, TmpDir}|Config];
- init_per_group(_, Config) -> Config.
- end_per_group(_, Config) -> Config.
-
- init_per_testcase(Test, Config) ->
- case os:type() of
- {win32, _} ->
- case lists:member(Test, [resolve_link, mv_warning_is_ignored]) of
- true -> {skip, "broken in windows"};
- false -> Config
- end;
- _ ->
- Config
- end.
-
- end_per_testcase(_Test, Config) ->
- Config.
-
- raw_tmpdir(_Config) ->
- case rebar_file_utils:system_tmpdir() of
- "/tmp" -> ok;
- "./tmp" -> ok
- end.
-
- empty_tmpdir(_Config) ->
- case rebar_file_utils:system_tmpdir([]) of
- "/tmp" -> ok;
- "./tmp" -> ok
- end.
-
- simple_tmpdir(_Config) ->
- case rebar_file_utils:system_tmpdir(["test"]) of
- "/tmp/test" -> ok;
- "./tmp/test" -> ok
- end.
-
- multi_tmpdir(_Config) ->
- case rebar_file_utils:system_tmpdir(["a", "b", "c"]) of
- "/tmp/a/b/c" -> ok;
- "./tmp/a/b/c" -> ok
- end.
-
- reset_nonexistent_dir(Config) ->
- TmpDir = ?config(tmpdir, Config),
- _ = ec_file:remove(TmpDir, [recursive]),
- ?assertNot(filelib:is_dir(TmpDir)),
- ok = rebar_file_utils:reset_dir(TmpDir),
- ?assert(filelib:is_dir(TmpDir)),
- {ok, []} = rebar_utils:list_dir(TmpDir).
-
- reset_empty_dir(Config) ->
- TmpDir = ?config(tmpdir, Config),
- _ = ec_file:remove(TmpDir, [recursive]),
- _ = filelib:ensure_dir(filename:join([TmpDir, "dummy.beam"])),
- ?assert(filelib:is_dir(TmpDir)),
- ok = rebar_file_utils:reset_dir(TmpDir),
- ?assert(filelib:is_dir(TmpDir)),
- {ok, []} = rebar_utils:list_dir(TmpDir).
-
- reset_dir(Config) ->
- TmpDir = ?config(tmpdir, Config),
- _ = ec_file:remove(TmpDir, [recursive]),
- _ = filelib:ensure_dir(filename:join([TmpDir, "dummy.beam"])),
- ?assert(filelib:is_dir(TmpDir)),
- lists:foreach(fun(Name) -> file:write_file(filename:join([TmpDir, Name]), <<>>) end,
- ["a", "b", "c"]),
- lists:foreach(fun(File) -> ?assert(filelib:is_file(filename:join([TmpDir, File]))) end,
- ["a", "b", "c"]),
- ok = rebar_file_utils:reset_dir(TmpDir),
- ?assert(filelib:is_dir(TmpDir)),
- {ok, []} = rebar_utils:list_dir(TmpDir).
-
- path_from_ancestor(_Config) ->
- ?assertEqual({ok, "foo/bar/baz"}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/")),
- ?assertEqual({ok, "bar/baz"}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo")),
- ?assertEqual({ok, "bar"}, rebar_file_utils:path_from_ancestor("foo/bar", "foo")),
- ?assertEqual({ok, "bar"}, rebar_file_utils:path_from_ancestor("foo/bar/", "foo/")),
- ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/qux")),
- ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo/bar/baz/qux")).
-
- canonical_path(_Config) ->
- %% We find the root so that the name works both on unix-likes and
- %% with Windows.
- Root = case os:type() of
- {win32, _} -> filename:nativename(filename:absname("/")); % C:\, with proper drive
- _ -> "/"
- end,
- ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/")),
- ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/../../..")),
- ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/bar/..")),
- ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/../foo")),
- ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/.")),
- ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")),
- ?assertEqual(filename:nativename(Root ++ "foo/bar"),
- rebar_file_utils:canonical_path("/foo/./bar")).
-
- resolve_link(_Config) ->
- TmpDir = rebar_file_utils:system_tmpdir(
- ["rebar_file_utils_SUITE", "resolve_link"]),
- Link = filename:join(TmpDir, "link"),
- Target = filename:join(TmpDir, "link-target"),
- ec_file:remove(TmpDir, [recursive]),
- ok = filelib:ensure_dir(Target),
- ok = file:write_file(Target, <<>>),
- ok = file:make_symlink(Target, Link),
- ?assertEqual(Target, rebar_file_utils:resolve_link(Link)).
-
- split_dirname(_Config) ->
- ?assertEqual({".", ""}, rebar_file_utils:split_dirname("")),
- ?assertEqual({"/", ""}, rebar_file_utils:split_dirname("/")),
- ?assertEqual({"/", "foo"}, rebar_file_utils:split_dirname("/foo")),
- ?assertEqual({".", "foo"}, rebar_file_utils:split_dirname("foo")),
- ?assertEqual({"/foo", "bar"}, rebar_file_utils:split_dirname("/foo/bar")),
- ?assertEqual({"foo", "bar"}, rebar_file_utils:split_dirname("foo/bar")).
-
- mv_warning_is_ignored(_Config) ->
- meck:new(rebar_utils, [passthrough]),
- meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end),
- ok = rebar_file_utils:mv("ding", "dong"),
- meck:unload(rebar_utils).
-
- %%% Ensure Windows & Unix operations to move files
-
- mv_dir(Config) ->
- %% Move a directory to another one location
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_dir),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- %% empty dir movement
- DstDir1 = filename:join(BaseDir, "dst1/"),
- ?assertNot(filelib:is_dir(DstDir1)),
- ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir1)),
- ?assert(filelib:is_dir(DstDir1)),
-
- %% move files from dir to empty dir
- F1 = filename:join(SrcDir, "file1"),
- F2 = filename:join(SrcDir, "subdir/file2"),
- filelib:ensure_dir(F2),
- file:write_file(F1, "hello"),
- file:write_file(F2, "world"),
- DstDir2 = filename:join(BaseDir, "dst2/"),
- D2F1 = filename:join(DstDir2, "file1"),
- D2F2 = filename:join(DstDir2, "subdir/file2"),
- ?assertNot(filelib:is_dir(DstDir2)),
- ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)),
- ?assert(filelib:is_file(D2F1)),
- ?assert(filelib:is_file(D2F2)),
-
- %% move files from dir to existing dir moves it to
- %% a subdir
- filelib:ensure_dir(F2),
- file:write_file(F1, "hello"),
- file:write_file(F2, "world"),
- DstDir3 = filename:join(BaseDir, "dst3/"),
- D3F1 = filename:join(DstDir3, "src/file1"),
- D3F2 = filename:join(DstDir3, "src/subdir/file2"),
- ec_file:mkdir_p(DstDir3),
- ?assert(filelib:is_dir(DstDir3)),
- ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)),
- ?assertNot(filelib:is_file(F1)),
- ?assertNot(filelib:is_file(F2)),
- ?assert(filelib:is_file(D3F1)),
- ?assert(filelib:is_file(D3F2)),
- ?assertNot(filelib:is_dir(SrcDir)),
- ok.
-
- mv_file_same(Config) ->
- %% Move a file from a directory to the other without renaming
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_file_same),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- F = filename:join(SrcDir, "file"),
- file:write_file(F, "hello"),
- DstDir = filename:join(BaseDir, "dst/"),
- ec_file:mkdir_p(DstDir),
- Dst = filename:join(DstDir, "file"),
- ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
- ?assert(filelib:is_file(Dst)),
- ?assertNot(filelib:is_file(F)),
- ok.
-
- mv_file_diff(Config) ->
- %% Move a file from a directory to another one while renaming
- %% into a pre-existing file
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_file_diff),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- F = filename:join(SrcDir, "file"),
- file:write_file(F, "hello"),
- DstDir = filename:join(BaseDir, "dst/"),
- ec_file:mkdir_p(DstDir),
- Dst = filename:join(DstDir, "file-rename"),
- file:write_file(Dst, "not-the-right-content"),
- ?assert(filelib:is_file(Dst)),
- ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
- ?assert(filelib:is_file(Dst)),
- ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
- ?assertNot(filelib:is_file(F)),
- ok.
-
- mv_file_dir_same(Config) ->
- %% Move a file to a directory without renaming
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_file_dir_same),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- F = filename:join(SrcDir, "file"),
- file:write_file(F, "hello"),
- DstDir = filename:join(BaseDir, "dst/"),
- ec_file:mkdir_p(DstDir),
- Dst = filename:join(DstDir, "file"),
- ?assert(filelib:is_dir(DstDir)),
- ?assertEqual(ok, rebar_file_utils:mv(F, DstDir)),
- ?assert(filelib:is_file(Dst)),
- ?assertNot(filelib:is_file(F)),
- ok.
-
- mv_file_dir_diff(Config) ->
- %% Move a file to a directory while renaming
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_file_dir_diff),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- F = filename:join(SrcDir, "file"),
- file:write_file(F, "hello"),
- DstDir = filename:join(BaseDir, "dst/"),
- ec_file:mkdir_p(DstDir),
- Dst = filename:join(DstDir, "file-rename"),
- ?assert(filelib:is_dir(DstDir)),
- ?assertNot(filelib:is_file(Dst)),
- ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
- ?assert(filelib:is_file(Dst)),
- ?assertNot(filelib:is_file(F)),
- ok.
-
- mv_no_clobber(Config) ->
- %% Moving a file while renaming does not clobber other files
- PrivDir = ?config(priv_dir, Config),
- BaseDir = mk_base_dir(PrivDir, mv_no_clobber),
- SrcDir = filename:join(BaseDir, "src/"),
- ec_file:mkdir_p(SrcDir),
- ?assert(filelib:is_dir(SrcDir)),
- F = filename:join(SrcDir, "file"),
- file:write_file(F, "hello"),
- FBad = filename:join(SrcDir, "file-alt"),
- file:write_file(FBad, "wrong-data"),
- DstDir = filename:join(BaseDir, "dst/"),
- ec_file:mkdir_p(DstDir),
- Dst = filename:join(DstDir, "file-alt"),
- DstBad = filename:join(DstDir, "file"),
- file:write_file(DstBad, "wrong-data"),
- ?assert(filelib:is_file(F)),
- ?assert(filelib:is_file(FBad)),
- ?assert(filelib:is_dir(DstDir)),
- ?assertNot(filelib:is_file(Dst)),
- ?assert(filelib:is_file(DstBad)),
- ?assertEqual(ok, rebar_file_utils:mv(F, Dst)),
- ?assert(filelib:is_file(Dst)),
- ?assertNot(filelib:is_file(F)),
- ?assert(filelib:is_file(DstBad)),
- ?assert(filelib:is_file(FBad)),
- ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)),
- ?assertEqual({ok, <<"wrong-data">>}, file:read_file(FBad)),
- ?assertEqual({ok, <<"wrong-data">>}, file:read_file(DstBad)),
- ok.
-
-
- mk_base_dir(BasePath, Name) ->
- {_,_,Micro} = os:timestamp(),
- Index = integer_to_list(Micro),
- Path = filename:join(BasePath, atom_to_list(Name) ++ Index),
- ec_file:mkdir_p(Path),
- Path.
|