From 9359852ee762d46de15dbf0761b7c609911a7b5c Mon Sep 17 00:00:00 2001 From: Gabe Levi Date: Wed, 21 Nov 2018 17:16:45 -0800 Subject: [PATCH] Watchman.get_mergebase Summary: This adds an API to `Watchman` and `Watchman_lwt` which uses a one-off scm-aware watchman query to figure out the mergebase. I am adding this because I want to know when the mergebase changes. Unfortunately, I can't use an scm-aware subscription, because it would filter out files which change during a rebase. So instead, I plan to call `Watchman_lwt.get_mergebase` whenever an `hg.update` finishes, to detect when the mergebase changes. It's important to note, this will NOT use the existing connection for this one-off query. The existing connection might be used for a subscription, which means watchman might push a message to us and we may mis-interpret that message as a response. Reviewed By: jbrown215 Differential Revision: D13060161 fbshipit-source-id: db179da6dd49d38da02fc6b66c9d632a27acb445 --- hphp/hack/src/watchman/watchman.ml | 44 +++++++++++++++++++++++++--------- hphp/hack/src/watchman/watchman_sig.ml | 2 ++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/hphp/hack/src/watchman/watchman.ml b/hphp/hack/src/watchman/watchman.ml index 44397cb24c2..629d7d1ac68 100644 --- a/hphp/hack/src/watchman/watchman.ml +++ b/hphp/hack/src/watchman/watchman.ml @@ -665,19 +665,30 @@ struct | `Leave -> State_leave (name, metadata) - let make_mergebase_changed_response env data = + let extract_mergebase data = let open Hh_json.Access in let accessor = return data in - accessor >>= + let ret = + accessor >>= get_obj "clock" >>= - get_string "clock" >>= fun (clock, _) -> - accessor >>= get_obj "clock" >>= - get_obj "scm" >>= - get_string "mergebase" >>= fun (mergebase, keytrace) -> - let files = set_of_list @@ extract_file_names env data in - env.clockspec <- clock; - let response = Changed_merge_base (mergebase, files, clock) in - Ok ((env, response), keytrace) + get_string "clock" >>= + fun (clock, _) -> + accessor >>= get_obj "clock" >>= + get_obj "scm" >>= + get_string "mergebase" >>= + fun (mergebase, _) -> + return (clock, mergebase) + in + to_option ret + + let make_mergebase_changed_response env data = + match extract_mergebase data with + | None -> Error "Failed to extract mergebase" + | Some (clock, mergebase) -> + let files = set_of_list @@ extract_file_names env data in + env.clockspec <- clock; + let response = Changed_merge_base (mergebase, files, clock) in + Ok (env, response) let transform_asynchronous_get_changes_response env data = match data with | None -> @@ -685,7 +696,7 @@ struct | Some data -> begin match make_mergebase_changed_response env data with - | Ok ((env, response), _) -> env, response + | Ok (env, response) -> env, response | Error _ -> env.clockspec <- J.get_string_val "clock" data; assert_no_fresh_instance data; @@ -724,6 +735,16 @@ struct (get_changes_since_mergebase_query env) >|= extract_file_names env + let get_mergebase env = + Watchman_process.request + ~timeout:(float_of_int env.settings.init_timeout) + ~debug_logging:env.settings.debug_logging + (get_changes_since_mergebase_query env) + >|= fun response -> + match extract_mergebase response with + | Some (_clock, mergebase) -> mergebase + | None -> raise (Watchman_error "Failed to extract mergebase from response") + let flush_request ~(timeout:int) watch_root = let open Hh_json in let directive = JSON_Object [ @@ -900,6 +921,7 @@ module Watchman_mock = struct let get_changes_since_mergebase _ = [] + let get_mergebase _ = "mergebase" end module type S = sig diff --git a/hphp/hack/src/watchman/watchman_sig.ml b/hphp/hack/src/watchman/watchman_sig.ml index def50e81e50..5da18879c15 100644 --- a/hphp/hack/src/watchman/watchman_sig.ml +++ b/hphp/hack/src/watchman/watchman_sig.ml @@ -123,6 +123,8 @@ module type S = sig val get_changes_since_mergebase: env -> string list result + val get_mergebase: env -> string result + val get_changes: ?deadline:float -> watchman_instance -> (watchman_instance * changes) result val get_changes_synchronously: timeout:int -> -- 2.11.4.GIT