forked from denoland/deno
/
main.rs
156 lines (137 loc) · 3.61 KB
/
main.rs
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate serde_json;
extern crate clap;
extern crate deno;
mod ansi;
pub mod compiler;
pub mod deno_dir;
pub mod errors;
pub mod flags;
mod fs;
mod global_timer;
mod http_body;
mod http_util;
pub mod js_errors;
pub mod modules;
pub mod msg;
pub mod msg_util;
pub mod ops;
pub mod permissions;
mod repl;
pub mod resolve_addr;
pub mod resources;
mod startup_data;
pub mod state;
mod tokio_util;
mod tokio_write;
pub mod version;
pub mod worker;
use crate::errors::RustOrJsError;
use crate::state::ThreadSafeState;
use crate::worker::Worker;
use futures::lazy;
use futures::Future;
use log::{LevelFilter, Metadata, Record};
use std::env;
static LOGGER: Logger = Logger;
struct Logger;
impl log::Log for Logger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= log::max_level()
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
println!("{} RS - {}", record.level(), record.args());
}
}
fn flush(&self) {}
}
fn print_err_and_exit(err: RustOrJsError) {
eprintln!("{}", err.to_string());
std::process::exit(1);
}
fn js_check<E>(r: Result<(), E>)
where
E: Into<RustOrJsError>,
{
if let Err(err) = r {
print_err_and_exit(err.into());
}
}
fn main() {
// Tokio swallows panics. In order to actually crash when we panic, we have
// to set this custom hook.
std::panic::set_hook(Box::new(|panic_info| {
eprintln!("{}", panic_info.to_string());
std::process::abort();
}));
#[cfg(windows)]
ansi_term::enable_ansi_support().ok(); // For Windows 10
log::set_logger(&LOGGER).unwrap();
let args = env::args().collect();
let (mut flags, mut rest_argv) =
flags::set_flags(args).unwrap_or_else(|err| {
eprintln!("{}", err);
std::process::exit(1)
});
log::set_max_level(if flags.log_debug {
LevelFilter::Debug
} else {
LevelFilter::Warn
});
if flags.fmt {
rest_argv.insert(1, "https://deno.land/std/prettier/main.ts".to_string());
flags.allow_read = true;
flags.allow_write = true;
}
let should_prefetch = flags.prefetch || flags.info;
let should_display_info = flags.info;
let state = ThreadSafeState::new(flags, rest_argv, ops::op_selector_std);
let mut main_worker = Worker::new(
"main".to_string(),
startup_data::deno_isolate_init(),
state.clone(),
);
let main_future = lazy(move || {
// Setup runtime.
js_check(main_worker.execute("denoMain()"));
if state.flags.eval {
// Wrap provided script in async function so asynchronous methods
// work. This is required until top-level await is not supported.
let js_source = format!(
"async function _topLevelWrapper(){{
{}
}}
_topLevelWrapper();
",
&state.argv[1]
);
// ATM imports in `deno eval` are not allowed
// TODO Support ES modules once Worker supports evaluating anonymous modules.
js_check(main_worker.execute(&js_source));
} else {
// Execute main module.
if let Some(main_module) = state.main_module() {
debug!("main_module {}", main_module);
js_check(main_worker.execute_mod(&main_module, should_prefetch));
if should_display_info {
// Display file info and exit. Do not run file
main_worker.print_file_info(&main_module);
std::process::exit(0);
}
}
}
main_worker.then(|result| {
js_check(result);
Ok(())
})
});
tokio_util::run(main_future);
}