Implement 'whenjobs --daemon-status'.
[whenjobs.git] / tools / whenjobs.ml
index cfef9d6..db32eaf 100644 (file)
@@ -102,6 +102,7 @@ let rec main () =
     "-e", Arg.Unit (set_mode `Edit), " Edit and upload the script";
     "--edit", Arg.Unit (set_mode `Edit), " Edit and upload the script";
     "--get", Arg.Unit (set_mode `Get), "var Display the variable";
+    "--job-names", Arg.Unit (set_mode `JobNames), " List names of loaded jobs";
     "--jobs", Arg.Unit (set_mode `Jobs), " List running jobs";
     "-l", Arg.Unit (set_mode `List), " List the script";
     "--list", Arg.Unit (set_mode `List), " List the script";
@@ -109,6 +110,7 @@ let rec main () =
     "--set", Arg.Unit (set_mode `Set), " Set the variable";
     "--start", Arg.Unit (set_mode `Start), "name Start a job manually";
     "--tail", Arg.Unit (set_mode `Tail), "serial Tail job output";
+    "--test", Arg.Unit (set_mode `Test), " Test the effect of setting variables";
     "--type", Arg.String set_type, "bool|int|float|string|.. Set the variable type";
     "--upload", Arg.Unit (set_mode `Upload), " Upload the script";
     "--variables", Arg.Unit (set_mode `Variables), " Display all variables and values";
@@ -118,8 +120,9 @@ let rec main () =
 
   (* anon_fun normally just collects up the anonymous arguments as
    * strings, and most modes just use 'args' as a list of strings.
-   * However for `Set mode we need to record the type of each argument
-   * as well, so we keep that in a separate list (argtypes).
+   * However for `Set and `Test modes we need to record the type of
+   * each argument as well, so we keep that in a separate list
+   * (argtypes).
    *)
   let argtypes = ref [] in
   let anon_fun str = argtypes := (str, !typ) :: !argtypes in
@@ -188,6 +191,10 @@ Options:
     if nr_args > 0 then
       set_variables argtypes
 
+  | Some `Test ->
+    if nr_args > 0 then
+      test_variables argtypes
+
   | Some `Get ->
     if nr_args != 1 then (
       eprintf "whenjobs --get variable\n";
@@ -245,6 +252,10 @@ Options:
     );
     tail arg1
 
+  | Some `JobNames ->
+    unused_error args "--job-names";
+    job_names ()
+
 and edit_file () =
   (* If there is no initial file, create an empty one containing the
    * tutorial.
@@ -354,6 +365,31 @@ and set_variables argtypes =
   );
   stop_client client
 
+and test_variables argtypes =
+  let vars = List.map (
+    fun (def, typ) ->
+      (* 'def' should have the form "name=value".  The value part may
+       * be missing, but the equals sign is required.
+       *)
+      let i =
+        try String.index def '='
+        with Not_found ->
+          eprintf "whenjobs: set: missing = sign in variable definition\n";
+          suggest_help ();
+          exit 1 in
+      let name = String.sub def 0 i in
+      let value = String.sub def (i+1) (String.length def - (i+1)) in
+      let value = value_of_string value typ in
+      { Whenproto_aux.sv_name = name; sv_value = value }
+  ) argtypes in
+  let vars = Array.of_list vars in
+
+  let client = start_client () in
+  let jobnames = Whenproto_clnt.When.V1.test_variables client vars in
+  stop_client client;
+
+  Array.iter print_endline jobnames
+
 and get_variable name =
   let client = start_client () in
   let value = Whenproto_clnt.When.V1.get_variable client name in
@@ -388,7 +424,15 @@ and daemon_restart () =
   assert false
 
 and daemon_status () =
-  assert false
+  let r =
+    try
+      let client = start_client_no_exit () in
+      let r = Whenproto_clnt.When.V1.ping_daemon client () in
+      stop_client client;
+      r = `ok
+    with
+      exn -> false in
+  print_endline (if r then "up" else "down")
 
 and jobs () =
   let client = start_client () in
@@ -447,6 +491,12 @@ and tail serial =
       (Filename.quote job.Whenproto_aux.job_tmpdir) in
   exit (Sys.command cmd)
 
+and job_names () =
+  let client = start_client () in
+  let names = Whenproto_clnt.When.V1.get_job_names client () in
+  stop_client client;
+  Array.iter print_endline names
+
 and unused_error args op =
   if args <> [] then (
     eprintf "whenjobs %s: unused parameters on the command line.\n" op;
@@ -472,10 +522,7 @@ and create_tutorial file =
 and start_client () =
   let addr = sprintf "%s/socket" jobsdir in
   let client =
-    try
-      Whenproto_clnt.When.V1.create_client
-        (Rpc_client.Unix addr)
-        Rpc.Tcp (* not TCP, this is the same as SOCK_STREAM *)
+    try start_client_no_exit ()
     with
     | Unix_error ((ECONNREFUSED|ENOENT), _, _) ->
       eprintf "whenjobs: error: the daemon ('whenjobsd') is not running\n";
@@ -486,6 +533,12 @@ and start_client () =
       exit 1 in
   client
 
+and start_client_no_exit () =
+  let addr = sprintf "%s/socket" jobsdir in
+  Whenproto_clnt.When.V1.create_client
+    (Rpc_client.Unix addr)
+    Rpc.Tcp (* not TCP, this is the same as SOCK_STREAM *)
+
 and stop_client client =
   Rpc_client.shut_down client