Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configure and install #29

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions doc/configure.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
NAME
opam-compiler-configure - Run ./configure command

SYNOPSIS
opam-compiler configure [OPTION]... [CONFIGURE_ARGUMENT]...

ARGUMENTS
CONFIGURE_ARGUMENT
Positional arguments are passed verbatim to ./configure.

OPTIONS
--dry-run
Do not perform external commands. Print them and continue as if
they worked.

--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of `auto',
`pager', `groff' or `plain'. With `auto', the format is `pager` or
`plain' whenever the TERM env var is `dumb' or undefined.

--with=FEATURES
Create a switch with this set of features. For example --with
flambda,nnp will create a switch with the flambda and
no-naked-pointers features enabled.

20 changes: 20 additions & 0 deletions doc/dune
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,23 @@
(alias runtest)
(action
(diff create.txt create.txt.gen)))

(rule
(with-stdout-to
configure.txt.gen
(run opam-compiler configure --help=plain)))

(rule
(alias runtest)
(action
(diff configure.txt configure.txt.gen)))

(rule
(with-stdout-to
install.txt.gen
(run opam-compiler install --help=plain)))

(rule
(alias runtest)
(action
(diff install.txt install.txt.gen)))
16 changes: 16 additions & 0 deletions doc/install.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
NAME
opam-compiler-install - Run make install

SYNOPSIS
opam-compiler install [OPTION]...

OPTIONS
--dry-run
Do not perform external commands. Print them and continue as if
they worked.

--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of `auto',
`pager', `groff' or `plain'. With `auto', the format is `pager` or
`plain' whenever the TERM env var is `dumb' or undefined.

6 changes: 6 additions & 0 deletions doc/opam-compiler.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ SYNOPSIS
opam-compiler COMMAND ...

COMMANDS
configure
Run ./configure command

create
Create a switch from a compiler source

install
Run make install

OPTIONS
--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of `auto',
Expand Down
123 changes: 88 additions & 35 deletions lib/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ type t =
runner : Runner.t;
github_client : Github_client.t;
}
| Configure of { runner : Runner.t; args : string list }
| Install of { runner : Runner.t }

let eval = function
| Create { source; switch_name; configure_command; runner; github_client } ->
Op.create runner github_client source switch_name ~configure_command
| Configure { runner; args } -> Op.configure runner args
| Install { runner } -> Op.install runner

let configure_command_explicit =
let open Cmdliner.Arg in
Expand Down Expand Up @@ -43,29 +47,47 @@ let with_ =
in
value (opt (some (list conv)) None info)

let feature_args_opt =
let open Let_syntax.Cmdliner in
let+ with_ = with_ in
let ocaml_version = Ocaml_version.Releases.latest in
Option.map
(List.map (Ocaml_version.Configure_options.to_configure_flag ocaml_version))
with_

let configure_command =
let open Let_syntax.Cmdliner in
let use_command cmd = `Ok (Some cmd) in
let default = `Ok None in
let error m = `Error (false, m) in
let ret_term =
let+ explicit = configure_command_explicit and+ with_ = with_ in
match (explicit, with_) with
let+ explicit = configure_command_explicit
and+ feature_args_opt = feature_args_opt in
match (explicit, feature_args_opt) with
| Some e, None -> use_command e
| None, None -> default
| None, Some opts ->
let ocaml_version = Ocaml_version.Releases.latest in
let add_opt cmd opt =
Bos.Cmd.add_arg cmd
(Ocaml_version.Configure_options.to_configure_flag ocaml_version opt)
in
let configure = Bos.Cmd.v "./configure" in
use_command (List.fold_left add_opt configure opts)
| None, Some opts -> use_command Bos.Cmd.(v "./configure" %% of_list opts)
| Some _, Some _ ->
error "--configure-command and --with cannot be passed together."
in
Cmdliner.Term.ret ret_term

let dry_run =
let open Cmdliner.Arg in
let info =
info
~doc:
"Do not perform external commands. Print them and continue as if they \
worked."
[ "dry-run" ]
in
value (flag info)

