Repository navigation
Expand file tree
/
Copy pathflow.ml
More file actions
118 lines (103 loc) · 3.94 KB
/
Copy pathflow.ml
File metadata and controls
118 lines (103 loc) · 3.94 KB
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
(**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
(***********************************************************************)
(* flow shell is just a simple command-dispatching main *)
(***********************************************************************)
module FlowShell : sig
val main : unit -> unit
end = struct
(* normal commands *)
let commands = [
AstCommand.command;
AutocompleteCommand.command;
CheckCommands.CheckCommand.command;
CheckCommands.FocusCheckCommand.command;
CheckContentsCommand.command;
ConfigCommand.command;
CoverageCommand.command;
BatchCoverageCommand.command;
CycleCommand.command;
GraphCommand.command;
DumpTypesCommand.command;
FindModuleCommand.command;
FindRefsCommand.command;
ForceRecheckCommand.command;
GetDefCommand.command;
GetImportsCommand.command;
IdeCommand.command;
InitCommand.command;
LspCommand.command;
LsCommand.command;
RefactorCommand.command;
SaveStateCommand.command;
ServerCommand.command;
StartCommand.command;
StopCommand.command;
SuggestCommand.command;
TypeAtPosCommand.command;
VersionCommand.command;
] @ (Extra_commands.extra_commands ())
(* status commands, which need a list of other commands *)
module StatusCommand = StatusCommands.Status(struct
let commands = commands
end)
let commands = StatusCommand.command :: commands
module DefaultCommand = StatusCommands.Default(struct
let commands = commands
end)
let commands = DefaultCommand.command :: commands
module ShellCommand = ShellCompleteCommand.Command(struct
let commands = commands
end)
let commands = ShellCommand.command :: commands
let main () =
let default_command = DefaultCommand.command in
let argv = Array.to_list Sys.argv in
let (command, argv) = match argv with
| [] -> failwith "Expected command"
| _cmd::[] -> (default_command, [])
| _cmd::next::rest ->
let subcmd = String.lowercase_ascii next in
try
let command = List.find (fun command ->
(CommandSpec.name command) = subcmd
) commands in
(command, rest)
with Not_found ->
(default_command, next::rest)
in
let command_string = CommandSpec.name command in
FlowEventLogger.set_command (Some command_string);
FlowEventLogger.init_flow_command ~version:Flow_version.version;
CommandUtils.run_command command argv
end
let _ =
(* A SIGPIPE signal happens when writing to a closed pipe (e.g. C-c, or piping to `head` which
exits after it prints enough lines). By default, SIGPIPE kills the program because this is a
sane behavior for most commands; it makes them stop processing input if they can't write it
anywhere.
We don't like being killed uncleanly like that. By ignoring SIGPIPE, the write() syscall that
normally would cause a SIGPIPE instead throws an EPIPE exception. We handle exceptions and
exit via FlowExitStatus.exit instead. *)
let () = Sys_utils.set_signal Sys.sigpipe Sys.Signal_ignore in
let () = Exception.record_backtrace true in
let () = if Sys_utils.get_env "IN_FLOW_TEST" <> None then EventLogger.disable_logging () in
try
Daemon.check_entry_point (); (* this call might not return *)
FlowShell.main ()
with
| SharedMem_js.Out_of_shared_memory as e ->
let e = Exception.wrap e in
let bt = Exception.get_backtrace_string e in
let msg = Utils.spf "Out of shared memory%s" (if bt = "" then bt else ":\n"^bt) in
FlowExitStatus.(exit ~msg Out_of_shared_memory)
| e ->
let e = Exception.wrap e in
let msg = Utils.spf "Unhandled exception: %s" (Exception.to_string e) in
FlowExitStatus.(exit ~msg Unknown_error)
(* If we haven't exited yet, let's exit now for logging's sake *)
let _ = FlowExitStatus.(exit No_error)