summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/args/flags.rs59
-rw-r--r--cli/args/mod.rs14
-rw-r--r--cli/standalone.rs1
-rw-r--r--cli/tests/inspector_tests.rs56
-rw-r--r--cli/tests/testdata/inspector/inspect_wait.js2
-rw-r--r--cli/worker.rs5
6 files changed, 132 insertions, 5 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index c60bc0d99..ac2b7a062 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -312,6 +312,7 @@ pub struct Flags {
pub ignore: Vec<PathBuf>,
pub import_map_path: Option<String>,
pub inspect_brk: Option<SocketAddr>,
+ pub inspect_wait: Option<SocketAddr>,
pub inspect: Option<SocketAddr>,
pub location: Option<Url>,
pub lock_write: bool,
@@ -1482,6 +1483,7 @@ fn run_subcommand<'a>() -> Command<'a> {
.arg(
watch_arg(true)
.conflicts_with("inspect")
+ .conflicts_with("inspect-wait")
.conflicts_with("inspect-brk"),
)
.arg(no_clear_screen_arg())
@@ -1622,6 +1624,7 @@ fn test_subcommand<'a>() -> Command<'a> {
.takes_value(true)
.value_name("DIR")
.conflicts_with("inspect")
+ .conflicts_with("inspect-wait")
.conflicts_with("inspect-brk")
.help("UNSTABLE: Collect coverage profile data into DIR"),
)
@@ -1964,7 +1967,20 @@ fn inspect_args(app: Command) -> Command {
.long("inspect-brk")
.value_name("HOST:PORT")
.help(
- "Activate inspector on host:port and break at start of user script",
+ "Activate inspector on host:port, wait for debugger to connect and break at the start of user script",
+ )
+ .min_values(0)
+ .max_values(1)
+ .require_equals(true)
+ .takes_value(true)
+ .validator(inspect_arg_validate),
+ )
+ .arg(
+ Arg::new("inspect-wait")
+ .long("inspect-wait")
+ .value_name("HOST:PORT")
+ .help(
+ "Activate inspector on host:port and wait for debugger to connect before running user code",
)
.min_values(0)
.max_values(1)
@@ -3040,6 +3056,15 @@ fn inspect_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
} else {
None
};
+ flags.inspect_wait = if matches.is_present("inspect-wait") {
+ if let Some(host) = matches.value_of("inspect-wait") {
+ Some(host.parse().unwrap())
+ } else {
+ Some(default())
+ }
+ } else {
+ None
+ };
}
fn import_map_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
@@ -5876,6 +5901,38 @@ mod tests {
}
#[test]
+ fn inspect_wait() {
+ let r = flags_from_vec(svec!["deno", "run", "--inspect-wait", "foo.js"]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Run(RunFlags {
+ script: "foo.js".to_string(),
+ }),
+ inspect_wait: Some("127.0.0.1:9229".parse().unwrap()),
+ ..Flags::default()
+ }
+ );
+
+ let r = flags_from_vec(svec![
+ "deno",
+ "run",
+ "--inspect-wait=127.0.0.1:3567",
+ "foo.js"
+ ]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Run(RunFlags {
+ script: "foo.js".to_string(),
+ }),
+ inspect_wait: Some("127.0.0.1:3567".parse().unwrap()),
+ ..Flags::default()
+ }
+ );
+ }
+
+ #[test]
fn compile() {
let r = flags_from_vec(svec![
"deno",
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index ebe71c7fa..de5725a48 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -341,7 +341,11 @@ impl CliOptions {
}
pub fn resolve_inspector_server(&self) -> Option<InspectorServer> {
- let maybe_inspect_host = self.flags.inspect.or(self.flags.inspect_brk);
+ let maybe_inspect_host = self
+ .flags
+ .inspect
+ .or(self.flags.inspect_brk)
+ .or(self.flags.inspect_wait);
maybe_inspect_host
.map(|host| InspectorServer::new(host, version::get_user_agent()))
}
@@ -466,13 +470,19 @@ impl CliOptions {
/// If the --inspect or --inspect-brk flags are used.
pub fn is_inspecting(&self) -> bool {
- self.flags.inspect.is_some() || self.flags.inspect_brk.is_some()
+ self.flags.inspect.is_some()
+ || self.flags.inspect_brk.is_some()
+ || self.flags.inspect_wait.is_some()
}
pub fn inspect_brk(&self) -> Option<SocketAddr> {
self.flags.inspect_brk
}
+ pub fn inspect_wait(&self) -> Option<SocketAddr> {
+ self.flags.inspect_wait
+ }
+
pub fn log_level(&self) -> Option<log::Level> {
self.flags.log_level
}
diff --git a/cli/standalone.rs b/cli/standalone.rs
index 2742f9bbd..d4bf8edb3 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -299,6 +299,7 @@ pub async fn run(
web_worker_pre_execute_module_cb: web_worker_cb,
maybe_inspector_server: None,
should_break_on_first_statement: false,
+ should_wait_for_inspector_session: false,
module_loader,
npm_resolver: None, // not currently supported
get_error_class_fn: Some(&get_error_class_name),
diff --git a/cli/tests/inspector_tests.rs b/cli/tests/inspector_tests.rs
index 0cf8cc3bb..7044469e4 100644
--- a/cli/tests/inspector_tests.rs
+++ b/cli/tests/inspector_tests.rs
@@ -13,6 +13,7 @@ use deno_runtime::deno_websocket::tokio_tungstenite::tungstenite;
use std::io::BufRead;
use std::process::Child;
use test_util as util;
+use test_util::TempDir;
use tokio::net::TcpStream;
use util::http_server;
@@ -1319,4 +1320,59 @@ mod inspector {
assert_eq!(tester.child.wait().unwrap().code(), Some(1));
}
+
+ #[tokio::test]
+ async fn inspector_wait() {
+ let script = util::testdata_path().join("inspector/inspect_wait.js");
+ let temp_dir = TempDir::new();
+
+ let child = util::deno_cmd()
+ .current_dir(temp_dir.path())
+ .arg("run")
+ .arg("--quiet")
+ .arg("-A")
+ .arg(inspect_flag_with_unique_port("--inspect-wait"))
+ .arg(script)
+ .stdout(std::process::Stdio::piped())
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .unwrap();
+
+ tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
+ assert!(!temp_dir.path().join("hello.txt").exists());
+
+ let mut tester = InspectorTester::create(child, ignore_script_parsed).await;
+
+ tester.assert_stderr_for_inspect_brk();
+ tester
+ .send_many(&[
+ json!({"id":1,"method":"Runtime.enable"}),
+ json!({"id":2,"method":"Debugger.enable"}),
+ ])
+ .await;
+ tester.assert_received_messages(
+ &[
+ r#"{"id":1,"result":{}}"#,
+ r#"{"id":2,"result":{"debuggerId":"#,
+ ],
+ &[
+ r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#,
+ ],
+ )
+ .await;
+ // TODO(bartlomieju): ideally this shouldn't be needed, but currently there's
+ // no way to express that in inspector code. Most clients always send this
+ // message anyway.
+ tester
+ .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"}))
+ .await;
+ tester
+ .assert_received_messages(&[r#"{"id":3,"result":{}}"#], &[])
+ .await;
+ assert_eq!(&tester.stderr_line(), "Debugger session started.");
+ tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
+ assert_eq!(&tester.stderr_line(), "did run");
+ assert!(temp_dir.path().join("hello.txt").exists());
+ tester.child.kill().unwrap();
+ }
}
diff --git a/cli/tests/testdata/inspector/inspect_wait.js b/cli/tests/testdata/inspector/inspect_wait.js
new file mode 100644
index 000000000..e2b10199c
--- /dev/null
+++ b/cli/tests/testdata/inspector/inspect_wait.js
@@ -0,0 +1,2 @@
+Deno.writeTextFileSync("./hello.txt", "hello world");
+console.error("did run");
diff --git a/cli/worker.rs b/cli/worker.rs
index 27cefc1b8..03d0728e6 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -472,7 +472,6 @@ async fn create_main_worker_internal(
let module_loader = CliModuleLoader::new(ps.clone());
let maybe_inspector_server = ps.maybe_inspector_server.clone();
- let should_break_on_first_statement = ps.options.inspect_brk().is_some();
let create_web_worker_cb =
create_web_worker_callback(ps.clone(), stdio.clone());
@@ -533,7 +532,8 @@ async fn create_main_worker_internal(
web_worker_preload_module_cb,
web_worker_pre_execute_module_cb,
maybe_inspector_server,
- should_break_on_first_statement,
+ should_break_on_first_statement: ps.options.inspect_brk().is_some(),
+ should_wait_for_inspector_session: ps.options.inspect_wait().is_some(),
module_loader,
npm_resolver: Some(Rc::new(ps.npm_resolver.clone())),
get_error_class_fn: Some(&errors::get_error_class_name),
@@ -755,6 +755,7 @@ mod tests {
create_web_worker_cb: Arc::new(|_| unreachable!()),
maybe_inspector_server: None,
should_break_on_first_statement: false,
+ should_wait_for_inspector_session: false,
module_loader: Rc::new(FsModuleLoader),
npm_resolver: None,
get_error_class_fn: None,