let runner =
let open Let_syntax.Cmdliner in
let+ dry_run = dry_run in
if dry_run then Runner.dry_run else Runner.real

module Create = struct
module Source_with_original = struct
type t = { source : Source.t; original : string }
Expand Down Expand Up @@ -100,25 +122,10 @@ module Create = struct
\".\" will create a local switch in the current directory."
[ "switch" ]))

let dry_run =
let open Cmdliner.Arg in
let info =
info
~doc:
"Do not perform external commands. Print them and continue as if \
they worked."
[ "dry-run" ]
in
value (flag info)

let clients =
let github_client =
let open Let_syntax.Cmdliner in
let+ dry_run = dry_run in
let runner = if dry_run then Runner.dry_run else Runner.real in
let github_client =
if dry_run then Github_client.dry_run else Github_client.real
in
(runner, github_client)
if dry_run then Github_client.dry_run else Github_client.real

let man =
[
Expand All @@ -139,7 +146,8 @@ module Create = struct
let+ { Source_with_original.source; _ } = source
and+ switch_name = switch_name
and+ configure_command = configure_command
and+ runner, github_client = clients in
and+ runner = runner
and+ github_client = github_client in
Create { source; switch_name; configure_command; runner; github_client }

let info =
Expand All @@ -149,15 +157,60 @@ module Create = struct
let command = (term, info)
end

module Configure = struct
let configure_args =
let open Cmdliner.Arg in
value & pos_all string []
& info ~docv:"CONFIGURE_ARGUMENT"
~doc:"Positional arguments are passed verbatim to ./configure." []

let args =
let open Let_syntax.Cmdliner in
let+ configure_args = configure_args
and+ feature_args_opt = feature_args_opt in
let feature_args = Option.value feature_args_opt ~default:[] in
feature_args @ configure_args

let term =
let open Let_syntax.Cmdliner in
let+ runner = runner and+ args = args in
Configure { runner; args }

let info = Cmdliner.Term.info ~doc:"Run ./configure command" "configure"

let command = (term, info)
end

module Install = struct
let term =
let open Let_syntax.Cmdliner in
let+ runner = runner in
Install { runner }

let info = Cmdliner.Term.info ~doc:"Run make install" "install"

let command = (term, info)
end

let default =
let open Cmdliner.Term in
(ret (pure (`Help (`Auto, None))), info "opam-compiler")

let map_result f = function
| `Ok x -> `Ok (f x)
| (`Version | `Help | `Error _) as r -> r

let interpret_result =
map_result (fun op ->
match eval op with
| Ok () -> 0
| Error (`Msg msg) ->
print_endline msg;
2)

let main () =
let result = Cmdliner.Term.eval_choice default [ Create.command ] in
(match result with
| `Ok op -> eval op |> Rresult.R.failwith_error_msg
| `Version -> ()
| `Help -> ()
| `Error _ -> ());
Cmdliner.Term.exit result
let result =
Cmdliner.Term.eval_choice default
[ Create.command; Configure.command; Install.command ]
in
result |> interpret_result |> Cmdliner.Term.exit_status
5 changes: 3 additions & 2 deletions lib/import.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ let pp_cmd ppf cmd =
Bos.Cmd.to_list cmd |> List.map quote_if_needed |> String.concat " "
|> Format.pp_print_string ppf

type error = [ `Command_failed of Bos.Cmd.t | `Unknown ]
type error = [ `Command_failed of Bos.Cmd.t | `Configure_needed | `Unknown ]

let translate_error s =
let open Rresult.R in
reword_error (function
| `Unknown -> msgf "%s" s
| `Command_failed cmd -> msgf "%s - command failed: %a" s pp_cmd cmd)
| `Command_failed cmd -> msgf "%s - command failed: %a" s pp_cmd cmd
| `Configure_needed -> msgf "%s - configure step is required" s)
2 changes: 1 addition & 1 deletion lib/import.mli
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ val pp_env : Format.formatter -> (string * string) list option -> unit

val pp_cmd : Format.formatter -> Bos.Cmd.t -> unit

type error = [ `Command_failed of Bos.Cmd.t | `Unknown ]
type error = [ `Command_failed of Bos.Cmd.t | `Configure_needed | `Unknown ]

