open Yojson.Safe.Util; module StringSet = Set.Make(String); module Util = Flake_env__util; [@deriving yojson] type watch = { exists: bool, modtime: int, path: string, }; [@deriving yojson] type watches = array(watch); let get = () => { let direnv_watch_str = Sys.getenv("DIRENV_WATCHES"); let (read_p, write_p) = Unix.pipe(); let pid = Unix.create_process( "direnv", [|"direnv", "show_dump", direnv_watch_str|], Unix.stdin, write_p, Unix.stderr, ); let sub_stdout = Unix.in_channel_of_descr(read_p); switch (Unix.waitpid([], pid)) { | (reported_pid, WEXITED(0)) when reported_pid == pid => Ok(watches_of_yojson(Yojson.Safe.from_channel(sub_stdout))) | _ => Error("Failed to parse watches") }; }; let get_path = doc => { let pth = doc |> member("path") |> to_string; String.sub(pth, 11, String.length(pth) - 11); }; let rec get_paths_from_doc = (doc, paths) => { let p = get_path(doc); let sub_paths = List.concat( doc |> member("inputs") |> to_assoc |> List.map(((_k, v)) => get_paths_from_doc(v, paths)), ); List.concat([[p], sub_paths]); }; let get_input_paths = () => { switch (Util.nix(["flake", "archive", "--json", "--no-write-lock-file"])) { | (WEXITED(0), output) => get_paths_from_doc(Yojson.Safe.from_string(output), []) | _ => Printf.eprintf( "Failed to parse output of `nix flake archive --json`. Ignorning flake inputs. \n", ); []; }; };