0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-07 23:06:50 -05:00

Merge remote-tracking branch 'upstream/main' into check-workspace-member-compiler-options

This commit is contained in:
Nayeem Rahman 2024-11-30 01:09:30 +00:00
commit 14b3eb2789
45 changed files with 1356 additions and 630 deletions

235
Cargo.lock generated
View file

@ -231,7 +231,7 @@ dependencies = [
"nom 7.1.3", "nom 7.1.3",
"num-traits", "num-traits",
"rusticata-macros", "rusticata-macros",
"thiserror", "thiserror 1.0.64",
"time", "time",
] ]
@ -1292,7 +1292,7 @@ dependencies = [
"test_server", "test_server",
"text-size", "text-size",
"text_lines", "text_lines",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-util", "tokio-util",
"tracing", "tracing",
@ -1321,13 +1321,14 @@ dependencies = [
[[package]] [[package]]
name = "deno_ast" name = "deno_ast"
version = "0.43.3" version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d00b724e06d2081a141ec1155756a0b465d413d8e2a7515221f61d482eb2ee" checksum = "eebc7aaabfdb3ddcad32aee1b62d250149dc8b35dfbdccbb125df2bdc62da952"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"deno_error",
"deno_media_type", "deno_media_type",
"deno_terminal 0.1.1", "deno_terminal 0.2.0",
"dprint-swc-ext", "dprint-swc-ext",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
@ -1358,7 +1359,7 @@ dependencies = [
"swc_visit", "swc_visit",
"swc_visit_macros", "swc_visit_macros",
"text_lines", "text_lines",
"thiserror", "thiserror 2.0.3",
"unicode-width", "unicode-width",
"url", "url",
] ]
@ -1378,7 +1379,7 @@ version = "0.174.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"deno_core", "deno_core",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"uuid", "uuid",
] ]
@ -1392,15 +1393,15 @@ dependencies = [
"rusqlite", "rusqlite",
"serde", "serde",
"sha2", "sha2",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
] ]
[[package]] [[package]]
name = "deno_cache_dir" name = "deno_cache_dir"
version = "0.13.2" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c1f52170cd7715f8006da54cde1444863a0d6fbd9c11d037a737db2dec8e22" checksum = "cca43605c8cbce6c6787e0daf227864487c07c2b31d438c0bf43d1b38da94b7f"
dependencies = [ dependencies = [
"base32", "base32",
"deno_media_type", "deno_media_type",
@ -1412,7 +1413,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
@ -1424,13 +1425,13 @@ dependencies = [
"deno_webgpu", "deno_webgpu",
"image", "image",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
name = "deno_config" name = "deno_config"
version = "0.39.2" version = "0.39.3"
source = "git+https://github.com/denoland/deno_config.git?rev=485e7a71f1057437d2a2c4adddbfbe348a812667#485e7a71f1057437d2a2c4adddbfbe348a812667" source = "git+https://github.com/denoland/deno_config.git?branch=compiler-options-from-workspace-member#81d8e844624a8f6b3961213d1480dcc923d08b11"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_package_json", "deno_package_json",
@ -1446,7 +1447,7 @@ dependencies = [
"phf", "phf",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
@ -1507,7 +1508,7 @@ dependencies = [
"chrono", "chrono",
"deno_core", "deno_core",
"saffron", "saffron",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
] ]
@ -1542,7 +1543,7 @@ dependencies = [
"sha2", "sha2",
"signature", "signature",
"spki", "spki",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"uuid", "uuid",
"x25519-dalek", "x25519-dalek",
@ -1550,9 +1551,9 @@ dependencies = [
[[package]] [[package]]
name = "deno_doc" name = "deno_doc"
version = "0.161.1" version = "0.161.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32d994915f85e873865fc341e592080a487b0a987d06177016b2d93fd62162f8" checksum = "3af787319136f3e7f73ef551c618aeec70794522e36cd75ae35132a3bad983ef"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cfg-if", "cfg-if",
@ -1577,6 +1578,29 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "deno_error"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "199c66ffd17ee1a948904d33f3d3f364573951c1f9fb3f859bfe7770bf33862a"
dependencies = [
"deno_error_macro",
"libc",
"serde",
"serde_json",
]
[[package]]
name = "deno_error_macro"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cd99df6ae75443907e1f959fc42ec6dcea67a7bd083e76cf23a117102c9a2ce"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "deno_fetch" name = "deno_fetch"
version = "0.204.0" version = "0.204.0"
@ -1601,7 +1625,7 @@ dependencies = [
"rustls-webpki", "rustls-webpki",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tokio-socks", "tokio-socks",
@ -1626,7 +1650,7 @@ dependencies = [
"serde", "serde",
"serde-value", "serde-value",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"winapi", "winapi",
] ]
@ -1649,16 +1673,16 @@ dependencies = [
"rand", "rand",
"rayon", "rayon",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"winapi", "winapi",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "deno_graph" name = "deno_graph"
version = "0.86.2" version = "0.86.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c3f4be49dad28e794ff4eeb2daaf7956c97f8557097ef6f9c3ff1292e0a5c28" checksum = "fc78ed0b4bbcb4197300f0d6e7d1edc2d2c5019cdb9dedba7ff229158441885b"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1678,7 +1702,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
"thiserror", "thiserror 2.0.3",
"twox-hash", "twox-hash",
"url", "url",
"wasm_dep_analyzer", "wasm_dep_analyzer",
@ -1718,7 +1742,7 @@ dependencies = [
"scopeguard", "scopeguard",
"serde", "serde",
"smallvec", "smallvec",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-util", "tokio-util",
] ]
@ -1772,15 +1796,15 @@ dependencies = [
"rand", "rand",
"rusqlite", "rusqlite",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
[[package]] [[package]]
name = "deno_lint" name = "deno_lint"
version = "0.68.0" version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb994e6d1b18223df0a756c7948143b35682941d615edffef60d5b38822f38ac" checksum = "ce2a040657166e39c7d59ad34230f0cc829f8ea8b7b2377038cc012ec1a1ef16"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast",
@ -1796,14 +1820,14 @@ dependencies = [
[[package]] [[package]]
name = "deno_lockfile" name = "deno_lockfile"
version = "0.23.1" version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579117d5815aa9bae0212637d6f4d5f45f9649bb2c8988dca434077545535039" checksum = "559c19feb00af0c34f0bd4a20e56e12463fafd5c5069d6005f3ce33008027eea"
dependencies = [ dependencies = [
"deno_semver", "deno_semver",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 2.0.3",
] ]
[[package]] [[package]]
@ -1828,7 +1852,7 @@ dependencies = [
"libuv-sys-lite", "libuv-sys-lite",
"log", "log",
"napi_sym", "napi_sym",
"thiserror", "thiserror 1.0.64",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -1858,7 +1882,7 @@ dependencies = [
"rustls-tokio-stream", "rustls-tokio-stream",
"serde", "serde",
"socket2", "socket2",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
] ]
@ -1942,7 +1966,7 @@ dependencies = [
"sm3", "sm3",
"spki", "spki",
"stable_deref_trait", "stable_deref_trait",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-eld", "tokio-eld",
"url", "url",
@ -1956,9 +1980,9 @@ dependencies = [
[[package]] [[package]]
name = "deno_npm" name = "deno_npm"
version = "0.25.4" version = "0.25.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b4dc4a9f1cff63d5638e7d93042f24f46300d1cc77b86f3caaa699a7ddccf7" checksum = "89ded7af9db5d9f2986a739d1b5fbe1c57f498e4f996ae4114728e7c6dad213f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1969,7 +1993,7 @@ dependencies = [
"monch", "monch",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 2.0.3",
"url", "url",
] ]
@ -1986,20 +2010,22 @@ dependencies = [
"strum", "strum",
"strum_macros", "strum_macros",
"syn 2.0.87", "syn 2.0.87",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
name = "deno_package_json" name = "deno_package_json"
version = "0.1.2" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbc4c4d3eb0960b58e8f43f9fc2d3f620fcac9a03cd85203e08db5b04e83c1f" checksum = "80b0a3d81c592624a1ae15332a04b4dc2b7c163ef1dfc7c60171f736d1babdf5"
dependencies = [ dependencies = [
"deno_error",
"deno_path_util",
"deno_semver", "deno_semver",
"indexmap 2.3.0", "indexmap 2.3.0",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 2.0.3",
"url", "url",
] ]
@ -2010,7 +2036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff25f6e08e7a0214bbacdd6f7195c7f1ebcd850c87a624e4ff06326b68b42d99" checksum = "ff25f6e08e7a0214bbacdd6f7195c7f1ebcd850c87a624e4ff06326b68b42d99"
dependencies = [ dependencies = [
"percent-encoding", "percent-encoding",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
@ -2027,7 +2053,7 @@ dependencies = [
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"which 4.4.2", "which 4.4.2",
"winapi", "winapi",
] ]
@ -2047,7 +2073,7 @@ dependencies = [
"deno_semver", "deno_semver",
"node_resolver", "node_resolver",
"test_server", "test_server",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
@ -2110,7 +2136,7 @@ dependencies = [
"signal-hook-registry", "signal-hook-registry",
"tempfile", "tempfile",
"test_server", "test_server",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-metrics", "tokio-metrics",
"twox-hash", "twox-hash",
@ -2122,32 +2148,33 @@ dependencies = [
[[package]] [[package]]
name = "deno_semver" name = "deno_semver"
version = "0.5.16" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c957c6a57c38b7dde2315df0da0ec228911e56a74f185b108a488d0401841a67" checksum = "4756be7351289726087408984db18b9eb5e0186907673f39f858d119d0162071"
dependencies = [ dependencies = [
"deno_error",
"monch", "monch",
"once_cell", "once_cell",
"serde", "serde",
"thiserror", "thiserror 2.0.3",
"url", "url",
] ]
[[package]] [[package]]
name = "deno_task_shell" name = "deno_task_shell"
version = "0.18.1" version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f444918f7102c1a5a143e9d57809e499fb4d365070519bf2e8bdb16d586af2a" checksum = "01e09966ce29f8d26b652a43355397e1df43b85759e7824196bf0ceaeaa9a2f4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures", "futures",
"glob", "glob",
"monch", "monch",
"nix",
"os_pipe", "os_pipe",
"path-dedot", "path-dedot",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-util",
] ]
[[package]] [[package]]
@ -2202,7 +2229,7 @@ dependencies = [
"rustls-tokio-stream", "rustls-tokio-stream",
"rustls-webpki", "rustls-webpki",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"webpki-roots", "webpki-roots",
] ]
@ -2248,7 +2275,7 @@ dependencies = [
"deno_console", "deno_console",
"deno_core", "deno_core",
"deno_webidl", "deno_webidl",
"thiserror", "thiserror 1.0.64",
"urlpattern", "urlpattern",
] ]
@ -2269,7 +2296,7 @@ dependencies = [
"flate2", "flate2",
"futures", "futures",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"uuid", "uuid",
] ]
@ -2281,7 +2308,7 @@ dependencies = [
"deno_core", "deno_core",
"raw-window-handle", "raw-window-handle",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"wgpu-core", "wgpu-core",
"wgpu-types", "wgpu-types",
@ -2313,7 +2340,7 @@ dependencies = [
"once_cell", "once_cell",
"rustls-tokio-stream", "rustls-tokio-stream",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
] ]
@ -2324,7 +2351,7 @@ dependencies = [
"deno_core", "deno_core",
"deno_web", "deno_web",
"rusqlite", "rusqlite",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -2396,7 +2423,7 @@ dependencies = [
"rand", "rand",
"rusqlite", "rusqlite",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"uuid", "uuid",
@ -2689,9 +2716,9 @@ dependencies = [
[[package]] [[package]]
name = "dprint-plugin-typescript" name = "dprint-plugin-typescript"
version = "0.93.2" version = "0.93.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff29fd136541e59d51946f0d2d353fefc886776f61a799ebfb5838b06cef13b" checksum = "5804d1809f6191a9261f423c41cd51a50e49567d61caa5a8f6224eea94ae0d12"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast",
@ -2837,7 +2864,7 @@ dependencies = [
"debug-ignore", "debug-ignore",
"indexmap 2.3.0", "indexmap 2.3.0",
"log", "log",
"thiserror", "thiserror 1.0.64",
"zerocopy", "zerocopy",
] ]
@ -2997,7 +3024,7 @@ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"log", "log",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
] ]
@ -3032,7 +3059,7 @@ dependencies = [
"rand", "rand",
"sha1", "sha1",
"simdutf8", "simdutf8",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"utf-8", "utf-8",
] ]
@ -3090,7 +3117,7 @@ dependencies = [
"deno_terminal 0.1.1", "deno_terminal 0.1.1",
"parking_lot", "parking_lot",
"regex", "regex",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -3564,7 +3591,7 @@ dependencies = [
"pest_derive", "pest_derive",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -3650,7 +3677,7 @@ dependencies = [
"once_cell", "once_cell",
"radix_trie", "radix_trie",
"rand", "rand",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -3673,7 +3700,7 @@ dependencies = [
"once_cell", "once_cell",
"rand", "rand",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"tinyvec", "tinyvec",
"tokio", "tokio",
"tracing", "tracing",
@ -3697,7 +3724,7 @@ dependencies = [
"resolv-conf", "resolv-conf",
"serde", "serde",
"smallvec", "smallvec",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -3715,7 +3742,7 @@ dependencies = [
"futures-util", "futures-util",
"hickory-proto", "hickory-proto",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"time", "time",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -4155,7 +4182,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"url", "url",
] ]
@ -4361,7 +4388,7 @@ dependencies = [
"anyhow", "anyhow",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"uuid", "uuid",
] ]
@ -4811,7 +4838,7 @@ dependencies = [
"serde", "serde",
"spirv", "spirv",
"termcolor", "termcolor",
"thiserror", "thiserror 1.0.64",
"unicode-xid", "unicode-xid",
] ]
@ -4901,7 +4928,7 @@ dependencies = [
"path-clean", "path-clean",
"regex", "regex",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"url", "url",
] ]
@ -5098,7 +5125,7 @@ dependencies = [
"js-sys", "js-sys",
"once_cell", "once_cell",
"pin-project-lite", "pin-project-lite",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -5128,7 +5155,7 @@ dependencies = [
"opentelemetry_sdk", "opentelemetry_sdk",
"prost", "prost",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tonic", "tonic",
"tracing", "tracing",
@ -5170,7 +5197,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"rand", "rand",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.64",
"tracing", "tracing",
] ]
@ -5354,7 +5381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95"
dependencies = [ dependencies = [
"memchr", "memchr",
"thiserror", "thiserror 1.0.64",
"ucd-trie", "ucd-trie",
] ]
@ -5768,7 +5795,7 @@ dependencies = [
"indexmap 2.3.0", "indexmap 2.3.0",
"quick-xml", "quick-xml",
"strip-ansi-escapes", "strip-ansi-escapes",
"thiserror", "thiserror 1.0.64",
"uuid", "uuid",
] ]
@ -5793,7 +5820,7 @@ dependencies = [
"quinn-udp", "quinn-udp",
"rustc-hash 1.1.0", "rustc-hash 1.1.0",
"rustls", "rustls",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -5810,7 +5837,7 @@ dependencies = [
"rustc-hash 2.0.0", "rustc-hash 2.0.0",
"rustls", "rustls",
"slab", "slab",
"thiserror", "thiserror 1.0.64",
"tinyvec", "tinyvec",
"tracing", "tracing",
] ]
@ -5959,7 +5986,7 @@ checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"libredox", "libredox",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -6583,7 +6610,7 @@ dependencies = [
"num-bigint", "num-bigint",
"serde", "serde",
"smallvec", "smallvec",
"thiserror", "thiserror 1.0.64",
"v8", "v8",
] ]
@ -7586,7 +7613,16 @@ version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl 1.0.64",
]
[[package]]
name = "thiserror"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
dependencies = [
"thiserror-impl 2.0.3",
] ]
[[package]] [[package]]
@ -7600,6 +7636,17 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "thiserror-impl"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "thousands" name = "thousands"
version = "0.2.0" version = "0.2.0"
@ -7752,7 +7799,7 @@ checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
dependencies = [ dependencies = [
"either", "either",
"futures-util", "futures-util",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
] ]
@ -8169,7 +8216,7 @@ dependencies = [
"indexmap 2.3.0", "indexmap 2.3.0",
"num-bigint", "num-bigint",
"serde", "serde",
"thiserror", "thiserror 1.0.64",
"wtf8", "wtf8",
] ]
@ -8341,7 +8388,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8" checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8"
dependencies = [ dependencies = [
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]
@ -8395,7 +8442,7 @@ dependencies = [
"rustc-hash 1.1.0", "rustc-hash 1.1.0",
"serde", "serde",
"smallvec", "smallvec",
"thiserror", "thiserror 1.0.64",
"web-sys", "web-sys",
"wgpu-hal", "wgpu-hal",
"wgpu-types", "wgpu-types",
@ -8436,7 +8483,7 @@ dependencies = [
"raw-window-handle", "raw-window-handle",
"rustc-hash 1.1.0", "rustc-hash 1.1.0",
"smallvec", "smallvec",
"thiserror", "thiserror 1.0.64",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"wgpu-types", "wgpu-types",
@ -8502,7 +8549,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b2b1bf557d947847a30eb73f79aa6cdb3eaf3ce02f5e9599438f77896a62b3c" checksum = "5b2b1bf557d947847a30eb73f79aa6cdb3eaf3ce02f5e9599438f77896a62b3c"
dependencies = [ dependencies = [
"thiserror", "thiserror 1.0.64",
"windows", "windows",
] ]
@ -8784,7 +8831,7 @@ dependencies = [
"nom 7.1.3", "nom 7.1.3",
"oid-registry", "oid-registry",
"rusticata-macros", "rusticata-macros",
"thiserror", "thiserror 1.0.64",
"time", "time",
] ]
@ -8928,7 +8975,7 @@ dependencies = [
"parking_lot", "parking_lot",
"rand", "rand",
"regex", "regex",
"thiserror", "thiserror 1.0.64",
"tokio", "tokio",
"tokio-util", "tokio-util",
"uuid", "uuid",
@ -8969,7 +9016,7 @@ dependencies = [
"flate2", "flate2",
"indexmap 2.3.0", "indexmap 2.3.0",
"memchr", "memchr",
"thiserror", "thiserror 1.0.64",
] ]
[[package]] [[package]]

View file

@ -46,19 +46,19 @@ license = "MIT"
repository = "https://github.com/denoland/deno" repository = "https://github.com/denoland/deno"
[workspace.dependencies] [workspace.dependencies]
deno_ast = { version = "=0.43.3", features = ["transpiling"] } deno_ast = { version = "=0.44.0", features = ["transpiling"] }
deno_core = { version = "0.323.0" } deno_core = { version = "0.323.0" }
deno_bench_util = { version = "0.174.0", path = "./bench_util" } deno_bench_util = { version = "0.174.0", path = "./bench_util" }
# TODO(nayeemrmn): Use proper version when https://github.com/denoland/deno_config/pull/143 lands! # TODO(nayeemrmn): Use proper version when https://github.com/denoland/deno_config/pull/143 lands!
deno_config = { git = "https://github.com/denoland/deno_config.git", rev = "485e7a71f1057437d2a2c4adddbfbe348a812667", features = ["workspace", "sync"] } deno_config = { git = "https://github.com/denoland/deno_config.git", branch = "compiler-options-from-workspace-member", features = ["workspace", "sync"] }
deno_lockfile = "=0.23.1" deno_lockfile = "=0.23.2"
deno_media_type = { version = "0.2.0", features = ["module_specifier"] } deno_media_type = { version = "0.2.0", features = ["module_specifier"] }
deno_npm = "=0.25.4" deno_npm = "=0.25.5"
deno_path_util = "=0.2.1" deno_path_util = "=0.2.1"
deno_permissions = { version = "0.40.0", path = "./runtime/permissions" } deno_permissions = { version = "0.40.0", path = "./runtime/permissions" }
deno_runtime = { version = "0.189.0", path = "./runtime" } deno_runtime = { version = "0.189.0", path = "./runtime" }
deno_semver = "=0.5.16" deno_semver = "=0.6.0"
deno_terminal = "0.2.0" deno_terminal = "0.2.0"
napi_sym = { version = "0.110.0", path = "./ext/napi/sym" } napi_sym = { version = "0.110.0", path = "./ext/napi/sym" }
test_util = { package = "test_server", path = "./tests/util/server" } test_util = { package = "test_server", path = "./tests/util/server" }
@ -116,8 +116,8 @@ console_static_text = "=0.8.1"
dashmap = "5.5.3" dashmap = "5.5.3"
data-encoding = "2.3.3" data-encoding = "2.3.3"
data-url = "=0.3.0" data-url = "=0.3.0"
deno_cache_dir = "=0.13.2" deno_cache_dir = "=0.14.0"
deno_package_json = { version = "0.1.2", default-features = false } deno_package_json = { version = "0.2.1", default-features = false }
dlopen2 = "0.6.1" dlopen2 = "0.6.1"
ecb = "=0.1.2" ecb = "=0.1.2"
elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "jwk"] } elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "jwk"] }

