summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreu Botella <abb@randomunok.com>2022-01-16 16:48:32 +0100
committerGitHub <noreply@github.com>2022-01-16 16:48:32 +0100
commit9def44979a0c3a03a7ada09f8359ea6b1d795d03 (patch)
tree57f7c71de64a8484871d163fc60e9c31bfbb8949
parentad224f53c798e8417a63d98daeaf3cadc199666c (diff)
fix(cli): Don't strip shebangs from modules (#13220)
Deno's module loader currently strips a shebang if a module file starts with one. However, this is no longer necessary, since there is a stage-3 TC39 that adds support for shebangs (or "hashbangs") to the language (https://github.com/tc39/proposal-hashbang), and V8, `tsc` and `swc` all support it. Furthermore, stripping shebangs causes a correctness bug with JSON modules, since a JSON file with a shebang should not parse as a JSON module, yet it does with this stripping. This change fixes this.
-rw-r--r--.dprint.json1
-rw-r--r--cli/file_fetcher.rs31
-rw-r--r--cli/tests/integration/run_tests.rs22
-rw-r--r--cli/tests/testdata/import_assertions/json_with_shebang.json4
-rw-r--r--cli/tests/testdata/import_assertions/json_with_shebang.ts3
-rw-r--r--cli/tests/testdata/import_assertions/json_with_shebang.ts.out1
-rw-r--r--cli/tests/testdata/shebang.ts5
-rw-r--r--cli/tests/testdata/shebang.ts.out1
-rw-r--r--cli/tests/testdata/shebang2.ts3
9 files changed, 44 insertions, 27 deletions
diff --git a/.dprint.json b/.dprint.json
index dfaed6314..73204979a 100644
--- a/.dprint.json
+++ b/.dprint.json
@@ -27,6 +27,7 @@
"cli/tests/testdata/badly_formatted.json",
"cli/tests/testdata/byte_order_mark.ts",
"cli/tests/testdata/fmt/*",
+ "cli/tests/testdata/import_assertions/json_with_shebang.json",
"cli/tests/testdata/test/markdown_windows.md",
"cli/tsc/*typescript.js",
"test_util/std",
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 2a7b86727..1ca04ed9a 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -148,7 +148,7 @@ fn fetch_local(specifier: &ModuleSpecifier) -> Result<File, AnyError> {
})?;
let bytes = fs::read(local.clone())?;
let charset = text_encoding::detect_charset(&bytes).to_string();
- let source = strip_shebang(get_source_from_bytes(bytes, Some(charset))?);
+ let source = get_source_from_bytes(bytes, Some(charset))?;
let media_type = MediaType::from(specifier);
Ok(File {
@@ -173,10 +173,7 @@ pub fn get_source_from_data_url(
let (bytes, _) = data_url
.decode_to_vec()
.map_err(|e| uri_error(format!("{:?}", e)))?;
- Ok((
- strip_shebang(get_source_from_bytes(bytes, charset)?),
- format!("{}", mime),
- ))
+ Ok((get_source_from_bytes(bytes, charset)?, format!("{}", mime)))
}
/// Given a vector of bytes and optionally a charset, decode the bytes to a
@@ -230,19 +227,6 @@ pub fn map_content_type(
}
}
-/// Remove shebangs from the start of source code strings
-fn strip_shebang(mut value: String) -> String {
- if value.starts_with("#!") {
- if let Some(mid) = value.find('\n') {
- let (_, rest) = value.split_at(mid);
- value = rest.to_string()
- } else {
- value.clear()
- }
- }
- value
-}
-
/// A structure for resolving, fetching and caching source files.
#[derive(Debug, Clone)]
pub struct FileFetcher {
@@ -306,7 +290,7 @@ impl FileFetcher {
let maybe_content_type = headers.get("content-type").cloned();
let (media_type, maybe_charset) =
map_content_type(specifier, maybe_content_type);
- let source = strip_shebang(get_source_from_bytes(bytes, maybe_charset)?);
+ let source = get_source_from_bytes(bytes, maybe_charset)?;
let maybe_types = match media_type {
MediaType::JavaScript
| MediaType::Cjs
@@ -450,7 +434,7 @@ impl FileFetcher {
let (media_type, maybe_charset) =
map_content_type(specifier, Some(content_type.clone()));
- let source = strip_shebang(get_source_from_bytes(bytes, maybe_charset)?);
+ let source = get_source_from_bytes(bytes, maybe_charset)?;
let local =
self
@@ -787,13 +771,6 @@ mod tests {
}
#[test]
- fn test_strip_shebang() {
- let value =
- "#!/usr/bin/env deno\n\nconsole.log(\"hello deno!\");\n".to_string();
- assert_eq!(strip_shebang(value), "\n\nconsole.log(\"hello deno!\");\n");
- }
-
- #[test]
fn test_map_content_type() {
let fixtures = vec![
// Extension only
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index f4793a969..bc137a7fd 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -1600,6 +1600,28 @@ itest!(jsx_import_source_error {
exit_code: 1,
});
+itest!(shebang_tsc {
+ args: "run --quiet shebang.ts",
+ output: "shebang.ts.out",
+});
+
+itest!(shebang_swc {
+ args: "run --quiet --no-check shebang.ts",
+ output: "shebang.ts.out",
+});
+
+itest!(shebang_with_json_imports_tsc {
+ args: "run --quiet import_assertions/json_with_shebang.ts",
+ output: "import_assertions/json_with_shebang.ts.out",
+ exit_code: 1,
+});
+
+itest!(shebang_with_json_imports_swc {
+ args: "run --quiet --no-check import_assertions/json_with_shebang.ts",
+ output: "import_assertions/json_with_shebang.ts.out",
+ exit_code: 1,
+});
+
#[test]
fn no_validate_asm() {
let output = util::deno_cmd()
diff --git a/cli/tests/testdata/import_assertions/json_with_shebang.json b/cli/tests/testdata/import_assertions/json_with_shebang.json
new file mode 100644
index 000000000..b695e4457
--- /dev/null
+++ b/cli/tests/testdata/import_assertions/json_with_shebang.json
@@ -0,0 +1,4 @@
+#!/usr/env -S deno run
+{
+ "test": null
+}
diff --git a/cli/tests/testdata/import_assertions/json_with_shebang.ts b/cli/tests/testdata/import_assertions/json_with_shebang.ts
new file mode 100644
index 000000000..523bf8772
--- /dev/null
+++ b/cli/tests/testdata/import_assertions/json_with_shebang.ts
@@ -0,0 +1,3 @@
+import json from "./json_with_shebang.json" assert { type: "json" };
+
+console.log(json);
diff --git a/cli/tests/testdata/import_assertions/json_with_shebang.ts.out b/cli/tests/testdata/import_assertions/json_with_shebang.ts.out
new file mode 100644
index 000000000..ae5f3a65f
--- /dev/null
+++ b/cli/tests/testdata/import_assertions/json_with_shebang.ts.out
@@ -0,0 +1 @@
+error: Uncaught SyntaxError: Unexpected token # in JSON at position 0
diff --git a/cli/tests/testdata/shebang.ts b/cli/tests/testdata/shebang.ts
new file mode 100644
index 000000000..00feb2da0
--- /dev/null
+++ b/cli/tests/testdata/shebang.ts
@@ -0,0 +1,5 @@
+#!/usr/bin/env -S deno run
+
+import test from "./shebang2.ts";
+
+console.log(test as number);
diff --git a/cli/tests/testdata/shebang.ts.out b/cli/tests/testdata/shebang.ts.out
new file mode 100644
index 000000000..d81cc0710
--- /dev/null
+++ b/cli/tests/testdata/shebang.ts.out
@@ -0,0 +1 @@
+42
diff --git a/cli/tests/testdata/shebang2.ts b/cli/tests/testdata/shebang2.ts
new file mode 100644
index 000000000..da0d7bf0c
--- /dev/null
+++ b/cli/tests/testdata/shebang2.ts
@@ -0,0 +1,3 @@
+#!/usr/bin/env -S deno run
+
+export default 42;