1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
open Printf
open Fugue
open Filepath
open Compat
open Helper
open Target
open Project
exception ProjectAlreadyExists
exception CannotRunNotInteractive
exception AbortedByUser
let rec ask v x =
printf "%s\n> %!" x;
let r = try read_line () with End_of_file -> raise AbortedByUser in
match v r with
| None -> r
| Some vp ->
printf "error: %s\n" vp;
ask v x
let rec ask_many v x =
let r = ask v x in
if r = "" then [] else r :: ask_many v x
let run () =
(* check if a project file already exists and that we run in a interactive windows *)
(try
let _ = Project.findPath () in
raise ProjectAlreadyExists
with Project.NoConfFile -> ());
if not (Unix.isatty Unix.stdout) then
raise CannotRunNotInteractive;
printf " %swelcome to the obuild wizard%s\n" (color_green ()) (color_white ());
printf " ============================\n";
let expecting_output l s =
if List.mem s l then
None
else
Some
(sprintf "expecting one of the following: %s"
(Utils.showList ", " (fun s -> "\"" ^ s ^ "\"") l))
in
(* strip [ext] from the the end of [s] only if it's there *)
let strip_ext s ~ext =
try
let l = String.length s in
let ext_l = String.length ext in
if String.sub s (l - ext_l) ext_l = ext then
String.sub s 0 (l - ext_l)
else
s
with Invalid_argument _ -> s (* in case out of bounds above *)
in
let invalid ~x = function
| true -> None
| false -> Some ("invalid " ^ x)
in
let valid_name n = invalid ~x:"name" (String_utils.all char_is_alphanum n) in
let valid_fp _ = None in
(* FIXME *)
let valid_fn n = invalid ~x:"filename" (Filepath.valid_fn n) in
let valid_modname n =
invalid ~x:"module name"
(String_utils.all Modname.char_is_valid_modchar (strip_ext n ~ext:".ml"))
in
let name = ask valid_name "What is the name of your project ?" in
let obuild =
{
Project.make with
Project.name;
Project.version = "0.0.0";
Project.synopsis = "my new project";
Project.obuild_ver = 1;
}
in
let ty =
ask (expecting_output [ "1"; "2" ]) "What do you want to build ? 1: executable, 2: library"
in
let question_obits obits =
let dir = ask valid_fp "What is the directory name where to find the source ? (default .)" in
{ obits with target_srcdir = [ fp dir ] }
in
let question_cbits cbits = cbits in
let project =
let compose f g x = f (g x) in
match ty with
| "1" ->
let main = ask valid_fn "What is the name of your main ?" in
let nexe = Executable.make name in
let itarget = nexe.Executable.target in
let target =
{
itarget with
target_obits = question_obits itarget.target_obits;
target_cbits = question_cbits itarget.target_cbits;
}
in
{ obuild with exes = [ { nexe with Executable.main = fn main; Executable.target } ] }
| "2" ->
let modules =
List.map
(fun m -> string_capitalize $ strip_ext ~ext:".ml" m)
(ask_many valid_modname "Add a module ? (enter to terminate)")
in
let nlib = Library.make_from_string name in
let itarget = nlib.Library.target in
let target =
{
itarget with
target_obits = question_obits itarget.target_obits;
target_cbits = question_cbits itarget.target_cbits;
}
in
{
obuild with
libs =
[
{
nlib with
Library.modules = List.map (compose Hier.of_modname Modname.wrap) modules;
Library.target;
};
];
}
| _ -> assert false
in
project
|