View file

@ -72,9 +72,9 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
deno_cache_dir.workspace = true deno_cache_dir.workspace = true
deno_config.workspace = true deno_config.workspace = true
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
deno_doc = { version = "=0.161.1", features = ["rust", "comrak"] } deno_doc = { version = "=0.161.2", features = ["rust", "comrak"] }
deno_graph = { version = "=0.86.2" } deno_graph = { version = "=0.86.3" }
deno_lint = { version = "=0.68.0", features = ["docs"] } deno_lint = { version = "=0.68.1", features = ["docs"] }
deno_lockfile.workspace = true deno_lockfile.workspace = true
deno_npm.workspace = true deno_npm.workspace = true
deno_package_json.workspace = true deno_package_json.workspace = true
@ -82,7 +82,7 @@ deno_path_util.workspace = true
deno_resolver.workspace = true deno_resolver.workspace = true
deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] }
deno_semver.workspace = true deno_semver.workspace = true
deno_task_shell = "=0.18.1" deno_task_shell = "=0.20.1"
deno_telemetry.workspace = true deno_telemetry.workspace = true
deno_terminal.workspace = true deno_terminal.workspace = true
libsui = "0.5.0" libsui = "0.5.0"
@ -108,7 +108,7 @@ dotenvy = "0.15.7"
dprint-plugin-json = "=0.19.4" dprint-plugin-json = "=0.19.4"
dprint-plugin-jupyter = "=0.1.5" dprint-plugin-jupyter = "=0.1.5"
dprint-plugin-markdown = "=0.17.8" dprint-plugin-markdown = "=0.17.8"
dprint-plugin-typescript = "=0.93.2" dprint-plugin-typescript = "=0.93.3"
env_logger = "=0.10.0" env_logger = "=0.10.0"
fancy-regex = "=0.10.0" fancy-regex = "=0.10.0"
faster-hex.workspace = true faster-hex.workspace = true

View file

@ -18,12 +18,10 @@ impl<'a> deno_config::fs::DenoConfigFs for DenoConfigFsAdapter<'a> {
fn read_to_string_lossy( fn read_to_string_lossy(
&self, &self,
path: &std::path::Path, path: &std::path::Path,
) -> Result<String, std::io::Error> { ) -> Result<std::borrow::Cow<'static, str>, std::io::Error> {
self self
.0 .0
.read_text_file_lossy_sync(path, None) .read_text_file_lossy_sync(path, None)
// todo(https://github.com/denoland/deno_config/pull/140): avoid clone
.map(|s| s.into_owned())
.map_err(|err| err.into_io_error()) .map_err(|err| err.into_io_error())
} }

View file