val translate_error :
string -> ('a, [< error ]) result -> ('a, [> Rresult.R.msg ]) result
27 changes: 27 additions & 0 deletions lib/op.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,30 @@ let reinstall runner mode ~configure_command =
(let* () = Opam.reinstall_compiler runner ~configure_command in
reinstall_packages_if_needed runner mode)
|> translate_error "Could not reinstall"

let configure runner args =
let open Let_syntax.Result in
(let* prefix = Opam.get_prefix runner in
let cmd = Bos.Cmd.(v "./configure" % "--prefix" % prefix %% of_list args) in
Runner.run runner cmd)
|> translate_error "Could not configure"

let file_exists runner path =
let cmd =
Bos.Cmd.(
v "grep" % "-q" % "-e" % "prefix=.*_opam" % "-e" % "prefix=.*\\.opam"
% path)
in
match Runner.run runner cmd with
| Ok () -> Ok true
| Error (`Command_failed _) -> Ok false
| Error _ as e -> e

let install runner =
let open Let_syntax.Result in
(let* exists = file_exists runner "Makefile.config" in
if not exists then Error `Configure_needed
else
let cmd = Bos.Cmd.(v "make" % "install") in
Runner.run runner cmd)
|> translate_error "Could not install"
4 changes: 4 additions & 0 deletions lib/op.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ val reinstall :
reinstall_mode ->
configure_command:Bos.Cmd.t option ->
(unit, [> Rresult.R.msg ]) result

val configure : Runner.t -> string list -> (unit, [> Rresult.R.msg ]) result

val install : Runner.t -> (unit, [> Rresult.R.msg ]) result
4 changes: 3 additions & 1 deletion lib/opam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ let set_base runner name =
let update runner name =
run_opam runner [ A "update"; switch name; ocaml_variants ]

let get_prefix runner = run_out_opam runner [ A "config"; A "var"; A "prefix" ]

let reinstall_configure runner ~configure_command =
let open Let_syntax.Result in
let* prefix = run_out_opam runner [ A "config"; A "var"; A "prefix" ] in
let* prefix = get_prefix runner in
let base_command =
Option.value configure_command ~default:Bos.Cmd.(v "./configure")
in
Expand Down
2 changes: 2 additions & 0 deletions lib/opam.mli
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ val reinstall_compiler :
val reinstall_packages : Runner.t -> (unit, error) result

val remove_switch : Runner.t -> Switch_name.t -> (unit, error) result

val get_prefix : Runner.t -> (string, error) result
2 changes: 1 addition & 1 deletion lib/runner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module Dry_run = struct

let run_out ?extra_env cmd =
Format.printf "Run_out: %a%a\n" pp_env extra_env pp_cmd cmd;
Ok "output"
Format.kasprintf Rresult.R.ok "$(%a%a)" pp_env extra_env pp_cmd cmd
end

let dry_run =
Expand Down
23 changes: 23 additions & 0 deletions test/cram/configure.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Configure calls configure with the right prefix.

$ opam-compiler configure --dry-run
Run_out: OPAMCLI=2.0 opam config var prefix
Run: ./configure --prefix "$(OPAMCLI=2.0 opam config var prefix)"

Anything after -- is passed to the configure command.

$ opam-compiler configure --dry-run -- --xxx --yyy
Run_out: OPAMCLI=2.0 opam config var prefix
Run: ./configure --prefix "$(OPAMCLI=2.0 opam config var prefix)" --xxx --yyy

Shorthand versions are supported.

$ opam-compiler configure --dry-run --with afl
Run_out: OPAMCLI=2.0 opam config var prefix
Run: ./configure --prefix "$(OPAMCLI=2.0 opam config var prefix)" --with-afl

It is possible to mix both.

$ opam-compiler configure --dry-run --with afl -- --xxx --yyy
Run_out: OPAMCLI=2.0 opam config var prefix
Run: ./configure --prefix "$(OPAMCLI=2.0 opam config var prefix)" --with-afl --xxx --yyy
Loading