Implement // and quote.
[goaljobs.git] / goaljobs.mli
index 752e9b7..072fcef 100644 (file)
@@ -127,7 +127,9 @@ val file_exists : string -> bool
 val file_newer_than : string -> string -> bool
   (** [file_newer_than file_a file_b] returns true if [file_a] is
       newer than [file_b].  Note that if [file_a] does not exist, it
-      returns false.  If [file_b] does not exist, it is an error. *)
+      returns false.  If [file_b] does not exist, it is an error.
+
+      There is also a goal version of this function. *)
 
 val more_recent : string list -> string list -> bool
   (** [more_recent objects sources] expresses the [make] relationship:
@@ -148,14 +150,32 @@ val more_recent : string list -> string list -> bool
       Note that both parameters are lists (since in [make] you can
       have a list of source files and a list of object files).  If you
       don't want a list, pass a single-element list containing the
-      single the object/source file. *)
+      single the object/source file.
+
+      There is also a goal version of this function. *)
 
 val url_exists : string -> bool
   (** The URL is tested to see if it exists.
 
-      This function also exists as a goal.  Writing:
-      {v require (url_exists "http://example.com");}
-      will die unless the given URL exists. *)
+      There is also a goal version of this function. *)
+
+val file_contains_string : string -> string -> bool
+  (** [file_contains_string filename str] checks if the named file
+      contains the given substring [str].
+
+      There is also a goal version of this function. *)
+
+val url_contains_string : string -> string -> bool
+  (** [url_contains_string url str] downloads the URL and checks
+      whether the content contains the given substring [str].
+
+      There is also a goal version of this function. *)
+
+val (//) : string -> string -> string
+  (** Concatenate two paths. *)
+
+val quote : string -> string
+  (** Quote the string to make it safe to pass directly to the shell. *)
 
 (** {2 Shell}
 
@@ -292,6 +312,59 @@ val memory_get : string -> string option
 val memory_delete : string -> unit
   (** Delete the [key].  If the key doesn't exist, has no effect. *)
 
+(** {2 Publishing goals}
+
+    To "publish" a goal means it's available on the command line
+    for users to use directly.
+
+    Goals that have zero arguments are {b automatically published}.
+    So for example:
+
+    {v
+    let goal clean () = sh "rm *~"
+    }
+
+    can be used on the command line:
+
+    {v ./script clean }
+
+    The special goal called [all] (if it exists) is run implicitly
+    unless the user specifies another goal.  Unlike [make], there is
+    nothing special about the first rule in the file.
+
+    You can also publish goals, especially ones which take a non-zero
+    number of parameters, by calling {!publish}.
+*)
+
+val publish : string -> (string list -> unit) -> unit
+  (** Publish the named goal.
+
+      Use this function as in this example:
+
+      {v
+      let goal compiled program sources =
+        ... stuff for building the program from sources ...
+
+      let () = publish "compiled" (
+        fun args ->
+          let program = List.hd args in
+          let sources = List.tl args in
+          require (compiled program sources)
+      )
+      }
+
+      This could be used as follows:
+
+      {v ./script compiled program main.c utils.c }
+
+      You will notice you have to write a bit of OCaml code to
+      map the string arguments from the command line on to the
+      goal arguments.  In the example it means taking the first
+      string argument as the program name, and the rest of the
+      string arguments as the source filenames.  This is also
+      the place to perform string to int conversion, checks, and
+      so on (remember that OCaml is strongly typed). *)
+
 (**/**)
 
 (* Goal versions of some common functions.  You are using these
@@ -304,8 +377,15 @@ val goal_file_exists : string -> unit
 val goal_file_newer_than : string -> string -> unit
 val goal_more_recent : string list -> string list -> unit
 val goal_url_exists : string -> unit
+val goal_file_contains_string : string -> string -> unit
+val goal_url_contains_string : string -> string -> unit
 val goal_memory_exists : string -> unit
 
+(* A single call to this function is added by the 'goaljobs' script.
+ * It is responsible for parsing the command line and so on.
+ *)
+val init : unit -> unit
+
 (* Export this so the macros can catch these exceptions. *)
 type goal_result_t = Goal_OK | Goal_failed of string
 exception Goal_result of goal_result_t