add a few more actions

This commit is contained in:
Jeremie Dimino 2017-03-03 09:18:03 +00:00
parent 987d437a99
commit 2967987356
8 changed files with 99 additions and 35 deletions

View File

@ -10,6 +10,8 @@ module Mini_shexp = struct
| Progn of 'a t list | Progn of 'a t list
| Echo of 'a | Echo of 'a
| Cat of 'a | Cat of 'a
| Copy of 'a * 'a
| Symlink of 'a * 'a
| Copy_and_add_line_directive of 'a * 'a | Copy_and_add_line_directive of 'a * 'a
| System of 'a | System of 'a
@ -22,8 +24,11 @@ module Mini_shexp = struct
; cstr_rest "progn" nil (t a) (fun l -> Progn l) ; cstr_rest "progn" nil (t a) (fun l -> Progn l)
; cstr "echo" (a @> nil) (fun x -> Echo x) ; cstr "echo" (a @> nil) (fun x -> Echo x)
; cstr "cat" (a @> nil) (fun x -> Cat x) ; cstr "cat" (a @> nil) (fun x -> Cat x)
; cstr "copy" (a @> a @> nil) (fun src dst -> ; cstr "copy" (a @> a @> nil) (fun src dst -> Copy (src, dst))
With_stdout_to (dst, Cat src)) (*
(* We don't expose symlink to the user yet since this might complicate things *)
; cstr "symlink" (a @> a @> nil) (fun src dst -> Symlink (dst, Cat src))
*)
; cstr "copy-and-add-line-directive" (a @> a @> nil) (fun src dst -> ; cstr "copy-and-add-line-directive" (a @> a @> nil) (fun src dst ->
Copy_and_add_line_directive (src, dst)) Copy_and_add_line_directive (src, dst))
; cstr "system" (a @> nil) (fun cmd -> System cmd) ; cstr "system" (a @> nil) (fun cmd -> System cmd)
@ -45,6 +50,10 @@ module Mini_shexp = struct
| Progn l -> Progn (List.map l ~f:(fun t -> expand dir t ~f)) | Progn l -> Progn (List.map l ~f:(fun t -> expand dir t ~f))
| Echo x -> Echo (f dir x) | Echo x -> Echo (f dir x)
| Cat x -> Cat (f dir x) | Cat x -> Cat (f dir x)
| Copy (x, y) ->
Copy (f dir x, f dir y)
| Symlink (x, y) ->
Symlink (f dir x, f dir y)
| Copy_and_add_line_directive (x, y) -> | Copy_and_add_line_directive (x, y) ->
Copy_and_add_line_directive (f dir x, f dir y) Copy_and_add_line_directive (f dir x, f dir y)
| System x -> System (f dir x) | System x -> System (f dir x)
@ -58,6 +67,8 @@ module Mini_shexp = struct
| Progn l -> List.fold_left l ~init:acc ~f:(fun init t -> fold t ~init ~f) | Progn l -> List.fold_left l ~init:acc ~f:(fun init t -> fold t ~init ~f)
| Echo x -> f acc x | Echo x -> f acc x
| Cat x -> f acc x | Cat x -> f acc x
| Copy (x, y) -> f (f acc x) y
| Symlink (x, y) -> f (f acc x) y
| Copy_and_add_line_directive (x, y) -> f (f acc x) y | Copy_and_add_line_directive (x, y) -> f (f acc x) y
| System x -> f acc x | System x -> f acc x
@ -69,38 +80,58 @@ module Mini_shexp = struct
| Progn l -> List (Atom "progn" :: List.map l ~f:(sexp_of_t f)) | Progn l -> List (Atom "progn" :: List.map l ~f:(sexp_of_t f))
| Echo x -> List [Atom "echo"; f x] | Echo x -> List [Atom "echo"; f x]
| Cat x -> List [Atom "cat"; f x] | Cat x -> List [Atom "cat"; f x]
| Copy (x, y) ->
List [Atom "copy"; f x; f y]
| Symlink (x, y) ->
List [Atom "symlink"; f x; f y]
| Copy_and_add_line_directive (x, y) -> | Copy_and_add_line_directive (x, y) ->
List [Atom "copy-and-add-line-directive"; f x; f y] List [Atom "copy-and-add-line-directive"; f x; f y]
| System x -> List [Atom "system"; f x] | System x -> List [Atom "system"; f x]
end end
module T = struct module Desc = struct
type 'a t = module T = struct
| Bash of 'a type 'a t =
| Shexp of 'a Mini_shexp.t | Bash of 'a
| Shexp of 'a Mini_shexp.t
let t a sexp = let t a sexp =
match sexp with match sexp with
| Atom _ -> Bash (a sexp) | Atom _ -> Bash (a sexp)
| List _ -> Shexp (Mini_shexp.t a sexp) | List _ -> Shexp (Mini_shexp.t a sexp)
type context = Path.t type context = Path.t
let expand dir t ~f = let expand dir t ~f =
match t with match t with
| Bash x -> Bash (f dir x) | Bash x -> Bash (f dir x)
| Shexp x -> Shexp (Mini_shexp.expand dir x ~f) | Shexp x -> Shexp (Mini_shexp.expand dir x ~f)
let fold t ~init ~f = let fold t ~init ~f =
match t with match t with
| Bash x -> f init x | Bash x -> f init x
| Shexp x -> Mini_shexp.fold x ~init ~f | Shexp x -> Mini_shexp.fold x ~init ~f
let sexp_of_t f : _ -> Sexp.t = function let sexp_of_t f : _ -> Sexp.t = function
| Bash a -> List [Atom "bash" ; f a] | Bash a -> List [Atom "bash" ; f a]
| Shexp a -> List [Atom "shexp" ; Mini_shexp.sexp_of_t f a] | Shexp a -> List [Atom "shexp" ; Mini_shexp.sexp_of_t f a]
end
include T
module Unexpanded = String_with_vars.Lift(T)
end end
include T type t =
{ env : string array
; dir : Path.t
; action : string Desc.t
}
module Unexpanded = String_with_vars.Lift(T) let sexp_of_t { env; dir; action } =
let open Sexp.To_sexp in
Sexp.List
[ List [ Atom "env" ; array string env ]
; List [ Atom "dir" ; string (Path.to_string dir) ]
; List [ Atom "action"; Desc.sexp_of_t string action ]
]

View File

@ -209,6 +209,34 @@ module Shexp = struct
copy_channels ic oc; copy_channels ic oc;
if tail then close_out oc); if tail then close_out oc);
return () return ()
| Copy (src, dst) ->
let src = Path.relative dir src in
let dst = Path.relative dir dst in
copy_file ~src:(Path.to_string src) ~dst:(Path.to_string dst);
return ()
| Symlink (src, dst) ->
let src = Path.relative dir src in
let dst = Path.relative dir dst in
if Sys.win32 then
copy_file ~src:(Path.to_string src) ~dst:(Path.to_string dst)
else begin
let src =
if Path.is_root dst then
Path.to_string src
else
Path.reach ~from:(Path.parent dst) src
in
let dst = Path.to_string dst in
match Unix.readlink dst with
| target ->
if target <> src then begin
Unix.unlink dst;
Unix.symlink src dst
end
| exception _ ->
Unix.symlink src dst
end;
return ()
| Copy_and_add_line_directive (src, dst) -> | Copy_and_add_line_directive (src, dst) ->
let src = Path.relative dir src in let src = Path.relative dir src in
let dst = Path.relative dir dst in let dst = Path.relative dir dst in
@ -249,7 +277,7 @@ end
let action action ~dir ~env ~targets = let action action ~dir ~env ~targets =
prim ~targets (fun () -> prim ~targets (fun () ->
match (action : _ Action.t) with match (action : _ Action.Desc.t) with
| Bash cmd -> | Bash cmd ->
Future.run Strict ~dir:(Path.to_string dir) ~env Future.run Strict ~dir:(Path.to_string dir) ~env
"/bin/bash" ["-e"; "-u"; "-o"; "pipefail"; "-c"; cmd] "/bin/bash" ["-e"; "-u"; "-o"; "pipefail"; "-c"; cmd]

View File

@ -65,7 +65,7 @@ val run
-> ('a, unit) t -> ('a, unit) t
val action val action
: string Action.t : string Action.Desc.t
-> dir:Path.t -> dir:Path.t
-> env:string array -> env:string array
-> targets:Path.t list -> targets:Path.t list

View File

@ -1295,14 +1295,14 @@ module Gen(P : Params) = struct
module Action_interpret : sig module Action_interpret : sig
val run val run
: Action.Unexpanded.t : Action.Desc.Unexpanded.t
-> dir:Path.t -> dir:Path.t
-> dep_kind:Build.lib_dep_kind -> dep_kind:Build.lib_dep_kind
-> targets:Path.t list -> targets:Path.t list
-> deps:Dep_conf.t list -> deps:Dep_conf.t list
-> (unit, unit) Build.t -> (unit, unit) Build.t
end = struct end = struct
module U = Action.Unexpanded module U = Action.Desc.Unexpanded
type resolved_forms = type resolved_forms =
{ (* Mapping from ${...} forms to their resolutions *) { (* Mapping from ${...} forms to their resolutions *)
@ -1380,7 +1380,7 @@ module Gen(P : Params) = struct
in in
let forms = extract_artifacts ~dir t in let forms = extract_artifacts ~dir t in
let t = let t =
Action.Unexpanded.expand dir t U.expand dir t
~f:(expand_string_with_vars ~artifacts:forms.artifacts ~targets ~deps) ~f:(expand_string_with_vars ~artifacts:forms.artifacts ~targets ~deps)
in in
let build = let build =
@ -1420,7 +1420,7 @@ module Gen(P : Params) = struct
let action = let action =
match alias_conf.action with match alias_conf.action with
| None -> Sexp.Atom "none" | None -> Sexp.Atom "none"
| Some a -> List [Atom "some" ; Action.Unexpanded.sexp_of_t a] in | Some a -> List [Atom "some" ; Action.Desc.Unexpanded.sexp_of_t a] in
Sexp.List [deps ; action] Sexp.List [deps ; action]
|> Sexp.to_string |> Sexp.to_string
|> Digest.string |> Digest.string

View File

@ -546,13 +546,13 @@ module Rule = struct
type t = type t =
{ targets : string list (** List of files in the current directory *) { targets : string list (** List of files in the current directory *)
; deps : Dep_conf.t list ; deps : Dep_conf.t list
; action : Action.Unexpanded.t ; action : Action.Desc.Unexpanded.t
} }
let common = let common =
field "targets" (list file_in_current_dir) >>= fun targets -> field "targets" (list file_in_current_dir) >>= fun targets ->
field "deps" (list Dep_conf.t) ~default:[] >>= fun deps -> field "deps" (list Dep_conf.t) ~default:[] >>= fun deps ->
field "action" Action.Unexpanded.t >>= fun action -> field "action" Action.Desc.Unexpanded.t >>= fun action ->
return { targets; deps; action } return { targets; deps; action }
let v1 = record common let v1 = record common
@ -660,13 +660,13 @@ module Alias_conf = struct
type t = type t =
{ name : string { name : string
; deps : Dep_conf.t list ; deps : Dep_conf.t list
; action : Action.Unexpanded.t option ; action : Action.Desc.Unexpanded.t option
} }
let common = let common =
field "name" string >>= fun name -> field "name" string >>= fun name ->
field "deps" (list Dep_conf.t) ~default:[] >>= fun deps -> field "deps" (list Dep_conf.t) ~default:[] >>= fun deps ->
field_o "action" Action.Unexpanded.t >>= fun action -> field_o "action" Action.Desc.Unexpanded.t >>= fun action ->
return return
{ name { name
; deps ; deps

View File

@ -189,7 +189,7 @@ let relative t fn =
| _ , false -> fn | _ , false -> fn
| false, true -> External.relative t fn | false, true -> External.relative t fn
let of_string t = relative "" t let of_string t = relative "" t
let absolute = let absolute =
let initial_dir = Sys.getcwd () in let initial_dir = Sys.getcwd () in

View File

@ -60,6 +60,7 @@ module type Combinators = sig
val bool : bool t val bool : bool t
val pair : 'a t -> 'b t -> ('a * 'b) t val pair : 'a t -> 'b t -> ('a * 'b) t
val list : 'a t -> 'a list t val list : 'a t -> 'a list t
val array : 'a t -> 'a array t
val option : 'a t -> 'a option t val option : 'a t -> 'a option t
val string_set : String_set.t t val string_set : String_set.t t
val string_map : 'a t -> 'a String_map.t t val string_map : 'a t -> 'a String_map.t t
@ -73,6 +74,7 @@ module To_sexp = struct
let bool b = Atom (string_of_bool b) let bool b = Atom (string_of_bool b)
let pair fa fb (a, b) = List [fa a; fb b] let pair fa fb (a, b) = List [fa a; fb b]
let list f l = List (List.map l ~f) let list f l = List (List.map l ~f)
let array f a = list f (Array.to_list a)
let option f = function let option f = function
| None -> List [] | None -> List []
| Some x -> List [f x] | Some x -> List [f x]
@ -119,6 +121,8 @@ module Of_sexp = struct
| Atom _ as sexp -> of_sexp_error sexp "List expected" | Atom _ as sexp -> of_sexp_error sexp "List expected"
| List (_, l) -> List.map l ~f | List (_, l) -> List.map l ~f
let array f sexp = Array.of_list (list f sexp)
let option f = function let option f = function
| List (_, []) -> None | List (_, []) -> None
| List (_, [x]) -> Some (f x) | List (_, [x]) -> Some (f x)

View File

@ -30,6 +30,7 @@ module type Combinators = sig
val bool : bool t val bool : bool t
val pair : 'a t -> 'b t -> ('a * 'b) t val pair : 'a t -> 'b t -> ('a * 'b) t
val list : 'a t -> 'a list t val list : 'a t -> 'a list t
val array : 'a t -> 'a array t
val option : 'a t -> 'a option t val option : 'a t -> 'a option t
val string_set : String_set.t t val string_set : String_set.t t
val string_map : 'a t -> 'a String_map.t t val string_map : 'a t -> 'a String_map.t t