Add jbuilder exec
This commit is contained in:
parent
d5f78a1462
commit
c88bf33131
|
@ -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)
|
||||
|
|
55
bin/main.ml
55
bin/main.ml
|
@ -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 =
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue