diff --git a/bin/flake_env.re b/bin/flake_env.re index 4567cb9..d2b6dfd 100644 --- a/bin/flake_env.re +++ b/bin/flake_env.re @@ -12,7 +12,14 @@ let main = () => { switch (Lib.Watches.get()) { | Ok(watches) => let paths = Array.map(~f=watch => watch.path, watches); - let hash = Util.hash_files(paths); + let hash = + switch (Util.hash_files(paths)) { + | Ok(hsh) => hsh + | Error(msg) => + Printf.eprintf("%s\n", e); + exit(1); + }; + let profile = layout_directory ++ "/flake-profile-" ++ hash; let profile_rc = profile ++ ".rc"; diff --git a/lib/flake_env__util.re b/lib/flake_env__util.re index 1b5aa7b..e471010 100644 --- a/lib/flake_env__util.re +++ b/lib/flake_env__util.re @@ -17,23 +17,39 @@ let nix = args => ); let hash_files = filenames => { - /*** Hash all entries in [filenames], returning a hex-encoded string of the hash of their contents */ + /*** Hash all entries in [filenames] + Returns Some(hex-string) or None if no filenames are found. + */ let ctx = Sha1.init(); - let () = + let files_to_hash = filenames |> Array.filter(~f=f => switch (Sys_unix.file_exists(f)) { | `Yes => true - | _ => false + | _ => + // let fullpth = Filename_unix.realpath(f); + Printf.eprintf( + "Cannot find file %s (cwd: %s)\n", + f, + Core_unix.getcwd(), + ); + false; } - ) - |> Array.iter(~f=f => { - f - |> In_channel.create - |> In_channel.input_all - |> Sha1.update_string(ctx) - }); - Sha1.finalize(ctx) |> Sha1.to_hex; + ); + + switch (files_to_hash |> Array.length) { + | 0 => Error("No files found to hash") + | _ => + let () = + files_to_hash + |> Array.iter(~f=f => { + f + |> In_channel.create + |> In_channel.input_all + |> Sha1.update_string(ctx) + }); + Ok(Sha1.finalize(ctx) |> Sha1.to_hex); + }; }; let rec rmrf = path => { diff --git a/tests/flake_env_test_util.re b/tests/flake_env_test_util.re index e45ccaf..9444d8a 100644 --- a/tests/flake_env_test_util.re +++ b/tests/flake_env_test_util.re @@ -16,7 +16,22 @@ let _syst_to_bool = let check_exit_or_signal = Alcotest.(check(Alcotest.pair(testable_exit_or_signal, string))); -let check_string = Alcotest.(check(string)); +let testable_result_string = + Alcotest.testable( + (pp_fmt, elem) => { + switch (elem) { + | Ok(s) => Fmt.pf(pp_fmt, "Ok(%s)", s) + | Error(s) => Fmt.pf(pp_fmt, "Error(%s)", s) + } + }, + (a, b) => + switch (a, b) { + | (Ok(a), Ok(b)) => String.compare(a, b) == 0 + | (Error(a), Error(b)) => String.compare(a, b) == 0 + | _ => false + }, + ); +let check_result_string = Alcotest.(check(testable_result_string)); let check_bool = Alcotest.(check(bool)); let check_get_args = Alcotest.( @@ -47,26 +62,26 @@ let test_run_process_stdout = () => ); let test_hash_one = () => { - check_string( + check_result_string( "Hash matches", - hash_files([|"../LICENSE"|]), - "b43cf2e824eb66ba0e8f939c08072a8e307b5e5f", + Ok("32b4ac64be805d730745f6bac45a5d95174ebd10"), + hash_files([|"spit_version.sh"|]), ); }; let test_hash_multiple = () => { - check_string( + check_result_string( "Hash matches", - hash_files([|"../LICENSE", "../LICENSE"|]), - "08304d8baeed02722f81252952b00f6ac011ce0c", + Ok("e4c880fc6ab9a1b88e6be18e53fc4cec9f463d1a"), + hash_files([|"spit_version.sh", "spit_version.sh"|]), ); }; let test_hash_filters_nonexistent = () => { - check_string( + check_result_string( "Hash matches", - hash_files([|"../LICENSE", "FOOBARBAZ"|]), - "b43cf2e824eb66ba0e8f939c08072a8e307b5e5f", + Ok("32b4ac64be805d730745f6bac45a5d95174ebd10"), + hash_files([|"spit_version.sh", "FOOBARBAZ"|]), ); };