mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
Merge remote-tracking branch 'upstream/main' into check-workspace-member-compiler-options
This commit is contained in:
commit
14b3eb2789
45 changed files with 1356 additions and 630 deletions
235
Cargo.lock
generated
235
Cargo.lock
generated
|
@ -231,7 +231,7 @@ dependencies = [
|
|||
"nom 7.1.3",
|
||||
"num-traits",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
@ -1292,7 +1292,7 @@ dependencies = [
|
|||
"test_server",
|
||||
"text-size",
|
||||
"text_lines",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
|
@ -1321,13 +1321,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ast"
|
||||
version = "0.43.3"
|
||||
version = "0.44.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d00b724e06d2081a141ec1155756a0b465d413d8e2a7515221f61d482eb2ee"
|
||||
checksum = "eebc7aaabfdb3ddcad32aee1b62d250149dc8b35dfbdccbb125df2bdc62da952"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"deno_error",
|
||||
"deno_media_type",
|
||||
"deno_terminal 0.1.1",
|
||||
"deno_terminal 0.2.0",
|
||||
"dprint-swc-ext",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
|
@ -1358,7 +1359,7 @@ dependencies = [
|
|||
"swc_visit",
|
||||
"swc_visit_macros",
|
||||
"text_lines",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
"unicode-width",
|
||||
"url",
|
||||
]
|
||||
|
@ -1378,7 +1379,7 @@ version = "0.174.0"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -1392,15 +1393,15 @@ dependencies = [
|
|||
"rusqlite",
|
||||
"serde",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_cache_dir"
|
||||
version = "0.13.2"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c1f52170cd7715f8006da54cde1444863a0d6fbd9c11d037a737db2dec8e22"
|
||||
checksum = "cca43605c8cbce6c6787e0daf227864487c07c2b31d438c0bf43d1b38da94b7f"
|
||||
dependencies = [
|
||||
"base32",
|
||||
"deno_media_type",
|
||||
|
@ -1412,7 +1413,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1424,13 +1425,13 @@ dependencies = [
|
|||
"deno_webgpu",
|
||||
"image",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.39.2"
|
||||
source = "git+https://github.com/denoland/deno_config.git?rev=485e7a71f1057437d2a2c4adddbfbe348a812667#485e7a71f1057437d2a2c4adddbfbe348a812667"
|
||||
version = "0.39.3"
|
||||
source = "git+https://github.com/denoland/deno_config.git?branch=compiler-options-from-workspace-member#81d8e844624a8f6b3961213d1480dcc923d08b11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_package_json",
|
||||
|
@ -1446,7 +1447,7 @@ dependencies = [
|
|||
"phf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1507,7 +1508,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"deno_core",
|
||||
"saffron",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -1542,7 +1543,7 @@ dependencies = [
|
|||
"sha2",
|
||||
"signature",
|
||||
"spki",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"uuid",
|
||||
"x25519-dalek",
|
||||
|
@ -1550,9 +1551,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_doc"
|
||||
version = "0.161.1"
|
||||
version = "0.161.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32d994915f85e873865fc341e592080a487b0a987d06177016b2d93fd62162f8"
|
||||
checksum = "3af787319136f3e7f73ef551c618aeec70794522e36cd75ae35132a3bad983ef"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
|
@ -1577,6 +1578,29 @@ dependencies = [
|
|||
"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]]
|
||||
name = "deno_fetch"
|
||||
version = "0.204.0"
|
||||
|
@ -1601,7 +1625,7 @@ dependencies = [
|
|||
"rustls-webpki",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-socks",
|
||||
|
@ -1626,7 +1650,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde-value",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -1649,16 +1673,16 @@ dependencies = [
|
|||
"rand",
|
||||
"rayon",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"winapi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.86.2"
|
||||
version = "0.86.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c3f4be49dad28e794ff4eeb2daaf7956c97f8557097ef6f9c3ff1292e0a5c28"
|
||||
checksum = "fc78ed0b4bbcb4197300f0d6e7d1edc2d2c5019cdb9dedba7ff229158441885b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -1678,7 +1702,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
"twox-hash",
|
||||
"url",
|
||||
"wasm_dep_analyzer",
|
||||
|
@ -1718,7 +1742,7 @@ dependencies = [
|
|||
"scopeguard",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
@ -1772,15 +1796,15 @@ dependencies = [
|
|||
"rand",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_lint"
|
||||
version = "0.68.0"
|
||||
version = "0.68.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb994e6d1b18223df0a756c7948143b35682941d615edffef60d5b38822f38ac"
|
||||
checksum = "ce2a040657166e39c7d59ad34230f0cc829f8ea8b7b2377038cc012ec1a1ef16"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
|
@ -1796,14 +1820,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_lockfile"
|
||||
version = "0.23.1"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579117d5815aa9bae0212637d6f4d5f45f9649bb2c8988dca434077545535039"
|
||||
checksum = "559c19feb00af0c34f0bd4a20e56e12463fafd5c5069d6005f3ce33008027eea"
|
||||
dependencies = [
|
||||
"deno_semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1828,7 +1852,7 @@ dependencies = [
|
|||
"libuv-sys-lite",
|
||||
"log",
|
||||
"napi_sym",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
|
@ -1858,7 +1882,7 @@ dependencies = [
|
|||
"rustls-tokio-stream",
|
||||
"serde",
|
||||
"socket2",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -1942,7 +1966,7 @@ dependencies = [
|
|||
"sm3",
|
||||
"spki",
|
||||
"stable_deref_trait",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-eld",
|
||||
"url",
|
||||
|
@ -1956,9 +1980,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_npm"
|
||||
version = "0.25.4"
|
||||
version = "0.25.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b4dc4a9f1cff63d5638e7d93042f24f46300d1cc77b86f3caaa699a7ddccf7"
|
||||
checksum = "89ded7af9db5d9f2986a739d1b5fbe1c57f498e4f996ae4114728e7c6dad213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -1969,7 +1993,7 @@ dependencies = [
|
|||
"monch",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1986,20 +2010,22 @@ dependencies = [
|
|||
"strum",
|
||||
"strum_macros",
|
||||
"syn 2.0.87",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_package_json"
|
||||
version = "0.1.2"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cbc4c4d3eb0960b58e8f43f9fc2d3f620fcac9a03cd85203e08db5b04e83c1f"
|
||||
checksum = "80b0a3d81c592624a1ae15332a04b4dc2b7c163ef1dfc7c60171f736d1babdf5"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"indexmap 2.3.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -2010,7 +2036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ff25f6e08e7a0214bbacdd6f7195c7f1ebcd850c87a624e4ff06326b68b42d99"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -2027,7 +2053,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"which 4.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2047,7 +2073,7 @@ dependencies = [
|
|||
"deno_semver",
|
||||
"node_resolver",
|
||||
"test_server",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -2110,7 +2136,7 @@ dependencies = [
|
|||
"signal-hook-registry",
|
||||
"tempfile",
|
||||
"test_server",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-metrics",
|
||||
"twox-hash",
|
||||
|
@ -2122,32 +2148,33 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_semver"
|
||||
version = "0.5.16"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c957c6a57c38b7dde2315df0da0ec228911e56a74f185b108a488d0401841a67"
|
||||
checksum = "4756be7351289726087408984db18b9eb5e0186907673f39f858d119d0162071"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"monch",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_task_shell"
|
||||
version = "0.18.1"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f444918f7102c1a5a143e9d57809e499fb4d365070519bf2e8bdb16d586af2a"
|
||||
checksum = "01e09966ce29f8d26b652a43355397e1df43b85759e7824196bf0ceaeaa9a2f4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
"glob",
|
||||
"monch",
|
||||
"nix",
|
||||
"os_pipe",
|
||||
"path-dedot",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2202,7 +2229,7 @@ dependencies = [
|
|||
"rustls-tokio-stream",
|
||||
"rustls-webpki",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
@ -2248,7 +2275,7 @@ dependencies = [
|
|||
"deno_console",
|
||||
"deno_core",
|
||||
"deno_webidl",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"urlpattern",
|
||||
]
|
||||
|
||||
|
@ -2269,7 +2296,7 @@ dependencies = [
|
|||
"flate2",
|
||||
"futures",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -2281,7 +2308,7 @@ dependencies = [
|
|||
"deno_core",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"wgpu-core",
|
||||
"wgpu-types",
|
||||
|
@ -2313,7 +2340,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"rustls-tokio-stream",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -2324,7 +2351,7 @@ dependencies = [
|
|||
"deno_core",
|
||||
"deno_web",
|
||||
"rusqlite",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2396,7 +2423,7 @@ dependencies = [
|
|||
"rand",
|
||||
"rusqlite",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"uuid",
|
||||
|
@ -2689,9 +2716,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.93.2"
|
||||
version = "0.93.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ff29fd136541e59d51946f0d2d353fefc886776f61a799ebfb5838b06cef13b"
|
||||
checksum = "5804d1809f6191a9261f423c41cd51a50e49567d61caa5a8f6224eea94ae0d12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
|
@ -2837,7 +2864,7 @@ dependencies = [
|
|||
"debug-ignore",
|
||||
"indexmap 2.3.0",
|
||||
"log",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
|
@ -2997,7 +3024,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"async-trait",
|
||||
"log",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
]
|
||||
|
@ -3032,7 +3059,7 @@ dependencies = [
|
|||
"rand",
|
||||
"sha1",
|
||||
"simdutf8",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"utf-8",
|
||||
]
|
||||
|
@ -3090,7 +3117,7 @@ dependencies = [
|
|||
"deno_terminal 0.1.1",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3564,7 +3591,7 @@ dependencies = [
|
|||
"pest_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3650,7 +3677,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"radix_trie",
|
||||
"rand",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -3673,7 +3700,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tinyvec",
|
||||
"tokio",
|
||||
"tracing",
|
||||
|
@ -3697,7 +3724,7 @@ dependencies = [
|
|||
"resolv-conf",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -3715,7 +3742,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"hickory-proto",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -4155,7 +4182,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -4361,7 +4388,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
@ -4811,7 +4838,7 @@ dependencies = [
|
|||
"serde",
|
||||
"spirv",
|
||||
"termcolor",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
|
@ -4901,7 +4928,7 @@ dependencies = [
|
|||
"path-clean",
|
||||
"regex",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
@ -5098,7 +5125,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5128,7 +5155,7 @@ dependencies = [
|
|||
"opentelemetry_sdk",
|
||||
"prost",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tracing",
|
||||
|
@ -5170,7 +5197,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"rand",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -5354,7 +5381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
|
@ -5768,7 +5795,7 @@ dependencies = [
|
|||
"indexmap 2.3.0",
|
||||
"quick-xml",
|
||||
"strip-ansi-escapes",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
@ -5793,7 +5820,7 @@ dependencies = [
|
|||
"quinn-udp",
|
||||
"rustc-hash 1.1.0",
|
||||
"rustls",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -5810,7 +5837,7 @@ dependencies = [
|
|||
"rustc-hash 2.0.0",
|
||||
"rustls",
|
||||
"slab",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -5959,7 +5986,7 @@ checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
|
|||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6583,7 +6610,7 @@ dependencies = [
|
|||
"num-bigint",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"v8",
|
||||
]
|
||||
|
||||
|
@ -7586,7 +7613,16 @@ version = "1.0.64"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
||||
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]]
|
||||
|
@ -7600,6 +7636,17 @@ dependencies = [
|
|||
"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]]
|
||||
name = "thousands"
|
||||
version = "0.2.0"
|
||||
|
@ -7752,7 +7799,7 @@ checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
|
|||
dependencies = [
|
||||
"either",
|
||||
"futures-util",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -8169,7 +8216,7 @@ dependencies = [
|
|||
"indexmap 2.3.0",
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"wtf8",
|
||||
]
|
||||
|
||||
|
@ -8341,7 +8388,7 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -8395,7 +8442,7 @@ dependencies = [
|
|||
"rustc-hash 1.1.0",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"web-sys",
|
||||
"wgpu-hal",
|
||||
"wgpu-types",
|
||||
|
@ -8436,7 +8483,7 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
"wgpu-types",
|
||||
|
@ -8502,7 +8549,7 @@ version = "2.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b2b1bf557d947847a30eb73f79aa6cdb3eaf3ce02f5e9599438f77896a62b3c"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"windows",
|
||||
]
|
||||
|
||||
|
@ -8784,7 +8831,7 @@ dependencies = [
|
|||
"nom 7.1.3",
|
||||
"oid-registry",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
@ -8928,7 +8975,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"rand",
|
||||
"regex",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"uuid",
|
||||
|
@ -8969,7 +9016,7 @@ dependencies = [
|
|||
"flate2",
|
||||
"indexmap 2.3.0",
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"thiserror 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -46,19 +46,19 @@ license = "MIT"
|
|||
repository = "https://github.com/denoland/deno"
|
||||
|
||||
[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_bench_util = { version = "0.174.0", path = "./bench_util" }
|
||||
# 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_lockfile = "=0.23.1"
|
||||
deno_config = { git = "https://github.com/denoland/deno_config.git", branch = "compiler-options-from-workspace-member", features = ["workspace", "sync"] }
|
||||
deno_lockfile = "=0.23.2"
|
||||
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_permissions = { version = "0.40.0", path = "./runtime/permissions" }
|
||||
deno_runtime = { version = "0.189.0", path = "./runtime" }
|
||||
deno_semver = "=0.5.16"
|
||||
deno_semver = "=0.6.0"
|
||||
deno_terminal = "0.2.0"
|
||||
napi_sym = { version = "0.110.0", path = "./ext/napi/sym" }
|
||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||
|
@ -116,8 +116,8 @@ console_static_text = "=0.8.1"
|
|||
dashmap = "5.5.3"
|
||||
data-encoding = "2.3.3"
|
||||
data-url = "=0.3.0"
|
||||
deno_cache_dir = "=0.13.2"
|
||||
deno_package_json = { version = "0.1.2", default-features = false }
|
||||
deno_cache_dir = "=0.14.0"
|
||||
deno_package_json = { version = "0.2.1", default-features = false }
|
||||
dlopen2 = "0.6.1"
|
||||
ecb = "=0.1.2"
|
||||
elliptic-curve = { version = "0.13.4", features = ["alloc", "arithmetic", "ecdh", "std", "pem", "jwk"] }
|
||||
|
|
|
@ -72,9 +72,9 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
|
|||
deno_cache_dir.workspace = true
|
||||
deno_config.workspace = true
|
||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "=0.161.1", features = ["rust", "comrak"] }
|
||||
deno_graph = { version = "=0.86.2" }
|
||||
deno_lint = { version = "=0.68.0", features = ["docs"] }
|
||||
deno_doc = { version = "=0.161.2", features = ["rust", "comrak"] }
|
||||
deno_graph = { version = "=0.86.3" }
|
||||
deno_lint = { version = "=0.68.1", features = ["docs"] }
|
||||
deno_lockfile.workspace = true
|
||||
deno_npm.workspace = true
|
||||
deno_package_json.workspace = true
|
||||
|
@ -82,7 +82,7 @@ deno_path_util.workspace = true
|
|||
deno_resolver.workspace = true
|
||||
deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_semver.workspace = true
|
||||
deno_task_shell = "=0.18.1"
|
||||
deno_task_shell = "=0.20.1"
|
||||
deno_telemetry.workspace = true
|
||||
deno_terminal.workspace = true
|
||||
libsui = "0.5.0"
|
||||
|
@ -108,7 +108,7 @@ dotenvy = "0.15.7"
|
|||
dprint-plugin-json = "=0.19.4"
|
||||
dprint-plugin-jupyter = "=0.1.5"
|
||||
dprint-plugin-markdown = "=0.17.8"
|
||||
dprint-plugin-typescript = "=0.93.2"
|
||||
dprint-plugin-typescript = "=0.93.3"
|
||||
env_logger = "=0.10.0"
|
||||
fancy-regex = "=0.10.0"
|
||||
faster-hex.workspace = true
|
||||
|
|
|
@ -18,12 +18,10 @@ impl<'a> deno_config::fs::DenoConfigFs for DenoConfigFsAdapter<'a> {
|
|||
fn read_to_string_lossy(
|
||||
&self,
|
||||
path: &std::path::Path,
|
||||
) -> Result<String, std::io::Error> {
|
||||
) -> Result<std::borrow::Cow<'static, str>, std::io::Error> {
|
||||
self
|
||||
.0
|
||||
.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())
|
||||
}
|
||||
|
||||
|
|
|
@ -109,9 +109,12 @@ impl CliLockfile {
|
|||
let Some(pkg_json) = maybe_pkg_json else {
|
||||
return Default::default();
|
||||
};
|
||||
pkg_json
|
||||
.resolve_local_package_json_deps()
|
||||
let deps = pkg_json.resolve_local_package_json_deps();
|
||||
|
||||
deps
|
||||
.dependencies
|
||||
.values()
|
||||
.chain(deps.dev_dependencies.values())
|
||||
.filter_map(|dep| dep.as_ref().ok())
|
||||
.filter_map(|dep| match dep {
|
||||
PackageJsonDepValue::Req(req) => {
|
||||
|
|
|
@ -8,8 +8,10 @@ use deno_core::serde_json;
|
|||
use deno_core::url::Url;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_package_json::PackageJsonDepValueParseError;
|
||||
use deno_package_json::PackageJsonDepWorkspaceReq;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_semver::VersionReq;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -95,8 +97,14 @@ impl NpmInstallDepsProvider {
|
|||
|
||||
if let Some(pkg_json) = &folder.pkg_json {
|
||||
let deps = pkg_json.resolve_local_package_json_deps();
|
||||
let mut pkg_pkgs = Vec::with_capacity(deps.len());
|
||||
for (alias, dep) in deps {
|
||||
let mut pkg_pkgs = Vec::with_capacity(
|
||||
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 {
|
||||
Ok(dep) => dep,
|
||||
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| {
|
||||
pkg.matches_name_and_version_req(&alias, &version_req)
|
||||
}) {
|
||||
|
|
15
cli/cache/mod.rs
vendored
15
cli/cache/mod.rs
vendored
|
@ -23,6 +23,7 @@ use deno_graph::source::Loader;
|
|||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -67,8 +68,11 @@ pub const CACHE_PERM: u32 = 0o644;
|
|||
pub struct RealDenoCacheEnv;
|
||||
|
||||
impl deno_cache_dir::DenoCacheEnv for RealDenoCacheEnv {
|
||||
fn read_file_bytes(&self, path: &Path) -> std::io::Result<Vec<u8>> {
|
||||
std::fs::read(path)
|
||||
fn read_file_bytes(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> std::io::Result<Cow<'static, [u8]>> {
|
||||
std::fs::read(path).map(Cow::Owned)
|
||||
}
|
||||
|
||||
fn atomic_write_file(
|
||||
|
@ -112,12 +116,13 @@ pub struct 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
|
||||
.0
|
||||
.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())
|
||||
}
|
||||
|
||||
|
|
|
@ -504,7 +504,12 @@ impl CliFactory {
|
|||
let resolver = cli_options
|
||||
.create_workspace_resolver(
|
||||
self.file_fetcher()?,
|
||||
if cli_options.use_byonm() {
|
||||
if cli_options.use_byonm()
|
||||
&& !matches!(
|
||||
cli_options.sub_command(),
|
||||
DenoSubcommand::Publish(_)
|
||||
)
|
||||
{
|
||||
PackageJsonDepResolution::Disabled
|
||||
} else {
|
||||
// todo(dsherret): this should be false for nodeModulesDir: true
|
||||
|
|
|
@ -1540,7 +1540,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.unwrap()
|
||||
.content;
|
||||
String::from_utf8(bytes).unwrap()
|
||||
String::from_utf8(bytes.into_owned()).unwrap()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
|
|
@ -41,6 +41,7 @@ use deno_path_util::url_to_file_path;
|
|||
use deno_runtime::deno_node::PackageJson;
|
||||
use indexmap::IndexSet;
|
||||
use lsp_types::ClientCapabilities;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
|
@ -2093,7 +2094,7 @@ impl<T: Clone> CachedFsItems<T> {
|
|||
#[derive(Default)]
|
||||
struct InnerData {
|
||||
stat_calls: CachedFsItems<deno_config::fs::FsMetadata>,
|
||||
read_to_string_calls: CachedFsItems<String>,
|
||||
read_to_string_calls: CachedFsItems<Cow<'static, str>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -2114,7 +2115,7 @@ impl DenoConfigFs for CachedDenoConfigFs {
|
|||
fn read_to_string_lossy(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> Result<String, std::io::Error> {
|
||||
) -> Result<Cow<'static, str>, std::io::Error> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
|
|
|
@ -925,7 +925,7 @@ impl FileSystemDocuments {
|
|||
let content = bytes_to_content(
|
||||
specifier,
|
||||
media_type,
|
||||
cached_file.content,
|
||||
cached_file.content.into_owned(),
|
||||
maybe_charset,
|
||||
)
|
||||
.ok()?;
|
||||
|
|
|
@ -262,7 +262,7 @@ fn read_cached_url(
|
|||
cache
|
||||
.get(&cache.cache_item_key(url).ok()?, None)
|
||||
.ok()?
|
||||
.map(|f| f.content)
|
||||
.map(|f| f.content.into_owned())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1297,16 +1297,10 @@ impl TsServer {
|
|||
{
|
||||
// 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
|
||||
// await point. To pass on that cancellation to the TS thread, we make this
|
||||
// wrapper which cancels the request's token on drop.
|
||||
struct DroppableToken(CancellationToken);
|
||||
impl Drop for DroppableToken {
|
||||
fn drop(&mut self) {
|
||||
self.0.cancel();
|
||||
}
|
||||
}
|
||||
// await point. To pass on that cancellation to the TS thread, we use drop_guard
|
||||
// which cancels the request's token on drop.
|
||||
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 change = self.pending_change.lock().take();
|
||||
|
||||
|
@ -1320,7 +1314,7 @@ impl TsServer {
|
|||
tokio::select! {
|
||||
value = &mut rx => {
|
||||
let value = value??;
|
||||
drop(droppable_token);
|
||||
droppable_token.disarm();
|
||||
Ok(serde_json::from_str(&value)?)
|
||||
}
|
||||
_ = token.cancelled() => {
|
||||
|
|
|
@ -9,6 +9,7 @@ use deno_npm::resolution::NpmResolutionSnapshot;
|
|||
use deno_runtime::deno_io::FromRawIoHandle;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::Version;
|
||||
use deno_task_shell::KillSignal;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
|
@ -155,6 +156,29 @@ impl<'a> LifecycleScripts<'a> {
|
|||
packages: &[NpmResolutionPackage],
|
||||
root_node_modules_dir_path: &Path,
|
||||
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> {
|
||||
self.warn_not_run_scripts()?;
|
||||
let get_package_path =
|
||||
|
@ -246,6 +270,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
stderr: TaskStdio::piped(),
|
||||
stdout: TaskStdio::piped(),
|
||||
}),
|
||||
kill_signal: kill_signal.clone(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
|
|
@ -14,6 +14,7 @@ use deno_runtime::deno_node::NodeResolver;
|
|||
use deno_semver::package::PackageNv;
|
||||
use deno_task_shell::ExecutableCommand;
|
||||
use deno_task_shell::ExecuteResult;
|
||||
use deno_task_shell::KillSignal;
|
||||
use deno_task_shell::ShellCommand;
|
||||
use deno_task_shell::ShellCommandContext;
|
||||
use deno_task_shell::ShellPipeReader;
|
||||
|
@ -22,6 +23,7 @@ use lazy_regex::Lazy;
|
|||
use regex::Regex;
|
||||
use tokio::task::JoinHandle;
|
||||
use tokio::task::LocalSet;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::npm::InnerCliNpmResolverRef;
|
||||
|
@ -45,9 +47,11 @@ impl TaskStdio {
|
|||
pub fn stdout() -> Self {
|
||||
Self(None, ShellPipeWriter::stdout())
|
||||
}
|
||||
|
||||
pub fn stderr() -> Self {
|
||||
Self(None, ShellPipeWriter::stderr())
|
||||
}
|
||||
|
||||
pub fn piped() -> Self {
|
||||
let (r, w) = deno_task_shell::pipe();
|
||||
Self(Some(r), w)
|
||||
|
@ -62,8 +66,8 @@ pub struct TaskIo {
|
|||
impl Default for TaskIo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
stderr: TaskStdio::stderr(),
|
||||
stdout: TaskStdio::stdout(),
|
||||
stderr: TaskStdio::stderr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +82,7 @@ pub struct RunTaskOptions<'a> {
|
|||
pub custom_commands: HashMap<String, Rc<dyn ShellCommand>>,
|
||||
pub root_node_modules_dir: Option<&'a Path>,
|
||||
pub stdio: Option<TaskIo>,
|
||||
pub kill_signal: KillSignal,
|
||||
}
|
||||
|
||||
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))?;
|
||||
let env_vars =
|
||||
prepare_env_vars(opts.env_vars, opts.init_cwd, opts.root_node_modules_dir);
|
||||
let state =
|
||||
deno_task_shell::ShellState::new(env_vars, opts.cwd, opts.custom_commands);
|
||||
let state = deno_task_shell::ShellState::new(
|
||||
env_vars,
|
||||
opts.cwd,
|
||||
opts.custom_commands,
|
||||
opts.kill_signal,
|
||||
);
|
||||
let stdio = opts.stdio.unwrap_or_default();
|
||||
let (
|
||||
TaskStdio(stdout_read, stdout_write),
|
||||
|
@ -537,6 +546,80 @@ fn resolve_managed_npm_commands(
|
|||
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)]
|
||||
mod test {
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ impl Diagnostic for PublishDiagnostic {
|
|||
..
|
||||
}) => DiagnosticLevel::Warning,
|
||||
FastCheck(_) => DiagnosticLevel::Error,
|
||||
SpecifierUnfurl(_) => DiagnosticLevel::Warning,
|
||||
SpecifierUnfurl(d) => d.level(),
|
||||
InvalidPath { .. } => DiagnosticLevel::Error,
|
||||
DuplicatePath { .. } => DiagnosticLevel::Error,
|
||||
UnsupportedFileType { .. } => DiagnosticLevel::Warning,
|
||||
|
@ -187,7 +187,7 @@ impl Diagnostic for PublishDiagnostic {
|
|||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.code(),
|
||||
SpecifierUnfurl(diagnostic) => Cow::Borrowed(diagnostic.code()),
|
||||
SpecifierUnfurl(diagnostic) => diagnostic.code(),
|
||||
InvalidPath { .. } => Cow::Borrowed("invalid-path"),
|
||||
DuplicatePath { .. } => Cow::Borrowed("case-insensitive-duplicate-path"),
|
||||
UnsupportedFileType { .. } => Cow::Borrowed("unsupported-file-type"),
|
||||
|
@ -207,7 +207,7 @@ impl Diagnostic for PublishDiagnostic {
|
|||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.message(),
|
||||
SpecifierUnfurl(diagnostic) => Cow::Borrowed(diagnostic.message()),
|
||||
SpecifierUnfurl(diagnostic) => diagnostic.message(),
|
||||
InvalidPath { message, .. } => Cow::Borrowed(message.as_str()),
|
||||
DuplicatePath { .. } => {
|
||||
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::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.location(),
|
||||
SpecifierUnfurl(diagnostic) => match diagnostic {
|
||||
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport {
|
||||
specifier,
|
||||
text_info,
|
||||
range,
|
||||
} => DiagnosticLocation::ModulePosition {
|
||||
specifier: Cow::Borrowed(specifier),
|
||||
text_info: Cow::Borrowed(text_info),
|
||||
source_pos: DiagnosticSourcePos::SourcePos(range.start),
|
||||
},
|
||||
},
|
||||
SpecifierUnfurl(diagnostic) => diagnostic.location(),
|
||||
InvalidPath { path, .. } => {
|
||||
DiagnosticLocation::Path { path: path.clone() }
|
||||
}
|
||||
|
@ -325,24 +315,8 @@ impl Diagnostic for PublishDiagnostic {
|
|||
|
||||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.snippet(),
|
||||
SpecifierUnfurl(diagnostic) => match diagnostic {
|
||||
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()),
|
||||
}],
|
||||
}),
|
||||
},
|
||||
FastCheck(d) => d.snippet(),
|
||||
SpecifierUnfurl(d) => d.snippet(),
|
||||
InvalidPath { .. } => None,
|
||||
DuplicatePath { .. } => None,
|
||||
UnsupportedFileType { .. } => None,
|
||||
|
@ -380,7 +354,7 @@ impl Diagnostic for PublishDiagnostic {
|
|||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.hint(),
|
||||
SpecifierUnfurl(_) => None,
|
||||
SpecifierUnfurl(d) => d.hint(),
|
||||
InvalidPath { .. } => Some(
|
||||
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,
|
||||
}
|
||||
}
|
||||
SyntaxError(diagnostic) => diagnostic.snippet_fixed(),
|
||||
SyntaxError(d) => d.snippet_fixed(),
|
||||
SpecifierUnfurl(d) => d.snippet_fixed(),
|
||||
FastCheck(_)
|
||||
| SpecifierUnfurl(_)
|
||||
| InvalidPath { .. }
|
||||
| DuplicatePath { .. }
|
||||
| UnsupportedFileType { .. }
|
||||
|
@ -453,16 +427,8 @@ impl Diagnostic for PublishDiagnostic {
|
|||
fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
|
||||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => {
|
||||
diagnostic.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")
|
||||
]),
|
||||
},
|
||||
FastCheck(d) => d.info(),
|
||||
SpecifierUnfurl(d) => d.info(),
|
||||
InvalidPath { .. } => Cow::Borrowed(&[
|
||||
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>> {
|
||||
use PublishDiagnostic::*;
|
||||
match &self {
|
||||
FastCheck(diagnostic) => diagnostic.docs_url(),
|
||||
SpecifierUnfurl(diagnostic) => match diagnostic {
|
||||
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => None,
|
||||
},
|
||||
FastCheck(d) => d.docs_url(),
|
||||
SpecifierUnfurl(d) => d.docs_url(),
|
||||
InvalidPath { .. } => {
|
||||
Some(Cow::Borrowed("https://jsr.io/go/invalid-path"))
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use base64::Engine;
|
|||
use deno_ast::ModuleSpecifier;
|
||||
use deno_config::deno_json::ConfigFile;
|
||||
use deno_config::workspace::JsrPackageConfig;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
|
@ -44,8 +43,6 @@ use crate::cache::ParsedSourceCache;
|
|||
use crate::factory::CliFactory;
|
||||
use crate::graph_util::ModuleGraphCreator;
|
||||
use crate::http_util::HttpClient;
|
||||
use crate::resolver::CliSloppyImportsResolver;
|
||||
use crate::resolver::SloppyImportsCachedFs;
|
||||
use crate::tools::check::CheckOptions;
|
||||
use crate::tools::lint::collect_no_slow_type_diagnostics;
|
||||
use crate::tools::registry::diagnostics::PublishDiagnostic;
|
||||
|
@ -123,19 +120,8 @@ pub async fn publish(
|
|||
}
|
||||
|
||||
let specifier_unfurler = Arc::new(SpecifierUnfurler::new(
|
||||
if cli_options.unstable_sloppy_imports() {
|
||||
Some(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(
|
||||
cli_factory.fs().clone(),
|
||||
)))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
cli_options
|
||||
.create_workspace_resolver(
|
||||
cli_factory.file_fetcher()?,
|
||||
PackageJsonDepResolution::Enabled,
|
||||
)
|
||||
.await?,
|
||||
cli_factory.sloppy_imports_resolver()?.cloned(),
|
||||
cli_factory.workspace_resolver().await?.clone(),
|
||||
cli_options.unstable_bare_node_builtins(),
|
||||
));
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@ use deno_core::futures::FutureExt;
|
|||
use deno_core::futures::StreamExt;
|
||||
use deno_core::serde_json;
|
||||
use deno_graph::FillFromLockfileOptions;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_package_json::PackageJsonDepValueParseError;
|
||||
use deno_package_json::PackageJsonDepsMap;
|
||||
use deno_package_json::PackageJsonRc;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
|
@ -32,7 +31,6 @@ use deno_semver::VersionReq;
|
|||
use import_map::ImportMap;
|
||||
use import_map::ImportMapWithDiagnostics;
|
||||
use import_map::SpecifierMapEntry;
|
||||
use indexmap::IndexMap;
|
||||
use tokio::sync::Semaphore;
|
||||
|
||||
use crate::args::CliLockfile;
|
||||
|
@ -269,94 +267,6 @@ enum PackageJsonDepKind {
|
|||
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(
|
||||
deno_json: &Arc<ConfigFile>,
|
||||
mut filter: impl DepFilter,
|
||||
|
@ -406,40 +316,64 @@ fn add_deps_from_deno_json(
|
|||
|
||||
fn add_deps_from_package_json(
|
||||
package_json: &PackageJsonRc,
|
||||
mut filter: impl DepFilter,
|
||||
filter: impl DepFilter,
|
||||
deps: &mut Vec<Dep>,
|
||||
) {
|
||||
let package_json_deps = resolve_local_package_json_deps(package_json);
|
||||
for (k, v) in package_json_deps {
|
||||
let (package_dep_kind, v) = match v {
|
||||
Ok((k, v)) => (k, v),
|
||||
Err(e) => {
|
||||
log::warn!("bad package json dep value: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
match v {
|
||||
deno_package_json::PackageJsonDepValue::Req(req) => {
|
||||
let alias = k.as_str();
|
||||
let alias = (alias != req.name).then(|| alias.to_string());
|
||||
if !filter.should_include(alias.as_deref(), &req, DepKind::Npm) {
|
||||
let package_json_deps = package_json.resolve_local_package_json_deps();
|
||||
|
||||
fn iterate(
|
||||
package_json: &PackageJsonRc,
|
||||
mut filter: impl DepFilter,
|
||||
package_dep_kind: PackageJsonDepKind,
|
||||
package_json_deps: PackageJsonDepsMap,
|
||||
deps: &mut Vec<Dep>,
|
||||
) {
|
||||
for (k, v) in package_json_deps {
|
||||
let v = match v {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log::warn!("bad package json dep value: {e}");
|
||||
continue;
|
||||
}
|
||||
let id = DepId(deps.len());
|
||||
deps.push(Dep {
|
||||
id,
|
||||
kind: DepKind::Npm,
|
||||
location: DepLocation::PackageJson(
|
||||
package_json.clone(),
|
||||
KeyPath::from_parts([package_dep_kind.into(), k.into()]),
|
||||
),
|
||||
req,
|
||||
alias,
|
||||
})
|
||||
};
|
||||
match v {
|
||||
deno_package_json::PackageJsonDepValue::Req(req) => {
|
||||
let alias = k.as_str();
|
||||
let alias = (alias != req.name).then(|| alias.to_string());
|
||||
if !filter.should_include(alias.as_deref(), &req, DepKind::Npm) {
|
||||
continue;
|
||||
}
|
||||
let id = DepId(deps.len());
|
||||
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(
|
||||
|
|
|
@ -1,19 +1,35 @@
|
|||
// 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::SourceRange;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_ast::SourceTextProvider;
|
||||
use deno_config::workspace::MappedResolution;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::anyhow;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::DependencyDescriptor;
|
||||
use deno_graph::DynamicTemplatePart;
|
||||
use deno_graph::ParserModuleAnalyzer;
|
||||
use deno_graph::TypeScriptReference;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_package_json::PackageJsonDepWorkspaceReq;
|
||||
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
|
||||
use deno_runtime::deno_node::is_builtin_node_module;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::VersionReq;
|
||||
|
||||
use crate::resolver::CliSloppyImportsResolver;
|
||||
|
||||
|
@ -24,34 +40,163 @@ pub enum SpecifierUnfurlerDiagnostic {
|
|||
text_info: SourceTextInfo,
|
||||
range: SourceRange,
|
||||
},
|
||||
ResolvingNpmWorkspacePackage {
|
||||
specifier: ModuleSpecifier,
|
||||
package_name: String,
|
||||
text_info: SourceTextInfo,
|
||||
range: SourceRange,
|
||||
reason: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl SpecifierUnfurlerDiagnostic {
|
||||
pub fn code(&self) -> &'static str {
|
||||
impl Diagnostic for SpecifierUnfurlerDiagnostic {
|
||||
fn level(&self) -> DiagnosticLevel {
|
||||
match self {
|
||||
Self::UnanalyzableDynamicImport { .. } => "unanalyzable-dynamic-import",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message(&self) -> &'static str {
|
||||
match self {
|
||||
Self::UnanalyzableDynamicImport { .. } => {
|
||||
"unable to analyze dynamic import"
|
||||
SpecifierUnfurlerDiagnostic::UnanalyzableDynamicImport { .. } => {
|
||||
DiagnosticLevel::Warning
|
||||
}
|
||||
SpecifierUnfurlerDiagnostic::ResolvingNpmWorkspacePackage { .. } => {
|
||||
DiagnosticLevel::Error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
sloppy_imports_resolver: Option<CliSloppyImportsResolver>,
|
||||
workspace_resolver: WorkspaceResolver,
|
||||
sloppy_imports_resolver: Option<Arc<CliSloppyImportsResolver>>,
|
||||
workspace_resolver: Arc<WorkspaceResolver>,
|
||||
bare_node_builtins: bool,
|
||||
}
|
||||
|
||||
impl SpecifierUnfurler {
|
||||
pub fn new(
|
||||
sloppy_imports_resolver: Option<CliSloppyImportsResolver>,
|
||||
workspace_resolver: WorkspaceResolver,
|
||||
sloppy_imports_resolver: Option<Arc<CliSloppyImportsResolver>>,
|
||||
workspace_resolver: Arc<WorkspaceResolver>,
|
||||
bare_node_builtins: bool,
|
||||
) -> Self {
|
||||
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(
|
||||
&self,
|
||||
referrer: &ModuleSpecifier,
|
||||
specifier: &str,
|
||||
) -> Option<String> {
|
||||
) -> Result<Option<String>, UnfurlSpecifierError> {
|
||||
let resolved = if let Ok(resolved) =
|
||||
self.workspace_resolver.resolve(specifier, referrer)
|
||||
{
|
||||
|
@ -120,8 +299,40 @@ impl SpecifierUnfurler {
|
|||
))
|
||||
.ok()
|
||||
}
|
||||
PackageJsonDepValue::Workspace(version_req) => {
|
||||
// todo(#24612): consider warning or error when this is also a jsr package?
|
||||
PackageJsonDepValue::Workspace(workspace_version_req) => {
|
||||
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!(
|
||||
"npm:{}@{}{}",
|
||||
alias,
|
||||
|
@ -151,10 +362,14 @@ impl SpecifierUnfurler {
|
|||
None if self.bare_node_builtins && is_builtin_node_module(specifier) => {
|
||||
format!("node:{specifier}").parse().unwrap()
|
||||
}
|
||||
None => ModuleSpecifier::options()
|
||||
None => match ModuleSpecifier::options()
|
||||
.base_url(Some(referrer))
|
||||
.parse(specifier)
|
||||
.ok()?,
|
||||
.ok()
|
||||
{
|
||||
Some(value) => value,
|
||||
None => return Ok(None),
|
||||
},
|
||||
};
|
||||
// TODO(lucacasonato): this requires integration in deno_graph first
|
||||
// let resolved = if let Ok(specifier) =
|
||||
|
@ -188,7 +403,7 @@ impl SpecifierUnfurler {
|
|||
};
|
||||
let relative_resolved = relative_url(&resolved, referrer);
|
||||
if relative_resolved == specifier {
|
||||
None // nothing to unfurl
|
||||
Ok(None) // nothing to unfurl
|
||||
} else {
|
||||
log::debug!(
|
||||
"Unfurled specifier: {} from {} -> {}",
|
||||
|
@ -196,7 +411,29 @@ impl SpecifierUnfurler {
|
|||
referrer,
|
||||
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,
|
||||
dep: &deno_graph::DynamicDependencyDescriptor,
|
||||
text_changes: &mut Vec<deno_ast::TextChange>,
|
||||
diagnostic_reporter: &mut dyn FnMut(SpecifierUnfurlerDiagnostic),
|
||||
) -> bool {
|
||||
match &dep.argument {
|
||||
deno_graph::DynamicArgument::String(specifier) => {
|
||||
|
@ -217,8 +455,14 @@ impl SpecifierUnfurler {
|
|||
let Some(relative_index) = maybe_relative_index else {
|
||||
return true; // always say it's analyzable for a string
|
||||
};
|
||||
let unfurled = self.unfurl_specifier(module_url, specifier);
|
||||
if let Some(unfurled) = unfurled {
|
||||
let maybe_unfurled = self.unfurl_specifier_reporting_diagnostic(
|
||||
module_url,
|
||||
specifier,
|
||||
text_info,
|
||||
&dep.argument_range,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
if let Some(unfurled) = maybe_unfurled {
|
||||
let start = range.start + relative_index;
|
||||
text_changes.push(deno_ast::TextChange {
|
||||
range: start..start + specifier.len(),
|
||||
|
@ -238,7 +482,13 @@ impl SpecifierUnfurler {
|
|||
if !specifier.ends_with('/') {
|
||||
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 {
|
||||
return true; // nothing to unfurl
|
||||
};
|
||||
|
@ -280,8 +530,15 @@ impl SpecifierUnfurler {
|
|||
let analyze_specifier =
|
||||
|specifier: &str,
|
||||
range: &deno_graph::PositionRange,
|
||||
text_changes: &mut Vec<deno_ast::TextChange>| {
|
||||
if let Some(unfurled) = self.unfurl_specifier(url, specifier) {
|
||||
text_changes: &mut Vec<deno_ast::TextChange>,
|
||||
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 {
|
||||
range: to_range(text_info, range),
|
||||
new_text: unfurled,
|
||||
|
@ -295,11 +552,17 @@ impl SpecifierUnfurler {
|
|||
&dep.specifier,
|
||||
&dep.specifier_range,
|
||||
&mut text_changes,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
}
|
||||
DependencyDescriptor::Dynamic(dep) => {
|
||||
let success =
|
||||
self.try_unfurl_dynamic_dep(url, text_info, dep, &mut text_changes);
|
||||
let success = self.try_unfurl_dynamic_dep(
|
||||
url,
|
||||
text_info,
|
||||
dep,
|
||||
&mut text_changes,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
|
||||
if !success {
|
||||
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.range,
|
||||
&mut text_changes,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
}
|
||||
for jsdoc in &module_info.jsdoc_imports {
|
||||
|
@ -333,6 +597,7 @@ impl SpecifierUnfurler {
|
|||
&jsdoc.specifier.text,
|
||||
&jsdoc.specifier.range,
|
||||
&mut text_changes,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
}
|
||||
if let Some(specifier_with_range) = &module_info.jsx_import_source {
|
||||
|
@ -340,6 +605,7 @@ impl SpecifierUnfurler {
|
|||
&specifier_with_range.text,
|
||||
&specifier_with_range.range,
|
||||
&mut text_changes,
|
||||
diagnostic_reporter,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -458,10 +724,10 @@ mod tests {
|
|||
);
|
||||
let fs = Arc::new(RealFs);
|
||||
let unfurler = SpecifierUnfurler::new(
|
||||
Some(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(
|
||||
fs,
|
||||
Some(Arc::new(CliSloppyImportsResolver::new(
|
||||
SloppyImportsCachedFs::new(fs),
|
||||
))),
|
||||
workspace_resolver,
|
||||
Arc::new(workspace_resolver),
|
||||
true,
|
||||
);
|
||||
|
||||
|
@ -547,4 +813,114 @@ const warn2 = await import(`${expr}`);
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use deno_core::futures::StreamExt;
|
|||
use deno_core::url::Url;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_runtime::deno_node::NodeResolver;
|
||||
use deno_task_shell::KillSignal;
|
||||
use deno_task_shell::ShellCommand;
|
||||
use indexmap::IndexMap;
|
||||
use regex::Regex;
|
||||
|
@ -37,6 +38,7 @@ use crate::colors;
|
|||
use crate::factory::CliFactory;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::task_runner;
|
||||
use crate::task_runner::run_future_forwarding_signals;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -226,28 +228,33 @@ pub async fn execute_script(
|
|||
concurrency: no_of_concurrent_tasks.into(),
|
||||
};
|
||||
|
||||
if task_flags.eval {
|
||||
return task_runner
|
||||
.run_deno_task(
|
||||
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
|
||||
"",
|
||||
&TaskDefinition {
|
||||
command: task_flags.task.as_ref().unwrap().to_string(),
|
||||
dependencies: vec![],
|
||||
description: None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
for task_config in &packages_task_configs {
|
||||
let exit_code = task_runner.run_tasks(task_config).await?;
|
||||
if exit_code > 0 {
|
||||
return Ok(exit_code);
|
||||
let kill_signal = KillSignal::default();
|
||||
run_future_forwarding_signals(kill_signal.clone(), async {
|
||||
if task_flags.eval {
|
||||
return task_runner
|
||||
.run_deno_task(
|
||||
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
|
||||
"",
|
||||
&TaskDefinition {
|
||||
command: task_flags.task.as_ref().unwrap().to_string(),
|
||||
dependencies: vec![],
|
||||
description: None,
|
||||
},
|
||||
kill_signal,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
|
@ -255,6 +262,7 @@ struct RunSingleOptions<'a> {
|
|||
script: &'a str,
|
||||
cwd: &'a Path,
|
||||
custom_commands: HashMap<String, Rc<dyn ShellCommand>>,
|
||||
kill_signal: KillSignal,
|
||||
}
|
||||
|
||||
struct TaskRunner<'a> {
|
||||
|
@ -270,9 +278,10 @@ impl<'a> TaskRunner<'a> {
|
|||
pub async fn run_tasks(
|
||||
&self,
|
||||
pkg_tasks_config: &PackageTaskInfo,
|
||||
kill_signal: &KillSignal,
|
||||
) -> Result<i32, deno_core::anyhow::Error> {
|
||||
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 {
|
||||
TaskError::NotFound(name) => {
|
||||
if self.task_flags.is_run {
|
||||
|
@ -307,6 +316,7 @@ impl<'a> TaskRunner<'a> {
|
|||
async fn run_tasks_in_parallel(
|
||||
&self,
|
||||
tasks: Vec<ResolvedTask<'a>>,
|
||||
kill_signal: &KillSignal,
|
||||
) -> Result<i32, deno_core::anyhow::Error> {
|
||||
struct PendingTasksContext<'a> {
|
||||
completed: HashSet<usize>,
|
||||
|
@ -327,6 +337,7 @@ impl<'a> TaskRunner<'a> {
|
|||
fn get_next_task<'b>(
|
||||
&mut self,
|
||||
runner: &'b TaskRunner<'b>,
|
||||
kill_signal: &KillSignal,
|
||||
) -> Option<
|
||||
LocalBoxFuture<'b, Result<(i32, &'a ResolvedTask<'a>), AnyError>>,
|
||||
>
|
||||
|
@ -349,15 +360,23 @@ impl<'a> TaskRunner<'a> {
|
|||
}
|
||||
|
||||
self.running.insert(task.id);
|
||||
let kill_signal = kill_signal.clone();
|
||||
return Some(
|
||||
async move {
|
||||
match task.task_or_script {
|
||||
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, _) => {
|
||||
runner
|
||||
.run_npm_script(task.folder_url, task.name, scripts)
|
||||
.run_npm_script(
|
||||
task.folder_url,
|
||||
task.name,
|
||||
scripts,
|
||||
kill_signal,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +399,7 @@ impl<'a> TaskRunner<'a> {
|
|||
|
||||
while context.has_remaining_tasks() {
|
||||
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);
|
||||
} else {
|
||||
break;
|
||||
|
@ -409,6 +428,7 @@ impl<'a> TaskRunner<'a> {
|
|||
dir_url: &Url,
|
||||
task_name: &str,
|
||||
definition: &TaskDefinition,
|
||||
kill_signal: KillSignal,
|
||||
) -> Result<i32, deno_core::anyhow::Error> {
|
||||
let cwd = match &self.task_flags.cwd {
|
||||
Some(path) => canonicalize_path(&PathBuf::from(path))
|
||||
|
@ -426,6 +446,7 @@ impl<'a> TaskRunner<'a> {
|
|||
script: &definition.command,
|
||||
cwd: &cwd,
|
||||
custom_commands,
|
||||
kill_signal,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
@ -435,6 +456,7 @@ impl<'a> TaskRunner<'a> {
|
|||
dir_url: &Url,
|
||||
task_name: &str,
|
||||
scripts: &IndexMap<String, String>,
|
||||
kill_signal: KillSignal,
|
||||
) -> Result<i32, deno_core::anyhow::Error> {
|
||||
// ensure the npm packages are installed if using a managed resolver
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
|
@ -466,6 +488,7 @@ impl<'a> TaskRunner<'a> {
|
|||
script,
|
||||
cwd: &cwd,
|
||||
custom_commands: custom_commands.clone(),
|
||||
kill_signal: kill_signal.clone(),
|
||||
})
|
||||
.await?;
|
||||
if exit_code > 0 {
|
||||
|
@ -486,6 +509,7 @@ impl<'a> TaskRunner<'a> {
|
|||
script,
|
||||
cwd,
|
||||
custom_commands,
|
||||
kill_signal,
|
||||
} = opts;
|
||||
|
||||
output_task(
|
||||
|
@ -504,6 +528,7 @@ impl<'a> TaskRunner<'a> {
|
|||
argv: self.cli_options.argv(),
|
||||
root_node_modules_dir: self.npm_resolver.root_node_modules_path(),
|
||||
stdio: None,
|
||||
kill_signal,
|
||||
})
|
||||
.await?
|
||||
.exit_code,
|
||||
|
|
|
@ -872,12 +872,10 @@ impl deno_package_json::fs::DenoPkgJsonFs for DenoFsNodeResolverEnv {
|
|||
fn read_to_string_lossy(
|
||||
&self,
|
||||
path: &std::path::Path,
|
||||
) -> Result<String, std::io::Error> {
|
||||
) -> Result<Cow<'static, str>, std::io::Error> {
|
||||
self
|
||||
.fs
|
||||
.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())
|
||||
}
|
||||
}
|
||||
|
@ -888,12 +886,10 @@ impl<'a> deno_package_json::fs::DenoPkgJsonFs for DenoPkgJsonFsAdapter<'a> {
|
|||
fn read_to_string_lossy(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> Result<String, std::io::Error> {
|
||||
) -> Result<Cow<'static, str>, std::io::Error> {
|
||||
self
|
||||
.0
|
||||
.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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,11 @@ impl<Fs: DenoResolverFs, TEnv: NodeResolverEnv> ByonmNpmResolver<Fs, TEnv> {
|
|||
pkg_json: &PackageJson,
|
||||
) -> Option<String> {
|
||||
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 {
|
||||
match value {
|
||||
PackageJsonDepValue::Req(dep_req) => {
|
||||
|
|
|
@ -34,6 +34,7 @@ pub mod inspector_server;
|
|||
pub mod js;
|
||||
pub mod ops;
|
||||
pub mod permissions;
|
||||
pub mod signal;
|
||||
pub mod snapshot;
|
||||
pub mod sys_info;
|
||||
pub mod tokio_util;
|
||||
|
|
|
@ -256,9 +256,7 @@ impl TryFrom<ExitStatus> for ChildStatus {
|
|||
success: false,
|
||||
code: 128 + signal,
|
||||
#[cfg(unix)]
|
||||
signal: Some(
|
||||
crate::ops::signal::signal_int_to_str(signal)?.to_string(),
|
||||
),
|
||||
signal: Some(crate::signal::signal_int_to_str(signal)?.to_string()),
|
||||
#[cfg(not(unix))]
|
||||
signal: None,
|
||||
}
|
||||
|
@ -1076,7 +1074,8 @@ mod deprecated {
|
|||
|
||||
#[cfg(unix)]
|
||||
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::Signal;
|
||||
use nix::unistd::Pid;
|
||||
|
@ -1099,7 +1098,12 @@ mod deprecated {
|
|||
use winapi::um::winnt::PROCESS_TERMINATE;
|
||||
|
||||
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 {
|
||||
Err(ProcessError::InvalidPid)
|
||||
} else {
|
||||
|
|
|
@ -46,34 +46,10 @@ deno_core::extension!(
|
|||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum SignalError {
|
||||
#[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}")]
|
||||
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(transparent)]
|
||||
InvalidSignalStr(#[from] crate::signal::InvalidSignalStrError),
|
||||
#[error(transparent)]
|
||||
InvalidSignalInt(#[from] crate::signal::InvalidSignalIntError),
|
||||
#[error("Binding to signal '{0}' is not allowed")]
|
||||
SignalNotAllowed(String),
|
||||
#[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)]
|
||||
#[op2(fast)]
|
||||
#[smi]
|
||||
|
@ -400,7 +164,7 @@ fn op_signal_bind(
|
|||
state: &mut OpState,
|
||||
#[string] sig: &str,
|
||||
) -> 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) {
|
||||
return Err(SignalError::SignalNotAllowed(sig.to_string()));
|
||||
}
|
||||
|
@ -437,7 +201,7 @@ fn op_signal_bind(
|
|||
state: &mut OpState,
|
||||
#[string] sig: &str,
|
||||
) -> Result<ResourceId, SignalError> {
|
||||
let signo = signal_str_to_int(sig)?;
|
||||
let signo = crate::signal::signal_str_to_int(sig)?;
|
||||
let resource = SignalStreamResource {
|
||||
signal: AsyncRefCell::new(match signo {
|
||||
// SIGINT
|
||||
|
|
257
runtime/signal.rs
Normal file
257
runtime/signal.rs
Normal 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"));
|
10
tests/specs/npm/workspace_version_wildcards/__test__.jsonc
Normal file
10
tests/specs/npm/workspace_version_wildcards/__test__.jsonc
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [{
|
||||
"args": "install",
|
||||
"output": "[WILDCARD]"
|
||||
}, {
|
||||
"args": "run e/main.ts",
|
||||
"output": "main.out"
|
||||
}]
|
||||
}
|
3
tests/specs/npm/workspace_version_wildcards/a/mod.ts
Normal file
3
tests/specs/npm/workspace_version_wildcards/a/mod.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function sayHello() {
|
||||
console.log("Hello from a!");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@denotest/a",
|
||||
"version": "1.0.0",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
3
tests/specs/npm/workspace_version_wildcards/b/mod.ts
Normal file
3
tests/specs/npm/workspace_version_wildcards/b/mod.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function sayHello() {
|
||||
console.log("Hello from b!");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@denotest/b",
|
||||
"version": "1.0.0",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
3
tests/specs/npm/workspace_version_wildcards/c/mod.ts
Normal file
3
tests/specs/npm/workspace_version_wildcards/c/mod.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function sayHello() {
|
||||
console.log("Hello from c!");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@denotest/c",
|
||||
"version": "1.0.0",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
3
tests/specs/npm/workspace_version_wildcards/d/mod.ts
Normal file
3
tests/specs/npm/workspace_version_wildcards/d/mod.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function sayHello() {
|
||||
console.log("Hello from d!");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@denotest/d",
|
||||
"version": "1.2.3",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
9
tests/specs/npm/workspace_version_wildcards/e/main.ts
Normal file
9
tests/specs/npm/workspace_version_wildcards/e/main.ts
Normal 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();
|
10
tests/specs/npm/workspace_version_wildcards/e/package.json
Normal file
10
tests/specs/npm/workspace_version_wildcards/e/package.json
Normal 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"
|
||||
}
|
||||
}
|
4
tests/specs/npm/workspace_version_wildcards/main.out
Normal file
4
tests/specs/npm/workspace_version_wildcards/main.out
Normal file
|
@ -0,0 +1,4 @@
|
|||
Hello from a!
|
||||
Hello from b!
|
||||
Hello from c!
|
||||
Hello from d!
|
6
tests/specs/npm/workspace_version_wildcards/main.ts
Normal file
6
tests/specs/npm/workspace_version_wildcards/main.ts
Normal 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();
|
9
tests/specs/npm/workspace_version_wildcards/package.json
Normal file
9
tests/specs/npm/workspace_version_wildcards/package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"workspaces": [
|
||||
"./a",
|
||||
"./b",
|
||||
"./c",
|
||||
"./d",
|
||||
"./e"
|
||||
]
|
||||
}
|
8
tests/specs/task/signals/__test__.jsonc
Normal file
8
tests/specs/task/signals/__test__.jsonc
Normal 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]"
|
||||
}
|
5
tests/specs/task/signals/deno.jsonc
Normal file
5
tests/specs/task/signals/deno.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"tasks": {
|
||||
"listener": "deno run listener.ts"
|
||||
}
|
||||
}
|
16
tests/specs/task/signals/listener.ts
Normal file
16
tests/specs/task/signals/listener.ts
Normal 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");
|
55
tests/specs/task/signals/sender.ts
Normal file
55
tests/specs/task/signals/sender.ts
Normal 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");
|
65
tests/specs/task/signals/signals.ts
Normal file
65
tests/specs/task/signals/signals.ts
Normal 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 };
|
Loading…
Add table
Reference in a new issue