@ -109,9 +109,12 @@ impl CliLockfile {
let Some(pkg_json) = maybe_pkg_json else { let Some(pkg_json) = maybe_pkg_json else {
return Default::default(); return Default::default();
}; };
pkg_json let deps = pkg_json.resolve_local_package_json_deps();
.resolve_local_package_json_deps()
deps
.dependencies
.values() .values()
.chain(deps.dev_dependencies.values())
.filter_map(|dep| dep.as_ref().ok()) .filter_map(|dep| dep.as_ref().ok())
.filter_map(|dep| match dep { .filter_map(|dep| match dep {
PackageJsonDepValue::Req(req) => { PackageJsonDepValue::Req(req) => {

View file

@ -8,8 +8,10 @@ use deno_core::serde_json;
use deno_core::url::Url; use deno_core::url::Url;
use deno_package_json::PackageJsonDepValue; use deno_package_json::PackageJsonDepValue;
use deno_package_json::PackageJsonDepValueParseError; use deno_package_json::PackageJsonDepValueParseError;
use deno_package_json::PackageJsonDepWorkspaceReq;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq; use deno_semver::package::PackageReq;
use deno_semver::VersionReq;
use thiserror::Error; use thiserror::Error;
#[derive(Debug)] #[derive(Debug)]
@ -95,8 +97,14 @@ impl NpmInstallDepsProvider {
if let Some(pkg_json) = &folder.pkg_json { if let Some(pkg_json) = &folder.pkg_json {
let deps = pkg_json.resolve_local_package_json_deps(); let deps = pkg_json.resolve_local_package_json_deps();
let mut pkg_pkgs = Vec::with_capacity(deps.len()); let mut pkg_pkgs = Vec::with_capacity(
for (alias, dep) in deps { deps.dependencies.len() + deps.dev_dependencies.len(),
);
for (alias, dep) in deps
.dependencies
.into_iter()
.chain(deps.dev_dependencies.into_iter())
{
let dep = match dep { let dep = match dep {
Ok(dep) => dep, Ok(dep) => dep,
Err(err) => { Err(err) => {
@ -131,7 +139,16 @@ impl NpmInstallDepsProvider {
}); });
} }
} }
PackageJsonDepValue::Workspace(version_req) => { PackageJsonDepValue::Workspace(workspace_version_req) => {
let version_req = match workspace_version_req {
PackageJsonDepWorkspaceReq::VersionReq(version_req) => {
version_req
}
PackageJsonDepWorkspaceReq::Tilde
| PackageJsonDepWorkspaceReq::Caret => {
VersionReq::parse_from_npm("*").unwrap()
}
};
if let Some(pkg) = workspace_npm_pkgs.iter().find(|pkg| { if let Some(pkg) = workspace_npm_pkgs.iter().find(|pkg| {
pkg.matches_name_and_version_req(&alias, &version_req) pkg.matches_name_and_version_req(&alias, &version_req)
}) { }) {

15
cli/cache/mod.rs vendored
View file

@ -23,6 +23,7 @@ use deno_graph::source::Loader;
use deno_runtime::deno_fs; use deno_runtime::deno_fs;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use node_resolver::InNpmPackageChecker; use node_resolver::InNpmPackageChecker;
use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
@ -67,8 +68,11 @@ pub const CACHE_PERM: u32 = 0o644;
pub struct RealDenoCacheEnv; pub struct RealDenoCacheEnv;
impl deno_cache_dir::DenoCacheEnv for RealDenoCacheEnv { impl deno_cache_dir::DenoCacheEnv for RealDenoCacheEnv {
fn read_file_bytes(&self, path: &Path) -> std::io::Result<Vec<u8>> { fn read_file_bytes(
std::fs::read(path) &self,
path: &Path,
) -> std::io::Result<Cow<'static, [u8]>> {
std::fs::read(path).map(Cow::Owned)
} }
fn atomic_write_file( fn atomic_write_file(
@ -112,12 +116,13 @@ pub struct DenoCacheEnvFsAdapter<'a>(
); );
impl<'a> deno_cache_dir::DenoCacheEnv for DenoCacheEnvFsAdapter<'a> { impl<'a> deno_cache_dir::DenoCacheEnv for DenoCacheEnvFsAdapter<'a> {
fn read_file_bytes(&self, path: &Path) -> std::io::Result<Vec<u8>> { fn read_file_bytes(
&self,
path: &Path,
) -> std::io::Result<Cow<'static, [u8]>> {
self self
.0 .0
.read_file_sync(path, None) .read_file_sync(path, None)
// todo(https://github.com/denoland/deno_cache_dir/pull/66): avoid clone
.map(|bytes| bytes.into_owned())
.map_err(|err| err.into_io_error()) .map_err(|err| err.into_io_error())
} }

View file

@ -504,7 +504,12 @@ impl CliFactory {
let resolver = cli_options let resolver = cli_options
.create_workspace_resolver( .create_workspace_resolver(
self.file_fetcher()?, self.file_fetcher()?,
if cli_options.use_byonm() { if cli_options.use_byonm()
&& !matches!(
cli_options.sub_command(),
DenoSubcommand::Publish(_)
)
{
PackageJsonDepResolution::Disabled PackageJsonDepResolution::Disabled
} else { } else {
// todo(dsherret): this should be false for nodeModulesDir: true // todo(dsherret): this should be false for nodeModulesDir: true

View file

@ -1540,7 +1540,7 @@ mod tests {
.unwrap() .unwrap()
.unwrap() .unwrap()
.content; .content;
String::from_utf8(bytes).unwrap() String::from_utf8(bytes.into_owned()).unwrap()
} }
#[track_caller] #[track_caller]

View file

@ -41,6 +41,7 @@ use deno_path_util::url_to_file_path;
use deno_runtime::deno_node::PackageJson; use deno_runtime::deno_node::PackageJson;
use indexmap::IndexSet; use indexmap::IndexSet;
use lsp_types::ClientCapabilities; use lsp_types::ClientCapabilities;
use std::borrow::Cow;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::collections::HashMap; use std::collections::HashMap;
@ -2093,7 +2094,7 @@ impl<T: Clone> CachedFsItems<T> {
#[derive(Default)] #[derive(Default)]
struct InnerData { struct InnerData {
stat_calls: CachedFsItems<deno_config::fs::FsMetadata>, stat_calls: CachedFsItems<deno_config::fs::FsMetadata>,
read_to_string_calls: CachedFsItems<String>, read_to_string_calls: CachedFsItems<Cow<'static, str>>,
} }
#[derive(Default)] #[derive(Default)]
@ -2114,7 +2115,7 @@ impl DenoConfigFs for CachedDenoConfigFs {
fn read_to_string_lossy( fn read_to_string_lossy(
&self, &self,
path: &Path, path: &Path,
) -> Result<String, std::io::Error> { ) -> Result<Cow<'static, str>, std::io::Error> {
self self
.0 .0
.lock() .lock()

View file

@ -925,7 +925,7 @@ impl FileSystemDocuments {
let content = bytes_to_content( let content = bytes_to_content(
specifier, specifier,
media_type, media_type,
cached_file.content, cached_file.content.into_owned(),
maybe_charset, maybe_charset,
) )
.ok()?; .ok()?;

View file

@ -262,7 +262,7 @@ fn read_cached_url(
cache cache
.get(&cache.cache_item_key(url).ok()?, None) .get(&cache.cache_item_key(url).ok()?, None)
.ok()? .ok()?
.map(|f| f.content) .map(|f| f.content.into_owned())
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -1297,16 +1297,10 @@ impl TsServer {
{ {
// When an LSP request is cancelled by the client, the future this is being // When an LSP request is cancelled by the client, the future this is being
// executed under and any local variables here will be dropped at the next // executed under and any local variables here will be dropped at the next
// await point. To pass on that cancellation to the TS thread, we make this // await point. To pass on that cancellation to the TS thread, we use drop_guard
// wrapper which cancels the request's token on drop. // which cancels the request's token on drop.
struct DroppableToken(CancellationToken);
impl Drop for DroppableToken {
fn drop(&mut self) {
self.0.cancel();
}
}
let token = token.child_token(); let token = token.child_token();
let droppable_token = DroppableToken(token.clone()); let droppable_token = token.clone().drop_guard();
let (tx, mut rx) = oneshot::channel::<Result<String, AnyError>>(); let (tx, mut rx) = oneshot::channel::<Result<String, AnyError>>();
let change = self.pending_change.lock().take(); let change = self.pending_change.lock().take();
@ -1320,7 +1314,7 @@ impl TsServer {
tokio::select! { tokio::select! {
value = &mut rx => { value = &mut rx => {
let value = value??; let value = value??;
drop(droppable_token); droppable_token.disarm();
Ok(serde_json::from_str(&value)?) Ok(serde_json::from_str(&value)?)
} }
_ = token.cancelled() => { _ = token.cancelled() => {

View file

@ -9,6 +9,7 @@ use deno_npm::resolution::NpmResolutionSnapshot;
use deno_runtime::deno_io::FromRawIoHandle; use deno_runtime::deno_io::FromRawIoHandle;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_semver::Version; use deno_semver::Version;
use deno_task_shell::KillSignal;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashSet; use std::collections::HashSet;
use std::rc::Rc; use std::rc::Rc;
@ -155,6 +156,29 @@ impl<'a> LifecycleScripts<'a> {
packages: &[NpmResolutionPackage], packages: &[NpmResolutionPackage],
root_node_modules_dir_path: &Path, root_node_modules_dir_path: &Path,
progress_bar: &ProgressBar, progress_bar: &ProgressBar,
) -> Result<(), AnyError> {
let kill_signal = KillSignal::default();
let _drop_signal = kill_signal.clone().drop_guard();
// we don't run with signals forwarded because once signals
// are setup then they're process wide.
self
.finish_with_cancellation(
snapshot,
packages,
root_node_modules_dir_path,
progress_bar,
kill_signal,
)
.await
}
async fn finish_with_cancellation(
self,
snapshot: &NpmResolutionSnapshot,
packages: &[NpmResolutionPackage],
root_node_modules_dir_path: &Path,
progress_bar: &ProgressBar,
kill_signal: KillSignal,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {
self.warn_not_run_scripts()?; self.warn_not_run_scripts()?;
let get_package_path = let get_package_path =
@ -246,6 +270,7 @@ impl<'a> LifecycleScripts<'a> {
stderr: TaskStdio::piped(), stderr: TaskStdio::piped(),
stdout: TaskStdio::piped(), stdout: TaskStdio::piped(),
}), }),
kill_signal: kill_signal.clone(),
}, },
) )
.await?; .await?;

View file

@ -14,6 +14,7 @@ use deno_runtime::deno_node::NodeResolver;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_task_shell::ExecutableCommand; use deno_task_shell::ExecutableCommand;
use deno_task_shell::ExecuteResult; use deno_task_shell::ExecuteResult;
use deno_task_shell::KillSignal;
use deno_task_shell::ShellCommand; use deno_task_shell::ShellCommand;
use deno_task_shell::ShellCommandContext; use deno_task_shell::ShellCommandContext;
use deno_task_shell::ShellPipeReader; use deno_task_shell::ShellPipeReader;
@ -22,6 +23,7 @@ use lazy_regex::Lazy;
use regex::Regex; use regex::Regex;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tokio::task::LocalSet; use tokio::task::LocalSet;
use tokio_util::sync::CancellationToken;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::npm::InnerCliNpmResolverRef; use crate::npm::InnerCliNpmResolverRef;
@ -45,9 +47,11 @@ impl TaskStdio {
pub fn stdout() -> Self { pub fn stdout() -> Self {
Self(None, ShellPipeWriter::stdout()) Self(None, ShellPipeWriter::stdout())
} }
pub fn stderr() -> Self { pub fn stderr() -> Self {
Self(None, ShellPipeWriter::stderr()) Self(None, ShellPipeWriter::stderr())
} }
pub fn piped() -> Self { pub fn piped() -> Self {
let (r, w) = deno_task_shell::pipe(); let (r, w) = deno_task_shell::pipe();
Self(Some(r), w) Self(Some(r), w)
@ -62,8 +66,8 @@ pub struct TaskIo {
impl Default for TaskIo { impl Default for TaskIo {
fn default() -> Self { fn default() -> Self {
Self { Self {
stderr: TaskStdio::stderr(),
stdout: TaskStdio::stdout(), stdout: TaskStdio::stdout(),
stderr: TaskStdio::stderr(),
} }
} }
} }
@ -78,6 +82,7 @@ pub struct RunTaskOptions<'a> {
pub custom_commands: HashMap<String, Rc<dyn ShellCommand>>, pub custom_commands: HashMap<String, Rc<dyn ShellCommand>>,
pub root_node_modules_dir: Option<&'a Path>, pub root_node_modules_dir: Option<&'a Path>,
pub stdio: Option<TaskIo>, pub stdio: Option<TaskIo>,
pub kill_signal: KillSignal,
} }
pub type TaskCustomCommands = HashMap<String, Rc<dyn ShellCommand>>; pub type TaskCustomCommands = HashMap<String, Rc<dyn ShellCommand>>;
@ -96,8 +101,12 @@ pub async fn run_task(
.with_context(|| format!("Error parsing script '{}'.", opts.task_name))?; .with_context(|| format!("Error parsing script '{}'.", opts.task_name))?;
let env_vars = let env_vars =
prepare_env_vars(opts.env_vars, opts.init_cwd, opts.root_node_modules_dir); prepare_env_vars(opts.env_vars, opts.init_cwd, opts.root_node_modules_dir);
let state = let state = deno_task_shell::ShellState::new(
deno_task_shell::ShellState::new(env_vars, opts.cwd, opts.custom_commands); env_vars,
opts.cwd,
opts.custom_commands,
opts.kill_signal,
);
let stdio = opts.stdio.unwrap_or_default(); let stdio = opts.stdio.unwrap_or_default();
let ( let (
TaskStdio(stdout_read, stdout_write), TaskStdio(stdout_read, stdout_write),
@ -537,6 +546,80 @@ fn resolve_managed_npm_commands(
Ok(result) Ok(result)
} }
/// Runs a deno task future forwarding any signals received
/// to the process.
///
/// Signal listeners and ctrl+c listening will be setup.
pub async fn run_future_forwarding_signals<TOutput>(
kill_signal: KillSignal,
future: impl std::future::Future<Output = TOutput>,
) -> TOutput {
fn spawn_future_with_cancellation(
future: impl std::future::Future<Output = ()> + 'static,
token: CancellationToken,
) {
deno_core::unsync::spawn(async move {
tokio::select! {
_ = future => {}
_ = token.cancelled() => {}
}
});
}
let token = CancellationToken::new();
let _token_drop_guard = token.clone().drop_guard();
let _drop_guard = kill_signal.clone().drop_guard();
spawn_future_with_cancellation(
listen_ctrl_c(kill_signal.clone()),
token.clone(),
);
#[cfg(unix)]
spawn_future_with_cancellation(
listen_and_forward_all_signals(kill_signal),
token,
);
future.await
}
async fn listen_ctrl_c(kill_signal: KillSignal) {
while let Ok(()) = tokio::signal::ctrl_c().await {
kill_signal.send(deno_task_shell::SignalKind::SIGINT)
}
}
#[cfg(unix)]
async fn listen_and_forward_all_signals(kill_signal: KillSignal) {
use deno_core::futures::FutureExt;
use deno_runtime::signal::SIGNAL_NUMS;
// listen and forward every signal we support
let mut futures = Vec::with_capacity(SIGNAL_NUMS.len());
for signo in SIGNAL_NUMS.iter().copied() {
if signo == libc::SIGKILL || signo == libc::SIGSTOP {
continue; // skip, can't listen to these
}
let kill_signal = kill_signal.clone();
futures.push(
async move {
let Ok(mut stream) = tokio::signal::unix::signal(
tokio::signal::unix::SignalKind::from_raw(signo),
) else {
return;
};
let signal_kind: deno_task_shell::SignalKind = signo.into();
while let Some(()) = stream.recv().await {
kill_signal.send(signal_kind);
}
}
.boxed_local(),
)
}
futures::future::join_all(futures).await;
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {

View file

@ -169,7 +169,7 @@ impl Diagnostic for PublishDiagnostic {
.. ..
}) => DiagnosticLevel::Warning, }) => DiagnosticLevel::Warning,
FastCheck(_) => DiagnosticLevel::Error, FastCheck(_) => DiagnosticLevel::Error,
SpecifierUnfurl(_) => DiagnosticLevel::Warning, SpecifierUnfurl(d) => d.level(),
InvalidPath { .. } => DiagnosticLevel::Error, InvalidPath { .. } => DiagnosticLevel::Error,
DuplicatePath { .. } => DiagnosticLevel::Error, DuplicatePath { .. } => DiagnosticLevel::Error,
UnsupportedFileType { .. } => DiagnosticLevel::Warning, UnsupportedFileType { .. } => DiagnosticLevel::Warning,
@ -187,7 +187,7 @@ impl Diagnostic for PublishDiagnostic {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.code(), FastCheck(diagnostic) => diagnostic.code(),
SpecifierUnfurl(diagnostic) => Cow::Borrowed(diagnostic.code()), SpecifierUnfurl(diagnostic) => diagnostic.code(),
InvalidPath { .. } => Cow::Borrowed("invalid-path"), InvalidPath { .. } => Cow::Borrowed("invalid-path"),
DuplicatePath { .. } => Cow::Borrowed("case-insensitive-duplicate-path"), DuplicatePath { .. } => Cow::Borrowed("case-insensitive-duplicate-path"),
UnsupportedFileType { .. } => Cow::Borrowed("unsupported-file-type"), UnsupportedFileType { .. } => Cow::Borrowed("unsupported-file-type"),
@ -207,7 +207,7 @@ impl Diagnostic for PublishDiagnostic {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.message(), FastCheck(diagnostic) => diagnostic.message(),
SpecifierUnfurl(diagnostic) => Cow::Borrowed(diagnostic.message()), SpecifierUnfurl(diagnostic) => diagnostic.message(),
InvalidPath { message, .. } => Cow::Borrowed(message.as_str()), InvalidPath { message, .. } => Cow::Borrowed(message.as_str()),
DuplicatePath { .. } => { DuplicatePath { .. } => {
Cow::Borrowed("package path is a case insensitive duplicate of another path in the package") Cow::Borrowed("package path is a case insensitive duplicate of another path in the package")
@ -243,17 +243,7 @@ impl Diagnostic for PublishDiagnostic {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.location(), FastCheck(diagnostic) => diagnostic.location(),
SpecifierUnfurl(diagnostic) => match diagnostic { SpecifierUnfurl(diagnostic) => diagnostic.location(),
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport {
specifier,
text_info,
range,
} => DiagnosticLocation::ModulePosition {
specifier: Cow::Borrowed(specifier),
text_info: Cow::Borrowed(text_info),
source_pos: DiagnosticSourcePos::SourcePos(range.start),
},
},
InvalidPath { path, .. } => { InvalidPath { path, .. } => {
DiagnosticLocation::Path { path: path.clone() } DiagnosticLocation::Path { path: path.clone() }
} }
@ -325,24 +315,8 @@ impl Diagnostic for PublishDiagnostic {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.snippet(), FastCheck(d) => d.snippet(),
SpecifierUnfurl(diagnostic) => match diagnostic { SpecifierUnfurl(d) => d.snippet(),
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport {
text_info,
range,
..
} => Some(DiagnosticSnippet {
source: Cow::Borrowed(text_info),
highlights: vec![DiagnosticSnippetHighlight {
style: DiagnosticSnippetHighlightStyle::Warning,
range: DiagnosticSourceRange {
start: DiagnosticSourcePos::SourcePos(range.start),
end: DiagnosticSourcePos::SourcePos(range.end),
},
description: Some("the unanalyzable dynamic import".into()),
}],
}),
},
InvalidPath { .. } => None, InvalidPath { .. } => None,
DuplicatePath { .. } => None, DuplicatePath { .. } => None,
UnsupportedFileType { .. } => None, UnsupportedFileType { .. } => None,
@ -380,7 +354,7 @@ impl Diagnostic for PublishDiagnostic {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.hint(), FastCheck(diagnostic) => diagnostic.hint(),
SpecifierUnfurl(_) => None, SpecifierUnfurl(d) => d.hint(),
InvalidPath { .. } => Some( InvalidPath { .. } => Some(
Cow::Borrowed("rename or remove the file, or add it to 'publish.exclude' in the config file"), Cow::Borrowed("rename or remove the file, or add it to 'publish.exclude' in the config file"),
), ),
@ -436,9 +410,9 @@ impl Diagnostic for PublishDiagnostic {
None => None, None => None,
} }
} }
SyntaxError(diagnostic) => diagnostic.snippet_fixed(), SyntaxError(d) => d.snippet_fixed(),
SpecifierUnfurl(d) => d.snippet_fixed(),
FastCheck(_) FastCheck(_)
| SpecifierUnfurl(_)
| InvalidPath { .. } | InvalidPath { .. }
| DuplicatePath { .. } | DuplicatePath { .. }
| UnsupportedFileType { .. } | UnsupportedFileType { .. }
@ -453,16 +427,8 @@ impl Diagnostic for PublishDiagnostic {
fn info(&self) -> Cow<'_, [Cow<'_, str>]> { fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => { FastCheck(d) => d.info(),
diagnostic.info() SpecifierUnfurl(d) => d.info(),
}
SpecifierUnfurl(diagnostic) => match diagnostic {
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => Cow::Borrowed(&[
Cow::Borrowed("after publishing this package, imports from the local import map / package.json do not work"),
Cow::Borrowed("dynamic imports that can not be analyzed at publish time will not be rewritten automatically"),
Cow::Borrowed("make sure the dynamic import is resolvable at runtime without an import map / package.json")
]),
},
InvalidPath { .. } => Cow::Borrowed(&[ InvalidPath { .. } => Cow::Borrowed(&[
Cow::Borrowed("to portably support all platforms, including windows, the allowed characters in package paths are limited"), Cow::Borrowed("to portably support all platforms, including windows, the allowed characters in package paths are limited"),
]), ]),
@ -503,10 +469,8 @@ impl Diagnostic for PublishDiagnostic {
fn docs_url(&self) -> Option<Cow<'_, str>> { fn docs_url(&self) -> Option<Cow<'_, str>> {
use PublishDiagnostic::*; use PublishDiagnostic::*;
match &self { match &self {
FastCheck(diagnostic) => diagnostic.docs_url(), FastCheck(d) => d.docs_url(),
SpecifierUnfurl(diagnostic) => match diagnostic { SpecifierUnfurl(d) => d.docs_url(),
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => None,
},
InvalidPath { .. } => { InvalidPath { .. } => {
Some(Cow::Borrowed("https://jsr.io/go/invalid-path")) Some(Cow::Borrowed("https://jsr.io/go/invalid-path"))
} }

View file

@ -14,7 +14,6 @@ use base64::Engine;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_config::deno_json::ConfigFile; use deno_config::deno_json::ConfigFile;
use deno_config::workspace::JsrPackageConfig; use deno_config::workspace::JsrPackageConfig;
use deno_config::workspace::PackageJsonDepResolution;
use deno_config::workspace::Workspace; use deno_config::workspace::Workspace;
use deno_core::anyhow::bail; use deno_core::anyhow::bail;
use deno_core::anyhow::Context; use deno_core::anyhow::Context;
@ -44,8 +43,6 @@ use crate::cache::ParsedSourceCache;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::graph_util::ModuleGraphCreator; use crate::graph_util::ModuleGraphCreator;
use crate::http_util::HttpClient; use crate::http_util::HttpClient;
use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs;
use crate::tools::check::CheckOptions; use crate::tools::check::CheckOptions;
use crate::tools::lint::collect_no_slow_type_diagnostics; use crate::tools::lint::collect_no_slow_type_diagnostics;
use crate::tools::registry::diagnostics::PublishDiagnostic; use crate::tools::registry::diagnostics::PublishDiagnostic;
@ -123,19 +120,8 @@ pub async fn publish(
} }
let specifier_unfurler = Arc::new(SpecifierUnfurler::new( let specifier_unfurler = Arc::new(SpecifierUnfurler::new(
if cli_options.unstable_sloppy_imports() { cli_factory.sloppy_imports_resolver()?.cloned(),
Some(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new( cli_factory.workspace_resolver().await?.clone(),
cli_factory.fs().clone(),
)))
} else {
None
},
cli_options
.create_workspace_resolver(
cli_factory.file_fetcher()?,
PackageJsonDepResolution::Enabled,
)
.await?,
cli_options.unstable_bare_node_builtins(), cli_options.unstable_bare_node_builtins(),
)); ));

View file

@ -19,8 +19,7 @@ use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::serde_json; use deno_core::serde_json;
use deno_graph::FillFromLockfileOptions; use deno_graph::FillFromLockfileOptions;
use deno_package_json::PackageJsonDepValue; use deno_package_json::PackageJsonDepsMap;
use deno_package_json::PackageJsonDepValueParseError;
use deno_package_json::PackageJsonRc; use deno_package_json::PackageJsonRc;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use deno_semver::jsr::JsrPackageReqReference; use deno_semver::jsr::JsrPackageReqReference;
@ -32,7 +31,6 @@ use deno_semver::VersionReq;
use import_map::ImportMap; use import_map::ImportMap;
use import_map::ImportMapWithDiagnostics; use import_map::ImportMapWithDiagnostics;
use import_map::SpecifierMapEntry; use import_map::SpecifierMapEntry;
use indexmap::IndexMap;
use tokio::sync::Semaphore; use tokio::sync::Semaphore;
use crate::args::CliLockfile; use crate::args::CliLockfile;
@ -269,94 +267,6 @@ enum PackageJsonDepKind {
Dev, Dev,
} }
type PackageJsonDeps = IndexMap<
String,
Result<
(PackageJsonDepKind, PackageJsonDepValue),
PackageJsonDepValueParseError,
>,
>;
/// Resolve the package.json's dependencies.
// TODO(nathanwhit): Remove once we update deno_package_json with dev deps split out
fn resolve_local_package_json_deps(
package_json: &PackageJsonRc,
) -> PackageJsonDeps {
/// Gets the name and raw version constraint for a registry info or
/// package.json dependency entry taking into account npm package aliases.
fn parse_dep_entry_name_and_raw_version<'a>(
key: &'a str,
value: &'a str,
) -> (&'a str, &'a str) {
if let Some(package_and_version) = value.strip_prefix("npm:") {
if let Some((name, version)) = package_and_version.rsplit_once('@') {
// if empty, then the name was scoped and there's no version
if name.is_empty() {
(package_and_version, "*")
} else {
(name, version)
}
} else {
(package_and_version, "*")
}
} else {
(key, value)
}
}
fn parse_entry(
key: &str,
value: &str,
) -> Result<PackageJsonDepValue, PackageJsonDepValueParseError> {
if let Some(workspace_key) = value.strip_prefix("workspace:") {
let version_req = VersionReq::parse_from_npm(workspace_key)?;
return Ok(PackageJsonDepValue::Workspace(version_req));
}
if value.starts_with("file:")
|| value.starts_with("git:")
|| value.starts_with("http:")
|| value.starts_with("https:")
{
return Err(PackageJsonDepValueParseError::Unsupported {
scheme: value.split(':').next().unwrap().to_string(),
});
}
let (name, version_req) = parse_dep_entry_name_and_raw_version(key, value);
let result = VersionReq::parse_from_npm(version_req);
match result {
Ok(version_req) => Ok(PackageJsonDepValue::Req(PackageReq {
name: name.to_string(),
version_req,
})),
Err(err) => Err(PackageJsonDepValueParseError::VersionReq(err)),
}
}
fn insert_deps(
deps: Option<&IndexMap<String, String>>,
result: &mut PackageJsonDeps,
kind: PackageJsonDepKind,
) {
if let Some(deps) = deps {
for (key, value) in deps {
result.entry(key.to_string()).or_insert_with(|| {
parse_entry(key, value).map(|entry| (kind, entry))
});
}
}
}
let deps = package_json.dependencies.as_ref();
let dev_deps = package_json.dev_dependencies.as_ref();
let mut result = IndexMap::new();
// favors the deps over dev_deps
insert_deps(deps, &mut result, PackageJsonDepKind::Normal);
insert_deps(dev_deps, &mut result, PackageJsonDepKind::Dev);
result
}
fn add_deps_from_deno_json( fn add_deps_from_deno_json(
deno_json: &Arc<ConfigFile>, deno_json: &Arc<ConfigFile>,
mut filter: impl DepFilter, mut filter: impl DepFilter,
@ -406,40 +316,64 @@ fn add_deps_from_deno_json(
fn add_deps_from_package_json( fn add_deps_from_package_json(
package_json: &PackageJsonRc, package_json: &PackageJsonRc,
mut filter: impl DepFilter, filter: impl DepFilter,
deps: &mut Vec<Dep>, deps: &mut Vec<Dep>,
) { ) {
let package_json_deps = resolve_local_package_json_deps(package_json); let package_json_deps = package_json.resolve_local_package_json_deps();
for (k, v) in package_json_deps {
let (package_dep_kind, v) = match v { fn iterate(
Ok((k, v)) => (k, v), package_json: &PackageJsonRc,
Err(e) => { mut filter: impl DepFilter,
log::warn!("bad package json dep value: {e}"); package_dep_kind: PackageJsonDepKind,
continue; package_json_deps: PackageJsonDepsMap,
} deps: &mut Vec<Dep>,
}; ) {
match v { for (k, v) in package_json_deps {
deno_package_json::PackageJsonDepValue::Req(req) => { let v = match v {
let alias = k.as_str(); Ok(v) => v,
let alias = (alias != req.name).then(|| alias.to_string()); Err(e) => {
if !filter.should_include(alias.as_deref(), &req, DepKind::Npm) { log::warn!("bad package json dep value: {e}");
continue; continue;
} }
let id = DepId(deps.len()); };
deps.push(Dep { match v {
id, deno_package_json::PackageJsonDepValue::Req(req) => {
kind: DepKind::Npm, let alias = k.as_str();
location: DepLocation::PackageJson( let alias = (alias != req.name).then(|| alias.to_string());
package_json.clone(), if !filter.should_include(alias.as_deref(), &req, DepKind::Npm) {
KeyPath::from_parts([package_dep_kind.into(), k.into()]), continue;
), }
req, let id = DepId(deps.len());
alias, deps.push(Dep {
}) id,
kind: DepKind::Npm,
location: DepLocation::PackageJson(
package_json.clone(),
KeyPath::from_parts([package_dep_kind.into(), k.into()]),
),
req,
alias,
})
}
deno_package_json::PackageJsonDepValue::Workspace(_) => continue,
} }
deno_package_json::PackageJsonDepValue::Workspace(_) => continue,
} }
} }
iterate(
package_json,
filter,
PackageJsonDepKind::Normal,
package_json_deps.dependencies,
deps,
);
iterate(
package_json,
filter,
PackageJsonDepKind::Dev,
package_json_deps.dev_dependencies,
deps,
);
} }
fn deps_from_workspace( fn deps_from_workspace(

View file

@ -1,19 +1,35 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
use std::sync::Arc;
use deno_ast::diagnostics::Diagnostic;
use deno_ast::diagnostics::DiagnosticLevel;
use deno_ast::diagnostics::DiagnosticLocation;
use deno_ast::diagnostics::DiagnosticSnippet;
use deno_ast::diagnostics::DiagnosticSnippetHighlight;
use deno_ast::diagnostics::DiagnosticSnippetHighlightStyle;
use deno_ast::diagnostics::DiagnosticSourcePos;
use deno_ast::diagnostics::DiagnosticSourceRange;
use deno_ast::ParsedSource; use deno_ast::ParsedSource;
use deno_ast::SourceRange; use deno_ast::SourceRange;
use deno_ast::SourceTextInfo; use deno_ast::SourceTextInfo;
use deno_ast::SourceTextProvider;
use deno_config::workspace::MappedResolution; use deno_config::workspace::MappedResolution;
use deno_config::workspace::PackageJsonDepResolution; use deno_config::workspace::PackageJsonDepResolution;
use deno_config::workspace::WorkspaceResolver; use deno_config::workspace::WorkspaceResolver;
use deno_core::anyhow;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::DependencyDescriptor; use deno_graph::DependencyDescriptor;
use deno_graph::DynamicTemplatePart; use deno_graph::DynamicTemplatePart;
use deno_graph::ParserModuleAnalyzer; use deno_graph::ParserModuleAnalyzer;
use deno_graph::TypeScriptReference; use deno_graph::TypeScriptReference;
use deno_package_json::PackageJsonDepValue; use deno_package_json::PackageJsonDepValue;
use deno_package_json::PackageJsonDepWorkspaceReq;
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind; use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
use deno_runtime::deno_node::is_builtin_node_module; use deno_runtime::deno_node::is_builtin_node_module;
use deno_semver::Version;
use deno_semver::VersionReq;
use crate::resolver::CliSloppyImportsResolver; use crate::resolver::CliSloppyImportsResolver;
@ -24,34 +40,163 @@ pub enum SpecifierUnfurlerDiagnostic {
text_info: SourceTextInfo, text_info: SourceTextInfo,
range: SourceRange, range: SourceRange,
}, },
ResolvingNpmWorkspacePackage {
specifier: ModuleSpecifier,
package_name: String,
text_info: SourceTextInfo,
range: SourceRange,
reason: String,
},
} }
impl SpecifierUnfurlerDiagnostic { impl Diagnostic for SpecifierUnfurlerDiagnostic {
pub fn code(&self) -> &'static str { fn level(&self) -> DiagnosticLevel {
match self { match self {
Self::UnanalyzableDynamicImport { .. } => "unanalyzable-dynamic-import", SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => {
} DiagnosticLevel::Warning
} }
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage { .. } => {
pub fn message(&self) -> &'static str { DiagnosticLevel::Error
match self {
Self::UnanalyzableDynamicImport { .. } => {
"unable to analyze dynamic import"
} }
} }
} }
fn code(&self) -> Cow<'_, str> {
match self {
Self::UnanalyzableDynamicImport { .. } => "unanalyzable-dynamic-import",
Self::ResolvingNpmWorkspacePackage { .. } => "npm-workspace-package",
}
.into()
}
fn message(&self) -> Cow<'_, str> {
match self {
Self::UnanalyzableDynamicImport { .. } => {
"unable to analyze dynamic import".into()
}
Self::ResolvingNpmWorkspacePackage {
package_name,
reason,
..
} => format!(
"failed resolving npm workspace package '{}': {}",
package_name, reason
)
.into(),
}
}
fn location(&self) -> deno_ast::diagnostics::DiagnosticLocation {
match self {
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport {
specifier,
text_info,
range,
} => DiagnosticLocation::ModulePosition {
specifier: Cow::Borrowed(specifier),
text_info: Cow::Borrowed(text_info),
source_pos: DiagnosticSourcePos::SourcePos(range.start),
},
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage {
specifier,
text_info,
range,
..
} => DiagnosticLocation::ModulePosition {
specifier: Cow::Borrowed(specifier),
text_info: Cow::Borrowed(text_info),
source_pos: DiagnosticSourcePos::SourcePos(range.start),
},
}
}
fn snippet(&self) -> Option<deno_ast::diagnostics::DiagnosticSnippet<'_>> {
match self {
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport {
text_info,
range,
..
} => Some(DiagnosticSnippet {
source: Cow::Borrowed(text_info),
highlights: vec![DiagnosticSnippetHighlight {
style: DiagnosticSnippetHighlightStyle::Warning,
range: DiagnosticSourceRange {
start: DiagnosticSourcePos::SourcePos(range.start),
end: DiagnosticSourcePos::SourcePos(range.end),
},
description: Some("the unanalyzable dynamic import".into()),
}],
}),
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage {
text_info,
range,
..
} => Some(DiagnosticSnippet {
source: Cow::Borrowed(text_info),
highlights: vec![DiagnosticSnippetHighlight {
style: DiagnosticSnippetHighlightStyle::Warning,
range: DiagnosticSourceRange {
start: DiagnosticSourcePos::SourcePos(range.start),
end: DiagnosticSourcePos::SourcePos(range.end),
},
description: Some("the unresolved import".into()),
}],
}),
}
}
fn hint(&self) -> Option<Cow<'_, str>> {
match self {
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => {
None
}
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage { .. } => Some(
"make sure the npm workspace package is resolvable and has a version field in its package.json".into()
),
}
}
fn snippet_fixed(
&self,
) -> Option<deno_ast::diagnostics::DiagnosticSnippet<'_>> {
None
}
fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
match self {
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => Cow::Borrowed(&[
Cow::Borrowed("after publishing this package, imports from the local import map / package.json do not work"),
Cow::Borrowed("dynamic imports that can not be analyzed at publish time will not be rewritten automatically"),
Cow::Borrowed("make sure the dynamic import is resolvable at runtime without an import map / package.json")
]),
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage { .. } => {
Cow::Borrowed(&[])
},
}
}
fn docs_url(&self) -> Option<Cow<'_, str>> {
None
}
}
enum UnfurlSpecifierError {
Workspace {
package_name: String,
reason: String,
},
} }
pub struct SpecifierUnfurler { pub struct SpecifierUnfurler {
sloppy_imports_resolver: Option<CliSloppyImportsResolver>, sloppy_imports_resolver: Option<Arc<CliSloppyImportsResolver>>,
workspace_resolver: WorkspaceResolver, workspace_resolver: Arc<WorkspaceResolver>,
bare_node_builtins: bool, bare_node_builtins: bool,
} }
impl SpecifierUnfurler { impl SpecifierUnfurler {
pub fn new( pub fn new(
sloppy_imports_resolver: Option<CliSloppyImportsResolver>, sloppy_imports_resolver: Option<Arc<CliSloppyImportsResolver>>,
workspace_resolver: WorkspaceResolver, workspace_resolver: Arc<WorkspaceResolver>,
bare_node_builtins: bool, bare_node_builtins: bool,
) -> Self { ) -> Self {
debug_assert_eq!( debug_assert_eq!(
@ -65,11 +210,45 @@ impl SpecifierUnfurler {
} }
} }
fn unfurl_specifier_reporting_diagnostic(
&self,
referrer: &ModuleSpecifier,
specifier: &str,
text_info: &SourceTextInfo,
range: &deno_graph::PositionRange,
diagnostic_reporter: &mut dyn FnMut(SpecifierUnfurlerDiagnostic),
) -> Option<String> {
match self.unfurl_specifier(referrer, specifier) {
Ok(maybe_unfurled) => maybe_unfurled,
Err(diagnostic) => match diagnostic {
UnfurlSpecifierError::Workspace {
package_name,
reason,
} => {
let range = to_range(text_info, range);
diagnostic_reporter(
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage {
specifier: referrer.clone(),
package_name,
text_info: text_info.clone(),
range: SourceRange::new(
text_info.start_pos() + range.start,
text_info.start_pos() + range.end,
),
reason,
},
);
None
}
},
}
}
fn unfurl_specifier( fn unfurl_specifier(
&self, &self,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
specifier: &str, specifier: &str,
) -> Option<String> { ) -> Result<Option<String>, UnfurlSpecifierError> {
let resolved = if let Ok(resolved) = let resolved = if let Ok(resolved) =
self.workspace_resolver.resolve(specifier, referrer) self.workspace_resolver.resolve(specifier, referrer)
{ {
@ -120,8 +299,40 @@ impl SpecifierUnfurler {
)) ))
.ok() .ok()
} }
PackageJsonDepValue::Workspace(version_req) => { PackageJsonDepValue::Workspace(workspace_version_req) => {
// todo(#24612): consider warning or error when this is also a jsr package? let version_req = match workspace_version_req {
PackageJsonDepWorkspaceReq::VersionReq(version_req) => {
Cow::Borrowed(version_req)
}
PackageJsonDepWorkspaceReq::Caret => {
let version = self
.find_workspace_npm_dep_version(alias)
.map_err(|err| UnfurlSpecifierError::Workspace {
package_name: alias.to_string(),
reason: err.to_string(),
})?;
// version was validated, so ok to unwrap
Cow::Owned(
VersionReq::parse_from_npm(&format!("^{}", version))
.unwrap(),
)
}
PackageJsonDepWorkspaceReq::Tilde => {
let version = self
.find_workspace_npm_dep_version(alias)
.map_err(|err| UnfurlSpecifierError::Workspace {
package_name: alias.to_string(),
reason: err.to_string(),
})?;
// version was validated, so ok to unwrap
Cow::Owned(
VersionReq::parse_from_npm(&format!("~{}", version))
.unwrap(),
)
}
};
// todo(#24612): warn when this is also a jsr package telling
// people to map the specifiers in the import map
ModuleSpecifier::parse(&format!( ModuleSpecifier::parse(&format!(
"npm:{}@{}{}", "npm:{}@{}{}",
alias, alias,
@ -151,10 +362,14 @@ impl SpecifierUnfurler {
None if self.bare_node_builtins && is_builtin_node_module(specifier) => { None if self.bare_node_builtins && is_builtin_node_module(specifier) => {
format!("node:{specifier}").parse().unwrap() format!("node:{specifier}").parse().unwrap()
} }
None => ModuleSpecifier::options() None => match ModuleSpecifier::options()
.base_url(Some(referrer)) .base_url(Some(referrer))
.parse(specifier) .parse(specifier)
.ok()?, .ok()
{
Some(value) => value,
None => return Ok(None),
},
}; };
// TODO(lucacasonato): this requires integration in deno_graph first // TODO(lucacasonato): this requires integration in deno_graph first
// let resolved = if let Ok(specifier) = // let resolved = if let Ok(specifier) =
@ -188,7 +403,7 @@ impl SpecifierUnfurler {
}; };
let relative_resolved = relative_url(&resolved, referrer); let relative_resolved = relative_url(&resolved, referrer);
if relative_resolved == specifier { if relative_resolved == specifier {
None // nothing to unfurl Ok(None) // nothing to unfurl
} else { } else {
log::debug!( log::debug!(
"Unfurled specifier: {} from {} -> {}", "Unfurled specifier: {} from {} -> {}",
@ -196,7 +411,29 @@ impl SpecifierUnfurler {
referrer, referrer,
relative_resolved relative_resolved
); );
Some(relative_resolved) Ok(Some(relative_resolved))
}
}
fn find_workspace_npm_dep_version(
&self,
pkg_name: &str,
) -> Result<Version, anyhow::Error> {
// todo(#24612): warn when this is also a jsr package telling
// people to map the specifiers in the import map
let pkg_json = self
.workspace_resolver
.package_jsons()
.find(|pkg| pkg.name.as_deref() == Some(pkg_name))
.ok_or_else(|| {
anyhow::anyhow!("unable to find npm package in workspace")
})?;
if let Some(version) = &pkg_json.version {
Ok(Version::parse_from_npm(version)?)
} else {
Err(anyhow::anyhow!(
"missing version in package.json of npm package",
))
} }
} }
@ -208,6 +445,7 @@ impl SpecifierUnfurler {
text_info: &SourceTextInfo, text_info: &SourceTextInfo,
dep: &deno_graph::DynamicDependencyDescriptor, dep: &deno_graph::DynamicDependencyDescriptor,
text_changes: &mut Vec<deno_ast::TextChange>, text_changes: &mut Vec<deno_ast::TextChange>,
diagnostic_reporter: &mut dyn FnMut(SpecifierUnfurlerDiagnostic),
) -> bool { ) -> bool {
match &dep.argument { match &dep.argument {
deno_graph::DynamicArgument::String(specifier) => { deno_graph::DynamicArgument::String(specifier) => {
@ -217,8 +455,14 @@ impl SpecifierUnfurler {
let Some(relative_index) = maybe_relative_index else { let Some(relative_index) = maybe_relative_index else {
return true; // always say it's analyzable for a string return true; // always say it's analyzable for a string
}; };
let unfurled = self.unfurl_specifier(module_url, specifier); let maybe_unfurled = self.unfurl_specifier_reporting_diagnostic(
if let Some(unfurled) = unfurled { module_url,
specifier,
text_info,
&dep.argument_range,
diagnostic_reporter,
);
if let Some(unfurled) = maybe_unfurled {
let start = range.start + relative_index; let start = range.start + relative_index;
text_changes.push(deno_ast::TextChange { text_changes.push(deno_ast::TextChange {
range: start..start + specifier.len(), range: start..start + specifier.len(),
@ -238,7 +482,13 @@ impl SpecifierUnfurler {
if !specifier.ends_with('/') { if !specifier.ends_with('/') {
return false; return false;
} }
let unfurled = self.unfurl_specifier(module_url, specifier); let unfurled = self.unfurl_specifier_reporting_diagnostic(
module_url,
specifier,
text_info,
&dep.argument_range,
diagnostic_reporter,
);
let Some(unfurled) = unfurled else { let Some(unfurled) = unfurled else {
return true; // nothing to unfurl return true; // nothing to unfurl
}; };
@ -280,8 +530,15 @@ impl SpecifierUnfurler {
let analyze_specifier = let analyze_specifier =
|specifier: &str, |specifier: &str,
range: &deno_graph::PositionRange, range: &deno_graph::PositionRange,
text_changes: &mut Vec<deno_ast::TextChange>| { text_changes: &mut Vec<deno_ast::TextChange>,
if let Some(unfurled) = self.unfurl_specifier(url, specifier) { diagnostic_reporter: &mut dyn FnMut(SpecifierUnfurlerDiagnostic)| {
if let Some(unfurled) = self.unfurl_specifier_reporting_diagnostic(
url,
specifier,
text_info,
range,
diagnostic_reporter,
) {
text_changes.push(deno_ast::TextChange { text_changes.push(deno_ast::TextChange {
range: to_range(text_info, range), range: to_range(text_info, range),
new_text: unfurled, new_text: unfurled,
@ -295,11 +552,17 @@ impl SpecifierUnfurler {
&dep.specifier, &dep.specifier,
&dep.specifier_range, &dep.specifier_range,
&mut text_changes, &mut text_changes,
diagnostic_reporter,
); );
} }
DependencyDescriptor::Dynamic(dep) => { DependencyDescriptor::Dynamic(dep) => {
let success = let success = self.try_unfurl_dynamic_dep(
self.try_unfurl_dynamic_dep(url, text_info, dep, &mut text_changes); url,
text_info,
dep,
&mut text_changes,
diagnostic_reporter,
);
if !success { if !success {
let start_pos = text_info.line_start(dep.argument_range.start.line) let start_pos = text_info.line_start(dep.argument_range.start.line)
@ -326,6 +589,7 @@ impl SpecifierUnfurler {
&specifier_with_range.text, &specifier_with_range.text,
&specifier_with_range.range, &specifier_with_range.range,
&mut text_changes, &mut text_changes,
diagnostic_reporter,
); );
} }
for jsdoc in &module_info.jsdoc_imports { for jsdoc in &module_info.jsdoc_imports {
@ -333,6 +597,7 @@ impl SpecifierUnfurler {
&jsdoc.specifier.text, &jsdoc.specifier.text,
&jsdoc.specifier.range, &jsdoc.specifier.range,
&mut text_changes, &mut text_changes,
diagnostic_reporter,
); );
} }
if let Some(specifier_with_range) = &module_info.jsx_import_source { if let Some(specifier_with_range) = &module_info.jsx_import_source {
@ -340,6 +605,7 @@ impl SpecifierUnfurler {
&specifier_with_range.text, &specifier_with_range.text,
&specifier_with_range.range, &specifier_with_range.range,
&mut text_changes, &mut text_changes,
diagnostic_reporter,
); );
} }
@ -458,10 +724,10 @@ mod tests {
); );
let fs = Arc::new(RealFs); let fs = Arc::new(RealFs);
let unfurler = SpecifierUnfurler::new( let unfurler = SpecifierUnfurler::new(
Some(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new( Some(Arc::new(CliSloppyImportsResolver::new(
fs, SloppyImportsCachedFs::new(fs),
))), ))),
workspace_resolver, Arc::new(workspace_resolver),
true, true,
); );
@ -547,4 +813,114 @@ const warn2 = await import(`${expr}`);
assert_eq!(unfurled_source, expected_source); assert_eq!(unfurled_source, expected_source);
} }
} }
#[test]
fn test_unfurling_npm_dep_workspace_specifier() {
let cwd = testdata_path().join("unfurl").to_path_buf();
let pkg_json_add = PackageJson::load_from_value(
cwd.join("add/package.json"),
json!({ "name": "add", "version": "0.1.0", }),
);
let pkg_json_subtract = PackageJson::load_from_value(
cwd.join("subtract/package.json"),
json!({ "name": "subtract", "version": "0.2.0", }),
);
let pkg_json_publishing = PackageJson::load_from_value(
cwd.join("publish/package.json"),
json!({
"name": "@denotest/main",
"version": "1.0.0",
"dependencies": {
"add": "workspace:~",
"subtract": "workspace:^",
"non-existent": "workspace:~",
}
}),
);
let root_pkg_json = PackageJson::load_from_value(
cwd.join("package.json"),
json!({ "workspaces": ["./publish", "./subtract", "./add"] }),
);
let workspace_resolver = WorkspaceResolver::new_raw(
Arc::new(ModuleSpecifier::from_directory_path(&cwd).unwrap()),
None,
vec![ResolverWorkspaceJsrPackage {
is_patch: false,
base: ModuleSpecifier::from_directory_path(
cwd.join("publish/jsr.json"),
)
.unwrap(),
name: "@denotest/main".to_string(),
version: Some(Version::parse_standard("1.0.0").unwrap()),
exports: IndexMap::from([(".".to_string(), "mod.ts".to_string())]),
}],
vec![
Arc::new(root_pkg_json),
Arc::new(pkg_json_add),
Arc::new(pkg_json_subtract),
Arc::new(pkg_json_publishing),
],
deno_config::workspace::PackageJsonDepResolution::Enabled,
);
let fs = Arc::new(RealFs);
let unfurler = SpecifierUnfurler::new(
Some(Arc::new(CliSloppyImportsResolver::new(
SloppyImportsCachedFs::new(fs),
))),
Arc::new(workspace_resolver),
true,
);
{
let source_code = r#"import add from "add";
import subtract from "subtract";
console.log(add, subtract);
"#;
let specifier =
ModuleSpecifier::from_file_path(cwd.join("publish").join("mod.ts"))
.unwrap();
let source = parse_ast(&specifier, source_code);
let mut d = Vec::new();
let mut reporter = |diagnostic| d.push(diagnostic);
let unfurled_source = unfurler.unfurl(&specifier, &source, &mut reporter);
assert_eq!(d.len(), 0);
// it will inline the version
let expected_source = r#"import add from "npm:add@~0.1.0";
import subtract from "npm:subtract@^0.2.0";
console.log(add, subtract);
"#;
assert_eq!(unfurled_source, expected_source);
}
{
let source_code = r#"import nonExistent from "non-existent";
console.log(nonExistent);
"#;
let specifier =
ModuleSpecifier::from_file_path(cwd.join("publish").join("other.ts"))
.unwrap();
let source = parse_ast(&specifier, source_code);
let mut d = Vec::new();
let mut reporter = |diagnostic| d.push(diagnostic);
let unfurled_source = unfurler.unfurl(&specifier, &source, &mut reporter);
assert_eq!(d.len(), 1);
match &d[0] {
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage {
package_name,
reason,
..
} => {
assert_eq!(package_name, "non-existent");
assert_eq!(reason, "unable to find npm package in workspace");
}
_ => unreachable!(),
}
// won't make any changes, but the above will be a fatal error
assert!(matches!(d[0].level(), DiagnosticLevel::Error));
assert_eq!(unfurled_source, source_code);
}
}
} }

View file

@ -26,6 +26,7 @@ use deno_core::futures::StreamExt;
use deno_core::url::Url; use deno_core::url::Url;
use deno_path_util::normalize_path; use deno_path_util::normalize_path;
use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::NodeResolver;
use deno_task_shell::KillSignal;
use deno_task_shell::ShellCommand; use deno_task_shell::ShellCommand;
use indexmap::IndexMap; use indexmap::IndexMap;
use regex::Regex; use regex::Regex;
@ -37,6 +38,7 @@ use crate::colors;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::task_runner; use crate::task_runner;
use crate::task_runner::run_future_forwarding_signals;
use crate::util::fs::canonicalize_path; use crate::util::fs::canonicalize_path;
#[derive(Debug)] #[derive(Debug)]
@ -226,28 +228,33 @@ pub async fn execute_script(
concurrency: no_of_concurrent_tasks.into(), concurrency: no_of_concurrent_tasks.into(),
}; };
if task_flags.eval { let kill_signal = KillSignal::default();
return task_runner run_future_forwarding_signals(kill_signal.clone(), async {
.run_deno_task( if task_flags.eval {
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(), return task_runner
"", .run_deno_task(
&TaskDefinition { &Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
command: task_flags.task.as_ref().unwrap().to_string(), "",
dependencies: vec![], &TaskDefinition {
description: None, command: task_flags.task.as_ref().unwrap().to_string(),
}, dependencies: vec![],
) description: None,
.await; },
} kill_signal,
)
for task_config in &packages_task_configs { .await;
let exit_code = task_runner.run_tasks(task_config).await?;
if exit_code > 0 {
return Ok(exit_code);
} }
}
Ok(0) for task_config in &packages_task_configs {
let exit_code = task_runner.run_tasks(task_config, &kill_signal).await?;
if exit_code > 0 {
return Ok(exit_code);
}
}
Ok(0)
})
.await
} }
struct RunSingleOptions<'a> { struct RunSingleOptions<'a> {
@ -255,6 +262,7 @@ struct RunSingleOptions<'a> {
script: &'a str, script: &'a str,
cwd: &'a Path, cwd: &'a Path,
custom_commands: HashMap<String, Rc<dyn ShellCommand>>, custom_commands: HashMap<String, Rc<dyn ShellCommand>>,
kill_signal: KillSignal,
} }
struct TaskRunner<'a> { struct TaskRunner<'a> {
@ -270,9 +278,10 @@ impl<'a> TaskRunner<'a> {
pub async fn run_tasks( pub async fn run_tasks(
&self, &self,
pkg_tasks_config: &PackageTaskInfo, pkg_tasks_config: &PackageTaskInfo,
kill_signal: &KillSignal,
) -> Result<i32, deno_core::anyhow::Error> { ) -> Result<i32, deno_core::anyhow::Error> {
match sort_tasks_topo(pkg_tasks_config) { match sort_tasks_topo(pkg_tasks_config) {
Ok(sorted) => self.run_tasks_in_parallel(sorted).await, Ok(sorted) => self.run_tasks_in_parallel(sorted, kill_signal).await,
Err(err) => match err { Err(err) => match err {
TaskError::NotFound(name) => { TaskError::NotFound(name) => {
if self.task_flags.is_run { if self.task_flags.is_run {
@ -307,6 +316,7 @@ impl<'a> TaskRunner<'a> {
async fn run_tasks_in_parallel( async fn run_tasks_in_parallel(
&self, &self,
tasks: Vec<ResolvedTask<'a>>, tasks: Vec<ResolvedTask<'a>>,
kill_signal: &KillSignal,
) -> Result<i32, deno_core::anyhow::Error> { ) -> Result<i32, deno_core::anyhow::Error> {
struct PendingTasksContext<'a> { struct PendingTasksContext<'a> {
completed: HashSet<usize>, completed: HashSet<usize>,
@ -327,6 +337,7 @@ impl<'a> TaskRunner<'a> {
fn get_next_task<'b>( fn get_next_task<'b>(
&mut self, &mut self,
runner: &'b TaskRunner<'b>, runner: &'b TaskRunner<'b>,
kill_signal: &KillSignal,
) -> Option< ) -> Option<
LocalBoxFuture<'b, Result<(i32, &'a ResolvedTask<'a>), AnyError>>, LocalBoxFuture<'b, Result<(i32, &'a ResolvedTask<'a>), AnyError>>,
> >
@ -349,15 +360,23 @@ impl<'a> TaskRunner<'a> {
} }
self.running.insert(task.id); self.running.insert(task.id);
let kill_signal = kill_signal.clone();
return Some( return Some(
async move { async move {
match task.task_or_script { match task.task_or_script {
TaskOrScript::Task(_, def) => { TaskOrScript::Task(_, def) => {
runner.run_deno_task(task.folder_url, task.name, def).await runner
.run_deno_task(task.folder_url, task.name, def, kill_signal)
.await
} }
TaskOrScript::Script(scripts, _) => { TaskOrScript::Script(scripts, _) => {
runner runner
.run_npm_script(task.folder_url, task.name, scripts) .run_npm_script(
task.folder_url,
task.name,
scripts,
kill_signal,
)
.await .await
} }
} }
@ -380,7 +399,7 @@ impl<'a> TaskRunner<'a> {
while context.has_remaining_tasks() { while context.has_remaining_tasks() {
while queue.len() < self.concurrency { while queue.len() < self.concurrency {
if let Some(task) = context.get_next_task(self) { if let Some(task) = context.get_next_task(self, kill_signal) {
queue.push(task); queue.push(task);
} else { } else {
break; break;
@ -409,6 +428,7 @@ impl<'a> TaskRunner<'a> {
dir_url: &Url, dir_url: &Url,
task_name: &str, task_name: &str,
definition: &TaskDefinition, definition: &TaskDefinition,
kill_signal: KillSignal,
) -> Result<i32, deno_core::anyhow::Error> { ) -> Result<i32, deno_core::anyhow::Error> {
let cwd = match &self.task_flags.cwd { let cwd = match &self.task_flags.cwd {
Some(path) => canonicalize_path(&PathBuf::from(path)) Some(path) => canonicalize_path(&PathBuf::from(path))
@ -426,6 +446,7 @@ impl<'a> TaskRunner<'a> {
script: &definition.command, script: &definition.command,
cwd: &cwd, cwd: &cwd,
custom_commands, custom_commands,
kill_signal,
}) })
.await .await
} }
@ -435,6 +456,7 @@ impl<'a> TaskRunner<'a> {
dir_url: &Url, dir_url: &Url,
task_name: &str, task_name: &str,
scripts: &IndexMap<String, String>, scripts: &IndexMap<String, String>,
kill_signal: KillSignal,
) -> Result<i32, deno_core::anyhow::Error> { ) -> Result<i32, deno_core::anyhow::Error> {
// ensure the npm packages are installed if using a managed resolver // ensure the npm packages are installed if using a managed resolver
if let Some(npm_resolver) = self.npm_resolver.as_managed() { if let Some(npm_resolver) = self.npm_resolver.as_managed() {
@ -466,6 +488,7 @@ impl<'a> TaskRunner<'a> {
script, script,
cwd: &cwd, cwd: &cwd,
custom_commands: custom_commands.clone(), custom_commands: custom_commands.clone(),
kill_signal: kill_signal.clone(),
}) })
.await?; .await?;
if exit_code > 0 { if exit_code > 0 {
@ -486,6 +509,7 @@ impl<'a> TaskRunner<'a> {
script, script,
cwd, cwd,
custom_commands, custom_commands,
kill_signal,
} = opts; } = opts;
output_task( output_task(
@ -504,6 +528,7 @@ impl<'a> TaskRunner<'a> {
argv: self.cli_options.argv(), argv: self.cli_options.argv(),
root_node_modules_dir: self.npm_resolver.root_node_modules_path(), root_node_modules_dir: self.npm_resolver.root_node_modules_path(),
stdio: None, stdio: None,
kill_signal,
}) })
.await? .await?
.exit_code, .exit_code,

View file

@ -872,12 +872,10 @@ impl deno_package_json::fs::DenoPkgJsonFs for DenoFsNodeResolverEnv {
fn read_to_string_lossy( fn read_to_string_lossy(
&self, &self,
path: &std::path::Path, path: &std::path::Path,
) -> Result<String, std::io::Error> { ) -> Result<Cow<'static, str>, std::io::Error> {
self self
.fs .fs
.read_text_file_lossy_sync(path, None) .read_text_file_lossy_sync(path, None)
// todo(https://github.com/denoland/deno_package_json/pull/9): don't clone
.map(|text| text.into_owned())
.map_err(|err| err.into_io_error()) .map_err(|err| err.into_io_error())
} }
} }
@ -888,12 +886,10 @@ impl<'a> deno_package_json::fs::DenoPkgJsonFs for DenoPkgJsonFsAdapter<'a> {
fn read_to_string_lossy( fn read_to_string_lossy(
&self, &self,
path: &Path, path: &Path,
) -> Result<String, std::io::Error> { ) -> Result<Cow<'static, str>, std::io::Error> {
self self
.0 .0
.read_text_file_lossy_sync(path, None) .read_text_file_lossy_sync(path, None)
// todo(https://github.com/denoland/deno_package_json/pull/9): don't clone
.map(|text| text.into_owned())
.map_err(|err| err.into_io_error()) .map_err(|err| err.into_io_error())
} }
} }

View file

@ -179,7 +179,11 @@ impl<Fs: DenoResolverFs, TEnv: NodeResolverEnv> ByonmNpmResolver<Fs, TEnv> {
pkg_json: &PackageJson, pkg_json: &PackageJson,
) -> Option<String> { ) -> Option<String> {
let deps = pkg_json.resolve_local_package_json_deps(); let deps = pkg_json.resolve_local_package_json_deps();
for (key, value) in deps { for (key, value) in deps
.dependencies
.into_iter()
.chain(deps.dev_dependencies.into_iter())
{
if let Ok(value) = value { if let Ok(value) = value {
match value { match value {
PackageJsonDepValue::Req(dep_req) => { PackageJsonDepValue::Req(dep_req) => {

View file

@ -34,6 +34,7 @@ pub mod inspector_server;
pub mod js; pub mod js;
pub mod ops; pub mod ops;
pub mod permissions; pub mod permissions;
pub mod signal;
pub mod snapshot; pub mod snapshot;
pub mod sys_info; pub mod sys_info;
pub mod tokio_util; pub mod tokio_util;

View file

@ -256,9 +256,7 @@ impl TryFrom<ExitStatus> for ChildStatus {
success: false, success: false,
code: 128 + signal, code: 128 + signal,
#[cfg(unix)] #[cfg(unix)]
signal: Some( signal: Some(crate::signal::signal_int_to_str(signal)?.to_string()),
crate::ops::signal::signal_int_to_str(signal)?.to_string(),
),
#[cfg(not(unix))] #[cfg(not(unix))]
signal: None, signal: None,
} }
@ -1076,7 +1074,8 @@ mod deprecated {
#[cfg(unix)] #[cfg(unix)]
pub fn kill(pid: i32, signal: &str) -> Result<(), ProcessError> { pub fn kill(pid: i32, signal: &str) -> Result<(), ProcessError> {
let signo = super::super::signal::signal_str_to_int(signal)?; let signo = crate::signal::signal_str_to_int(signal)
.map_err(SignalError::InvalidSignalStr)?;
use nix::sys::signal::kill as unix_kill; use nix::sys::signal::kill as unix_kill;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
use nix::unistd::Pid; use nix::unistd::Pid;
@ -1099,7 +1098,12 @@ mod deprecated {
use winapi::um::winnt::PROCESS_TERMINATE; use winapi::um::winnt::PROCESS_TERMINATE;
if !matches!(signal, "SIGKILL" | "SIGTERM") { if !matches!(signal, "SIGKILL" | "SIGTERM") {
Err(SignalError::InvalidSignalStr(signal.to_string()).into()) Err(
SignalError::InvalidSignalStr(crate::signal::InvalidSignalStrError(
signal.to_string(),
))
.into(),
)
} else if pid <= 0 { } else if pid <= 0 {
Err(ProcessError::InvalidPid) Err(ProcessError::InvalidPid)
} else { } else {

View file

@ -46,34 +46,10 @@ deno_core::extension!(
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum SignalError { pub enum SignalError {
#[cfg(any( #[error(transparent)]
target_os = "android", InvalidSignalStr(#[from] crate::signal::InvalidSignalStrError),
target_os = "linux", #[error(transparent)]
target_os = "openbsd", InvalidSignalInt(#[from] crate::signal::InvalidSignalIntError),
target_os = "openbsd",
target_os = "macos",
target_os = "solaris",
target_os = "illumos"
))]
#[error("Invalid signal: {0}")]
InvalidSignalStr(String),
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "openbsd",
target_os = "openbsd",
target_os = "macos",
target_os = "solaris",
target_os = "illumos"
))]
#[error("Invalid signal: {0}")]
InvalidSignalInt(libc::c_int),
#[cfg(target_os = "windows")]
#[error("Windows only supports ctrl-c (SIGINT) and ctrl-break (SIGBREAK), but got {0}")]
InvalidSignalStr(String),
#[cfg(target_os = "windows")]
#[error("Windows only supports ctrl-c (SIGINT) and ctrl-break (SIGBREAK), but got {0}")]
InvalidSignalInt(libc::c_int),
#[error("Binding to signal '{0}' is not allowed")] #[error("Binding to signal '{0}' is not allowed")]
SignalNotAllowed(String), SignalNotAllowed(String),
#[error("{0}")] #[error("{0}")]
@ -181,218 +157,6 @@ impl Resource for SignalStreamResource {
} }
} }
macro_rules! first_literal {
($head:literal $(, $tail:literal)*) => {
$head
};
}
macro_rules! signal_dict {
($(($number:literal, $($name:literal)|+)),*) => {
pub fn signal_str_to_int(s: &str) -> Result<libc::c_int, SignalError> {
match s {
$($($name)|* => Ok($number),)*
_ => Err(SignalError::InvalidSignalStr(s.to_string())),
}
}
pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, SignalError> {
match s {
$($number => Ok(first_literal!($($name),+)),)*
_ => Err(SignalError::InvalidSignalInt(s)),
}
}
}
}
#[cfg(target_os = "freebsd")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2"),
(32, "SIGTHR"),
(33, "SIGLIBRT")
);
#[cfg(target_os = "openbsd")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2"),
(32, "SIGTHR")
);
#[cfg(any(target_os = "android", target_os = "linux"))]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGBUS"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGUSR1"),
(11, "SIGSEGV"),
(12, "SIGUSR2"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGSTKFLT"),
(17, "SIGCHLD"),
(18, "SIGCONT"),
(19, "SIGSTOP"),
(20, "SIGTSTP"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGURG"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGIO" | "SIGPOLL"),
(30, "SIGPWR"),
(31, "SIGSYS" | "SIGUNUSED")
);
#[cfg(target_os = "macos")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2")
);
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGUSR1"),
(17, "SIGUSR2"),
(18, "SIGCHLD"),
(19, "SIGPWR"),
(20, "SIGWINCH"),
(21, "SIGURG"),
(22, "SIGPOLL"),
(23, "SIGSTOP"),
(24, "SIGTSTP"),
(25, "SIGCONT"),
(26, "SIGTTIN"),
(27, "SIGTTOU"),
(28, "SIGVTALRM"),
(29, "SIGPROF"),
(30, "SIGXCPU"),
(31, "SIGXFSZ"),
(32, "SIGWAITING"),
(33, "SIGLWP"),
(34, "SIGFREEZE"),
(35, "SIGTHAW"),
(36, "SIGCANCEL"),
(37, "SIGLOST"),
(38, "SIGXRES"),
(39, "SIGJVM1"),
(40, "SIGJVM2")
);
#[cfg(target_os = "windows")]
signal_dict!((2, "SIGINT"), (21, "SIGBREAK"));
#[cfg(unix)] #[cfg(unix)]
#[op2(fast)] #[op2(fast)]
#[smi] #[smi]
@ -400,7 +164,7 @@ fn op_signal_bind(
state: &mut OpState, state: &mut OpState,
#[string] sig: &str, #[string] sig: &str,
) -> Result<ResourceId, SignalError> { ) -> Result<ResourceId, SignalError> {
let signo = signal_str_to_int(sig)?; let signo = crate::signal::signal_str_to_int(sig)?;
if signal_hook_registry::FORBIDDEN.contains(&signo) { if signal_hook_registry::FORBIDDEN.contains(&signo) {
return Err(SignalError::SignalNotAllowed(sig.to_string())); return Err(SignalError::SignalNotAllowed(sig.to_string()));
} }
@ -437,7 +201,7 @@ fn op_signal_bind(
state: &mut OpState, state: &mut OpState,
#[string] sig: &str, #[string] sig: &str,
) -> Result<ResourceId, SignalError> { ) -> Result<ResourceId, SignalError> {
let signo = signal_str_to_int(sig)?; let signo = crate::signal::signal_str_to_int(sig)?;
let resource = SignalStreamResource { let resource = SignalStreamResource {
signal: AsyncRefCell::new(match signo { signal: AsyncRefCell::new(match signo {
// SIGINT // SIGINT

257
runtime/signal.rs Normal file
View file

@ -0,0 +1,257 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
#[cfg(target_os = "windows")]
#[derive(Debug, thiserror::Error)]
#[error("Windows only supports ctrl-c (SIGINT) and ctrl-break (SIGBREAK), but got {0}")]
pub struct InvalidSignalStrError(pub String);
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "openbsd",
target_os = "openbsd",
target_os = "macos",
target_os = "solaris",
target_os = "illumos"
))]
#[derive(Debug, thiserror::Error)]
#[error("Invalid signal: {0}")]
pub struct InvalidSignalStrError(pub String);
#[cfg(target_os = "windows")]
#[derive(Debug, thiserror::Error)]
#[error("Windows only supports ctrl-c (SIGINT) and ctrl-break (SIGBREAK), but got {0}")]
pub struct InvalidSignalIntError(pub libc::c_int);
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "openbsd",
target_os = "openbsd",
target_os = "macos",
target_os = "solaris",
target_os = "illumos"
))]
#[derive(Debug, thiserror::Error)]
#[error("Invalid signal: {0}")]
pub struct InvalidSignalIntError(pub libc::c_int);
macro_rules! first_literal {
($head:literal $(, $tail:literal)*) => {
$head
};
}
macro_rules! signal_dict {
($(($number:literal, $($name:literal)|+)),*) => {
pub const SIGNAL_NUMS: &'static [libc::c_int] = &[
$(
$number
),*
];
pub fn signal_str_to_int(s: &str) -> Result<libc::c_int, InvalidSignalStrError> {
match s {
$($($name)|* => Ok($number),)*
_ => Err(InvalidSignalStrError(s.to_string())),
}
}
pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, InvalidSignalIntError> {
match s {
$($number => Ok(first_literal!($($name),+)),)*
_ => Err(InvalidSignalIntError(s)),
}
}
}
}
#[cfg(target_os = "freebsd")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2"),
(32, "SIGTHR"),
(33, "SIGLIBRT")
);
#[cfg(target_os = "openbsd")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2"),
(32, "SIGTHR")
);
#[cfg(any(target_os = "android", target_os = "linux"))]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGBUS"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGUSR1"),
(11, "SIGSEGV"),
(12, "SIGUSR2"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGSTKFLT"),
(17, "SIGCHLD"),
(18, "SIGCONT"),
(19, "SIGSTOP"),
(20, "SIGTSTP"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGURG"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGIO" | "SIGPOLL"),
(30, "SIGPWR"),
(31, "SIGSYS" | "SIGUNUSED")
);
#[cfg(target_os = "macos")]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGURG"),
(17, "SIGSTOP"),
(18, "SIGTSTP"),
(19, "SIGCONT"),
(20, "SIGCHLD"),
(21, "SIGTTIN"),
(22, "SIGTTOU"),
(23, "SIGIO"),
(24, "SIGXCPU"),
(25, "SIGXFSZ"),
(26, "SIGVTALRM"),
(27, "SIGPROF"),
(28, "SIGWINCH"),
(29, "SIGINFO"),
(30, "SIGUSR1"),
(31, "SIGUSR2")
);
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
signal_dict!(
(1, "SIGHUP"),
(2, "SIGINT"),
(3, "SIGQUIT"),
(4, "SIGILL"),
(5, "SIGTRAP"),
(6, "SIGABRT" | "SIGIOT"),
(7, "SIGEMT"),
(8, "SIGFPE"),
(9, "SIGKILL"),
(10, "SIGBUS"),
(11, "SIGSEGV"),
(12, "SIGSYS"),
(13, "SIGPIPE"),
(14, "SIGALRM"),
(15, "SIGTERM"),
(16, "SIGUSR1"),
(17, "SIGUSR2"),
(18, "SIGCHLD"),
(19, "SIGPWR"),
(20, "SIGWINCH"),
(21, "SIGURG"),
(22, "SIGPOLL"),
(23, "SIGSTOP"),
(24, "SIGTSTP"),
(25, "SIGCONT"),
(26, "SIGTTIN"),
(27, "SIGTTOU"),
(28, "SIGVTALRM"),
(29, "SIGPROF"),
(30, "SIGXCPU"),
(31, "SIGXFSZ"),
(32, "SIGWAITING"),
(33, "SIGLWP"),
(34, "SIGFREEZE"),
(35, "SIGTHAW"),
(36, "SIGCANCEL"),
(37, "SIGLOST"),
(38, "SIGXRES"),
(39, "SIGJVM1"),
(40, "SIGJVM2")
);
#[cfg(target_os = "windows")]
signal_dict!((2, "SIGINT"), (21, "SIGBREAK"));

View file

@ -0,0 +1,10 @@
{
"tempDir": true,
"steps": [{
"args": "install",
"output": "[WILDCARD]"
}, {
"args": "run e/main.ts",
"output": "main.out"
}]
}

View file

@ -0,0 +1,3 @@
export function sayHello() {
console.log("Hello from a!");
}

View file

@ -0,0 +1,7 @@
{
"name": "@denotest/a",
"version": "1.0.0",
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,3 @@
export function sayHello() {
console.log("Hello from b!");
}

View file

@ -0,0 +1,7 @@
{
"name": "@denotest/b",
"version": "1.0.0",
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,3 @@
export function sayHello() {
console.log("Hello from c!");
}

View file

@ -0,0 +1,7 @@
{
"name": "@denotest/c",
"version": "1.0.0",
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,3 @@
export function sayHello() {
console.log("Hello from d!");
}

View file

@ -0,0 +1,7 @@
{
"name": "@denotest/d",
"version": "1.2.3",
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,9 @@
import * as a from "@denotest/a";
import * as b from "@denotest/b";
import * as c from "@denotest/c";
import * as d from "@denotest/d";
a.sayHello();
b.sayHello();
c.sayHello();
d.sayHello();

View file

@ -0,0 +1,10 @@
{
"name": "@denotest/e",
"version": "1.0.0",
"dependencies": {
"@denotest/a": "workspace:*",
"@denotest/b": "workspace:~",
"@denotest/c": "workspace:^",
"@denotest/d": "workspace:1.2.3"
}
}

View file

@ -0,0 +1,4 @@
Hello from a!
Hello from b!
Hello from c!
Hello from d!

View file

@ -0,0 +1,6 @@
// should resolve these as bare specifiers within the workspace
import * as a from "@denotest/a";
import * as c from "@denotest/c";
a.sayHello();
c.sayHello();

View file

@ -0,0 +1,9 @@
{
"workspaces": [
"./a",
"./b",
"./c",
"./d",
"./e"
]
}

View file

@ -0,0 +1,8 @@
{
// signals don't really exist on windows
"if": "unix",
// this runs a deno task
"args": "run -A --check sender.ts",
// just ensure this doesn't hang and completes successfully
"output": "[WILDCARD]"
}

View file

@ -0,0 +1,5 @@
{
"tasks": {
"listener": "deno run listener.ts"
}
}

View file

@ -0,0 +1,16 @@
import { signals } from "./signals.ts";
for (const signal of signals) {
Deno.addSignalListener(signal, () => {
console.log("Received", signal);
if (signal === "SIGTERM") {
Deno.exit(0);
}
});
}
setInterval(() => {
// keep alive
}, 1000);
console.log("Ready");

View file

@ -0,0 +1,55 @@
import { signals } from "./signals.ts";
class StdoutReader {
readonly #reader: ReadableStreamDefaultReader<string>;
#text = "";
constructor(stream: ReadableStream<Uint8Array>) {
const textStream = stream.pipeThrough(new TextDecoderStream());
this.#reader = textStream.getReader();
}
[Symbol.dispose]() {
this.#reader.releaseLock();
}
async waitForText(waitingText: string) {
if (this.#text.includes(waitingText)) {
return;
}
while (true) {
const { value, done } = await this.#reader.read();
if (value) {
this.#text += value;
if (this.#text.includes(waitingText)) {
break;
}
}
if (done) {
throw new Error("Did not find text: " + waitingText);
}
}
}
}
const command = new Deno.Command(Deno.execPath(), {
args: ["task", "listener"],
stdout: "piped",
});
const child = command.spawn();
const reader = new StdoutReader(child.stdout!);
await reader.waitForText("Ready");
for (const signal of signals) {
if (signal === "SIGTERM") {
continue;
}
console.error("Sending", signal);
child.kill(signal);
await reader.waitForText("Received " + signal);
}
console.error("Sending SIGTERM");
child.kill("SIGTERM");

View file

@ -0,0 +1,65 @@
const signals = [
"SIGABRT",
"SIGALRM",
"SIGBUS",
"SIGCHLD",
"SIGCONT",
"SIGEMT",
"SIGFPE",
"SIGHUP",
"SIGILL",
"SIGINFO",
"SIGINT",
"SIGIO",
"SIGPOLL",
"SIGPIPE",
"SIGPROF",
"SIGPWR",
"SIGQUIT",
"SIGSEGV",
"SIGSTKFLT",
"SIGSYS",
"SIGTERM",
"SIGTRAP",
"SIGTSTP",
"SIGTTIN",
"SIGTTOU",
"SIGURG",
"SIGUSR1",
"SIGUSR2",
"SIGVTALRM",
"SIGWINCH",
"SIGXCPU",
"SIGXFSZ",
] as const;
// SIGKILL and SIGSTOP are not stoppable, SIGBREAK is for windows, and SIGUNUSED is not defined
type SignalsToTest = Exclude<
Deno.Signal,
"SIGKILL" | "SIGSTOP" | "SIGBREAK" | "SIGUNUSED"
>;
type EnsureAllSignalsIncluded = SignalsToTest extends typeof signals[number]
? typeof signals[number] extends SignalsToTest ? true
: never
: never;
const _checkSignals: EnsureAllSignalsIncluded = true;
const osSpecificSignals = signals.filter((s) => {
switch (s) {
case "SIGEMT":
return Deno.build.os === "darwin";
case "SIGINFO":
case "SIGFPE":
case "SIGILL":
case "SIGSEGV":
return Deno.build.os === "freebsd";
case "SIGPOLL":
case "SIGPWR":
case "SIGSTKFLT":
return Deno.build.os === "linux";
default:
return true;
}
});
export { osSpecificSignals as signals };