Add jbuilder exec

This commit is contained in:
Jeremie Dimino 2017-03-01 12:09:57 +00:00
parent d5f78a1462
commit c88bf33131
4 changed files with 80 additions and 0 deletions

View File

@ -19,6 +19,8 @@
+ =install=
+ =uninstall=
+ =installed-libraries=
+ =exec=: execute a command in an environment similar to what you
would get after =jbuilder install=
- Added support for aliases
(#7, Rudi Grinberg)

View File

@ -449,6 +449,60 @@ let install_uninstall ~what =
let install = install_uninstall ~what:"install"
let uninstall = install_uninstall ~what:"uninstall"
let exec =
let doc =
"Execute a command in a similar environment as if installation was performed."
in
let man =
[ `S "DESCRIPTION"
; `P {|$(b,jbuilder exec -- COMMAND) should behave in the same way as if you do:|}
; `Pre " \\$ jbuilder install\n\
\ \\$ COMMAND"
; `P {|In particular if you run $(b,jbuilder exec ocaml), you will have access
to the libraries defined in the workspace using your usual directives
($(b,#require) for instance)|}
; `Blocks help_secs
]
in
let go common context prog args =
set_common common;
Future.Scheduler.go ~log:(create_log ())
(Main.setup common >>= fun setup ->
let context =
match List.find setup.contexts ~f:(fun c -> c.name = context) with
| Some ctx -> ctx
| None ->
Format.eprintf "@{<Error>Error@}: Context %S not found!@." context;
die ""
in
match Context.which context prog with
| None ->
Format.eprintf "@{<Error>Error@}: Program %S not found!@." prog;
die ""
| Some real_prog ->
let real_prog = Path.to_string real_prog in
let env = Context.env_for_exec context in
if Sys.win32 then
Future.run ~env Strict real_prog (prog :: args)
else
Unix.execve real_prog (Array.of_list (prog :: args)) env
)
in
( Term.(const go
$ common
$ Arg.(value
& opt string "default"
& info ["context"] ~docv:"CONTEXT"
~doc:{|Run the command in this build context.|}
)
$ Arg.(required
& pos 0 (some string) None (Arg.info [] ~docv:"PROG"))
$ Arg.(value
& pos_right 0 string [] (Arg.info [] ~docv:"ARGS"))
)
, Term.info "exec" ~doc ~man)
let all =
[ installed_libraries
; build_package
@ -457,6 +511,7 @@ let all =
; runtest
; install
; uninstall
; exec
]
let default =

View File

@ -323,3 +323,24 @@ let install_prefix t =
opam_config_var t "prefix" >>| function
| Some x -> Path.absolute x
| None -> Path.parent t.ocaml_bin
(* CR-someday jdimino: maybe we should just do this for [t.env] directly? *)
let env_for_exec t =
let sep = if Sys.win32 then ';' else ':' in
let cwd = Sys.getcwd () in
let extend_var var v =
let v = Filename.concat cwd (Path.to_string v) in
match get_env t.env var with
| None -> (var, v)
| Some prev -> (var, sprintf "%s%c%s" v sep prev)
in
let vars =
[ extend_var "CAML_LD_LIBRARY_PATH" (Config.local_install_dir ~context:t.name)
; extend_var "OCAMLPATH" (Path.relative
(Config.local_install_dir ~context:t.name)
"lib")
; extend_var "PATH" (Config.local_install_bin_dir ~context:t.name)
]
in
extend_env ~env:t.env ~vars:(String_map.of_alist_exn vars)

View File

@ -127,3 +127,5 @@ val extend_env : vars:string String_map.t -> env:string array -> string array
val opam_config_var : t -> string -> string option Future.t
val install_prefix : t -> Path.t Future.t
val env_for_exec : t -> string array