File: init.ml

package info (click to toggle)
ocaml-obuild 0.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,456 kB
  • sloc: ml: 14,491; sh: 211; ansic: 34; makefile: 11
file content (139 lines) | stat: -rw-r--r-- 3,805 bytes parent folder | download
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