X-Git-Url: http://git.annexia.org/?p=whenjobs.git;a=blobdiff_plain;f=tools%2Fwhenjobs.ml;h=cfef9d6471123975ee0759f511a6f37dc3cebc35;hp=ff166a66e6ae7c4fd063fbe07a0dd5f5d1f3e32a;hb=1d8348d52e7d5b7f23c9c86841879afdf2aa5458;hpb=3d48fedd6df4da6e10c56eb9f8d313091d2d6916 diff --git a/tools/whenjobs.ml b/tools/whenjobs.ml index ff166a6..cfef9d6 100644 --- a/tools/whenjobs.ml +++ b/tools/whenjobs.ml @@ -71,10 +71,23 @@ let jobsdir = let rec main () = (* Parse the command line arguments. *) let mode = ref None in - let typ = ref "string" in + let typ = ref `String in let set_mode m () = mode := Some m in + let set_type t = + typ := + match t with + | "bool"|"boolean" -> `Bool + | "string" -> `String + | "int" -> `Int + | "float"|"double" -> `Float + | "unit" -> `Unit + | _ -> + eprintf "whenjobs: --type: unknown type (%s)\n" t; + exit 1 + in + let display_version () = printf "%s %s\n" Config.package_name Config.package_version; exit 0 @@ -96,15 +109,20 @@ 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"; - "--type", Arg.Set_string typ, "bool|int|float|string|unit Set the variable type"; + "--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"; "-V", Arg.Unit display_version, " Display version number and exit"; "--version", Arg.Unit display_version, " Display version number and exit"; ] in - let args = ref [] in - let anon_fun str = args := str :: !args in + (* 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). + *) + let argtypes = ref [] in + let anon_fun str = argtypes := (str, !typ) :: !argtypes in let usage_msg = "\ Whenjobs is a powerful but simple cron replacement. @@ -118,7 +136,7 @@ Editing the script: Get and set variables: whenjobs --get variable - whenjobs --set variable value + whenjobs --set variable=value Start and stop the per-user daemon: @@ -132,17 +150,8 @@ Options: Arg.parse argspec anon_fun usage_msg; let mode = !mode in - let args = List.rev !args in - - let typ = match !typ with - | "bool"|"boolean" -> `Bool - | "string" -> `String - | "int" -> `Int - | "float"|"double" -> `Float - | "unit" -> `Unit - | t -> - eprintf "whenjobs: --type: unknown type (%s)\n" t; - exit 1 in + let argtypes = List.rev !argtypes in + let args = List.map fst argtypes in let nr_args = List.length args in let arg1 = match args with [] -> "" | a::_ -> a in @@ -166,13 +175,18 @@ Options: upload_file () | Some `Set -> - if List.length args != 2 then ( - eprintf "whenjobs --set variable value\n"; - eprintf "If 'value' contains spaces, you may need to quote it.\n"; + if nr_args = 2 && not (String.contains arg1 '=') then ( + eprintf "'whenjobs --set variable value' is the old whenjobs <= 0.5 syntax!\n"; + eprintf "You need to change this to:\n"; + eprintf " whenjobs --set variable=value\n"; suggest_help (); exit 1 ); - set_variable (List.hd args) (List.hd (List.tl args)) typ + (* Just ignore the case where no variables are defined, to make + * it easier to write shell scripts. + *) + if nr_args > 0 then + set_variables argtypes | Some `Get -> if nr_args != 1 then ( @@ -311,39 +325,27 @@ and upload_file () = ); stop_client client -and set_variable name value typ = - let value = match typ with - | `Bool -> - (match value with - | "true"|"t"|"yes"|"y"|"on"|"1" -> `bool_t true - | "false"|"f"|"no"|"n"|"off"|"0" -> `bool_t false - | _ -> - eprintf "whenjobs: variable does not have a boolean value\n"; - exit 1 - ) - | `String -> `string_t value - | `Int -> - (try ignore (big_int_of_string value) - with Failure _ -> - eprintf "whenjobs: variable is not an integer\n"; - exit 1 - ); - `int_t value (* the string is what we pass over the wire *) - | `Float -> - (try `float_t (float_of_string value) - with Failure _ -> - eprintf "whenjobs: variable is not a floating point number\n"; - exit 1 - ) - | `Unit -> - if value <> "" then ( - eprintf "whenjobs: unit variables must be empty strings\n"; - exit 1 - ); - `unit_t in +and set_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 - (match Whenproto_clnt.When.V1.set_variable client (name, value) with + (match Whenproto_clnt.When.V1.set_variables client vars with | `ok -> () | `error msg -> eprintf "whenjobs: set: %s\n" msg; @@ -494,6 +496,36 @@ and string_of_variable = function | `int_t i -> i (* passed on the wire as a string *) | `float_t f -> string_of_float f +and value_of_string value = function + | `Bool -> + (match value with + | "true"|"t"|"yes"|"y"|"on"|"1" -> `bool_t true + | "false"|"f"|"no"|"n"|"off"|"0" -> `bool_t false + | _ -> + eprintf "whenjobs: variable does not have a boolean value\n"; + exit 1 + ) + | `String -> `string_t value + | `Int -> + (try ignore (big_int_of_string value) + with Failure _ -> + eprintf "whenjobs: variable is not an integer\n"; + exit 1 + ); + `int_t value (* the string is what we pass over the wire *) + | `Float -> + (try `float_t (float_of_string value) + with Failure _ -> + eprintf "whenjobs: variable is not a floating point number\n"; + exit 1 + ) + | `Unit -> + if value <> "" then ( + eprintf "whenjobs: unit variables must be empty strings\n"; + exit 1 + ); + `unit_t + let () = try main () with